/** 3D vector */
type Vec3 = [number, number, number];
/** 3x3 matrix */
type Matrix3x3 = [Vec3, Vec3, Vec3];
/** Cell in lengths+angles format: [[a,b,c],[alpha,beta,gamma]] */
type CellPar = [Vec3, Vec3];
/** Symmetry operation as [rotation matrix, translation vector] */
type SymOp = [number[][], number[]];
/** Token type identifiers produced by the CIF tokenizer */
type TokenType = 'quotestring' | 'semicolontext' | 'tag' | 'data_headers' | 'loop_kw' | 'unknown';
/** A single tokenized unit from a CIF file */
interface Token {
    val: string;
    type: TokenType;
    line: number;
}

/**
 * Convert a Cartesian cell (3×3 row vectors) to lengths-and-angles form.
 * @param radians  If true, return angles in radians (degrees by default)
 */
declare function cellToCellpar(cell: number[][], radians?: boolean): CellPar;
/**
 * Convert a cell from lengths-and-angles form to Cartesian (3×3 row vectors).
 * @param ab_normal   Desired direction for the normal to the AB plane
 * @param a_direction Direction for the a axis
 * @param radians     If true, treat angles as radians
 */
declare function cellparToCell(cellpar: CellPar, ab_normal?: number[], a_direction?: number[], radians?: boolean): Matrix3x3;
/**
 * Acceptable formats for the unit cell passed to `Atoms`:
 * - `null`/`false`/`undefined`: no periodic boundary
 * - `number`: cubic cell with that lattice parameter
 * - `[a, b, c]`: orthorhombic cell
 * - `[[a,b,c],[alpha,beta,gamma]]`: lengths-and-angles (CellPar)
 * - `[[...], [...], [...]]`: full Cartesian 3×3 cell
 * - `(number | null)[]` of length 3: partial periodicity (null = non-periodic axis)
 */
type CellInput = null | false | undefined | number | CellPar | Matrix3x3 | (number | null | false)[];
/**
 * A crystallographic structure inspired by ASE's Atoms class.
 */
declare class Atoms {
    private _arrays;
    private _N;
    private _pbc;
    private _cell;
    private _inv_cell;
    /** Arbitrary metadata attached to this structure */
    info: Record<string, unknown>;
    /**
     * @param elems      Array of element symbols or atomic numbers
     * @param positions  Array of 3D positions (Cartesian by default)
     * @param cell       Unit cell definition (see `CellInput` for accepted forms)
     * @param info       Arbitrary metadata
     * @param scaled     If true, treat `positions` as fractional coordinates
     * @param tolerant   If true, accept unknown element symbols without throwing
     */
    constructor(elems: (string | number)[], positions?: number[][], cell?: CellInput, info?: Record<string, unknown>, scaled?: boolean, tolerant?: boolean);
    /** Total number of atoms */
    length(): number;
    /**
     * Store a per-atom array (must have length equal to the number of atoms).
     */
    set_array(name: string, arr: unknown[]): void;
    /** Retrieve a per-atom array by name. */
    get_array(name: string): unknown[];
    get_chemical_symbols(): string[];
    get_atomic_numbers(): number[];
    get_cell(): (Vec3 | null)[] | null;
    get_inv_cell(): number[][] | null;
    get_pbc(): [boolean, boolean, boolean];
    get_positions(): number[][];
    /**
     * Return positions in fractional (scaled) coordinates.
     * Performance-critical: uses manual matrix-vector multiply rather than mathjs.
     */
    get_scaled_positions(): number[][];
    /**
     * Parse a CIF text string and return a dictionary mapping block names to
     * `Atoms` instances.
     * @param symtol  Distance threshold for deduplicating symmetry-equivalent sites
     */
    static readCif(cif: string, symtol?: number): Record<string, Atoms>;
}

type CifValueType = 'int' | 'float' | 'string' | 'mstring' | 'N/A' | '?';
/**
 * Represents a single value (string or numerical) found in a CIF file.
 */
declare class CifValue {
    type: CifValueType;
    /** Precision number (numerals only) */
    prec?: number;
    /** Numeric value (int or float) */
    num?: number;
    /** String value */
    text?: string;
    constructor(type: CifValueType, value?: number | string, prec?: number);
    /** Return the underlying numeric or string value. */
    get_value(): number | string | undefined;
}
interface SingleDataItem {
    tag: string;
    type: 'single';
    value: CifValue;
}
interface LoopDataItem {
    tag: string;
    type: 'loop';
    value: CifValue[];
}
type DataItem = SingleDataItem | LoopDataItem;
type CifBlock = Record<string, DataItem>;
type CifDict = Record<string, CifBlock>;
/**
 * Split a CIF text string into elementary tokens for further processing.
 */
declare function tokenize(cif: string): Token[];
/**
 * Parse a single token as a CIF value.
 */
declare function parseValue(tok: Token): CifValue | null;
/**
 * Split a token array at `data_` headers, returning `[name, tokens]` pairs.
 */
declare function parseDataBlocks(ciftokens: Token[]): [string, Token[]][];
/**
 * Parse a sequence of tokens representing the body of a data block into
 * structured data items.
 */
declare function parseDataItems(blocktokens: Token[]): DataItem[];
/**
 * Parse a CIF file string into a dictionary of named data blocks and their
 * items.  This is the low-level API; for full crystal structures use
 * `Atoms.readCif` or `parseCifStructures`.
 */
declare function parseCif(ciftext: string): CifDict;

/**
 * Convenience wrapper: parse a CIF string and return a dict of `Atoms`
 * instances keyed by data-block name.
 */
declare function parseCifStructures(ciftext: string): Record<string, Atoms>;

export { Atoms, type CellInput, type CellPar, type CifBlock, type CifDict, CifValue, type CifValueType, type DataItem, type LoopDataItem, type Matrix3x3, type SingleDataItem, type SymOp, type Token, type TokenType, type Vec3, cellToCellpar, cellparToCell, parseCif, parseCifStructures, parseDataBlocks, parseDataItems, parseValue, tokenize };
