/**
 * Grammar Types for Semantic Multilingual Parsing
 *
 * These types define the semantic role system used across all 13 supported languages.
 * Originally from @lokascript/i18n, now consolidated here for package independence.
 *
 * Key Linguistic Concepts:
 * - Word Order: SVO, SOV, VSO (and variations)
 * - Adposition Type: Preposition (English) vs Postposition (Japanese/Korean)
 * - Morphology: Isolating (Chinese) vs Agglutinative (Turkish) vs Fusional (Arabic)
 * - Text Direction: LTR vs RTL
 */
/**
 * Semantic roles in hyperscript commands.
 * These are universal across all 13 supported languages - only the surface form changes.
 *
 * ## Core Thematic Roles (from linguistic theory)
 * | Role        | Usage | Purpose                     | Example                   |
 * |-------------|-------|-----------------------------|---------------------------|
 * | action      | 100%  | Command verb                | toggle, put, fetch        |
 * | patient     | 90%   | What is acted upon          | .active, #count           |
 * | destination | 40%   | Where something goes        | into #output, to .class   |
 * | source      | 13%   | Where something comes from  | from #input, from URL     |
 * | event       | 106%  | Trigger events              | click, keydown, submit    |
 * | condition   | 8%    | Boolean expressions         | if x > 5, when visible    |
 * | agent       | 0%    | Who performs action         | Reserved for future use   |
 * | goal        | 1%    | Target value/state          | to 'red' (in transition)  |
 *
 * ## Quantitative Roles (answer "how much/long")
 * | Role     | Usage | Purpose        | Example              |
 * |----------|-------|----------------|----------------------|
 * | quantity | 7%    | Numeric amount | by 5, 3 times        |
 * | duration | 1%    | Time span      | for 5 seconds, 500ms |
 *
 * ## Adverbial/Modifier Roles (answer "how/by what means")
 * | Role         | Usage | Purpose                   | Example           |
 * |--------------|-------|---------------------------|-------------------|
 * | style        | 2%    | Animation/behavior        | with fade         |
 * | manner       | 2%    | Insertion position        | before, after     |
 * | method       | 1%    | HTTP method/technique     | via POST, as GET  |
 * | responseType | 1%    | Response format           | as json, as html  |
 *
 * ## Control Flow Roles
 * | Role     | Usage | Purpose      | Example               |
 * |----------|-------|--------------|-----------------------|
 * | loopType | 6%    | Loop variant | forever, until, times |
 *
 * ## Design Notes
 * - Low-usage roles (agent, goal, method, responseType) are intentionally kept for:
 *   - Linguistic completeness across all 13 languages
 *   - Future extensibility (AI agents, server-side execution)
 *   - Command-specific semantics (fetch, transition)
 * - Each role has distinct grammatical markers per language (see profiles/index.ts)
 * - Usage percentages based on pattern database analysis
 */
type SemanticRole = 'action' | 'agent' | 'patient' | 'source' | 'destination' | 'goal' | 'event' | 'condition' | 'quantity' | 'duration' | 'responseType' | 'method' | 'style' | 'manner' | 'loopType' | 'continues';

/**
 * Semantic-First Multilingual Hyperscript Types
 *
 * This module defines the canonical semantic representation that all languages
 * parse to and render from. The semantic layer is language-neutral - it captures
 * the MEANING of hyperscript commands independent of surface syntax.
 */

interface SourcePosition {
    readonly start: number;
    readonly end: number;
    readonly line?: number;
    readonly column?: number;
}
/**
 * A token from language-specific tokenization.
 */
interface LanguageToken {
    readonly value: string;
    readonly kind: TokenKind;
    readonly position: SourcePosition;
    /** Normalized form from explicit keyword map (e.g., 切り替え → toggle) */
    readonly normalized?: string;
    /** Morphologically normalized stem (e.g., 切り替えた → 切り替え) */
    readonly stem?: string;
    /** Confidence in the morphological stem (0.0-1.0) */
    readonly stemConfidence?: number;
    /** Additional metadata for specific token types (e.g., event modifier data) */
    readonly metadata?: Record<string, unknown>;
}
type TokenKind = 'keyword' | 'selector' | 'literal' | 'particle' | 'conjunction' | 'event-modifier' | 'identifier' | 'operator' | 'punctuation' | 'url';
/**
 * A stream of tokens with navigation capabilities.
 */
interface TokenStream {
    readonly tokens: readonly LanguageToken[];
    readonly language: string;
    /** Look at token at current position + offset without consuming */
    peek(offset?: number): LanguageToken | null;
    /** Consume and return current token, advance position */
    advance(): LanguageToken;
    /** Check if we've consumed all tokens */
    isAtEnd(): boolean;
    /** Save current position for backtracking */
    mark(): StreamMark;
    /** Restore to a saved position */
    reset(mark: StreamMark): void;
    /** Get current position */
    position(): number;
}
interface StreamMark {
    readonly position: number;
}
/**
 * Language-specific tokenizer interface.
 * Each language implements its own tokenizer to handle:
 * - Word boundaries (spaces for English, particles for Japanese)
 * - Character sets (ASCII, CJK, Arabic, etc.)
 * - Special markers (particles, prefixes, suffixes)
 */
interface LanguageTokenizer {
    readonly language: string;
    readonly direction: 'ltr' | 'rtl';
    /** Convert input string to token stream */
    tokenize(input: string): TokenStream;
    /** Classify a single token */
    classifyToken(token: string): TokenKind;
}

/**
 * Morphological Normalizer Types
 *
 * Defines interfaces for language-specific morphological analysis.
 * Normalizers reduce conjugated/inflected forms to canonical stems
 * that can be matched against keyword dictionaries.
 */
/**
 * Result of morphological normalization.
 */
interface NormalizationResult {
    /** The extracted stem/root form */
    readonly stem: string;
    /** Confidence in the normalization (0.0-1.0) */
    readonly confidence: number;
    /** Optional metadata about the transformation */
    readonly metadata?: NormalizationMetadata;
}
/**
 * Metadata about morphological transformations applied.
 */
interface NormalizationMetadata {
    /** Prefixes that were removed */
    readonly removedPrefixes?: readonly string[];
    /** Suffixes that were removed */
    readonly removedSuffixes?: readonly string[];
    /** Type of conjugation detected */
    readonly conjugationType?: ConjugationType;
    /** Original form classification */
    readonly originalForm?: string;
    /** Applied transformation rules (for debugging) */
    readonly appliedRules?: readonly string[];
}
/**
 * Types of verb conjugation/inflection.
 */
type ConjugationType = 'present' | 'past' | 'future' | 'progressive' | 'perfect' | 'imperative' | 'subjunctive' | 'conditional' | 'passive' | 'causative' | 'polite' | 'humble' | 'honorific' | 'negative' | 'potential' | 'volitional' | 'conditional-tara' | 'conditional-to' | 'conditional-ba' | 'connective' | 'conditional-myeon' | 'temporal-ttae' | 'causal-nikka' | 'honorific-conditional' | 'honorific-temporal' | 'honorific-causal' | 'honorific-past' | 'honorific-polite' | 'sequential-after' | 'sequential-before' | 'immediate' | 'obligation' | 'reflexive' | 'reflexive-imperative' | 'gerund' | 'participle' | 'conditional-idha' | 'temporal-indama' | 'temporal-hina' | 'temporal-lamma' | 'past-verb' | 'conditional-se' | 'temporal-ince' | 'temporal-dikce' | 'aorist' | 'optative' | 'necessitative' | 'request' | 'casual-request' | 'contracted' | 'contracted-past' | 'compound' | 'te-form' | 'dictionary';
/**
 * Interface for language-specific morphological normalizers.
 *
 * Normalizers attempt to reduce inflected word forms to their
 * canonical stems. This enables matching conjugated verbs against
 * keyword dictionaries that only contain base forms.
 *
 * Example (Japanese):
 *   切り替えた (past) → { stem: '切り替え', confidence: 0.85 }
 *   切り替えます (polite) → { stem: '切り替え', confidence: 0.85 }
 *
 * Example (Spanish):
 *   mostrarse (reflexive infinitive) → { stem: 'mostrar', confidence: 0.85 }
 *   alternando (gerund) → { stem: 'alternar', confidence: 0.85 }
 */
interface MorphologicalNormalizer {
    /** Language code this normalizer handles */
    readonly language: string;
    /**
     * Normalize a word to its canonical stem form.
     *
     * @param word - The word to normalize
     * @returns Normalization result with stem and confidence
     */
    normalize(word: string): NormalizationResult;
    /**
     * Check if a word appears to be a verb form that can be normalized.
     * Optional optimization to skip normalization for non-verb tokens.
     *
     * @param word - The word to check
     * @returns true if the word might be a normalizable verb form
     */
    isNormalizable?(word: string): boolean;
}

/**
 * Base Tokenizer
 *
 * Provides the TokenStream implementation and shared tokenization utilities.
 * Language-specific tokenizers extend these base utilities.
 */

/**
 * Configuration for a native language time unit pattern.
 * Used by tryNumberWithTimeUnits() to match language-specific time units.
 */
interface TimeUnitMapping {
    /** The pattern to match (e.g., 'segundos', 'ミリ秒') */
    readonly pattern: string;
    /** The standard suffix to use (ms, s, m, h) */
    readonly suffix: string;
    /** Length of the pattern (for optimization) */
    readonly length: number;
    /** Whether to check for word boundary after the pattern */
    readonly checkBoundary?: boolean;
    /** Character that cannot follow the pattern (e.g., 's' for 'm' to avoid 'ms') */
    readonly notFollowedBy?: string;
    /** Whether to do case-insensitive matching */
    readonly caseInsensitive?: boolean;
}
/**
 * Keyword entry for tokenizer - maps native word to normalized English form.
 */
interface KeywordEntry {
    readonly native: string;
    readonly normalized: string;
}
/**
 * Profile interface for keyword derivation.
 * Matches the structure of LanguageProfile but only includes fields needed for tokenization.
 */
interface TokenizerProfile {
    readonly keywords?: Record<string, {
        primary: string;
        alternatives?: string[];
        normalized?: string;
    }>;
    readonly references?: Record<string, string>;
    readonly roleMarkers?: Record<string, {
        primary: string;
        alternatives?: string[];
        position?: string;
    }>;
}
/**
 * Abstract base class for language-specific tokenizers.
 * Provides common functionality for CSS selectors, strings, and numbers.
 */
declare abstract class BaseTokenizer implements LanguageTokenizer {
    abstract readonly language: string;
    abstract readonly direction: 'ltr' | 'rtl';
    /** Optional morphological normalizer for this language */
    protected normalizer?: MorphologicalNormalizer;
    /** Keywords derived from profile, sorted longest-first for greedy matching */
    protected profileKeywords: KeywordEntry[];
    /** Map for O(1) keyword lookups by lowercase native word */
    protected profileKeywordMap: Map<string, KeywordEntry>;
    abstract tokenize(input: string): TokenStream;
    abstract classifyToken(token: string): TokenKind;
    /**
     * Initialize keyword mappings from a language profile.
     * Builds a list of native→english mappings from:
     * - profile.keywords (primary + alternatives)
     * - profile.references (me, it, you, etc.)
     * - profile.roleMarkers (into, from, with, etc.)
     *
     * Results are sorted longest-first for greedy matching (important for non-space languages).
     * Extras take precedence over profile entries when there are duplicates.
     *
     * @param profile - Language profile containing keyword translations
     * @param extras - Additional keyword entries to include (literals, positional, events)
     */
    protected initializeKeywordsFromProfile(profile: TokenizerProfile, extras?: KeywordEntry[]): void;
    /**
     * Remove diacritical marks from a word for normalization.
     * Primarily for Arabic (shadda, fatha, kasra, damma, sukun, etc.)
     * but could be extended for other languages.
     *
     * @param word - Word to normalize
     * @returns Word without diacritics
     */
    protected removeDiacritics(word: string): string;
    /**
     * Try to match a keyword from profile at the current position.
     * Uses longest-first greedy matching (important for non-space languages).
     *
     * @param input - Input string
     * @param pos - Current position
     * @returns Token if matched, null otherwise
     */
    protected tryProfileKeyword(input: string, pos: number): LanguageToken | null;
    /**
     * Check if the remaining input starts with any known keyword.
     * Useful for non-space languages to detect word boundaries.
     *
     * @param input - Input string
     * @param pos - Current position
     * @returns true if a keyword starts at this position
     */
    protected isKeywordStart(input: string, pos: number): boolean;
    /**
     * Look up a keyword by native word (case-insensitive).
     * O(1) lookup using the keyword map.
     *
     * @param native - Native word to look up
     * @returns KeywordEntry if found, undefined otherwise
     */
    protected lookupKeyword(native: string): KeywordEntry | undefined;
    /**
     * Check if a word is a known keyword (case-insensitive).
     * O(1) lookup using the keyword map.
     *
     * @param native - Native word to check
     * @returns true if the word is a keyword
     */
    protected isKeyword(native: string): boolean;
    /**
     * Set the morphological normalizer for this tokenizer.
     */
    setNormalizer(normalizer: MorphologicalNormalizer): void;
    /**
     * Try to normalize a word using the morphological normalizer.
     * Returns null if no normalizer is set or normalization fails.
     *
     * Note: We don't check isNormalizable() here because the individual tokenizers
     * historically called normalize() directly without that check. The normalize()
     * method itself handles returning noChange() for words that can't be normalized.
     */
    protected tryNormalize(word: string): NormalizationResult | null;
    /**
     * Try morphological normalization and keyword lookup.
     *
     * If the word can be normalized to a stem that matches a known keyword,
     * returns a keyword token with morphological metadata (stem, stemConfidence).
     *
     * This is the common pattern for handling conjugated verbs across languages:
     * 1. Normalize the word (e.g., "toggled" → "toggle")
     * 2. Look up the stem in the keyword map
     * 3. Create a token with both the original form and stem metadata
     *
     * @param word - The word to normalize and look up
     * @param startPos - Start position for the token
     * @param endPos - End position for the token
     * @returns Token if stem matches a keyword, null otherwise
     */
    protected tryMorphKeywordMatch(word: string, startPos: number, endPos: number): LanguageToken | null;
    /**
     * Try to extract a CSS selector at the current position.
     */
    protected trySelector(input: string, pos: number): LanguageToken | null;
    /**
     * Try to extract an event modifier at the current position.
     * Event modifiers are .once, .debounce(N), .throttle(N), .queue(strategy)
     */
    protected tryEventModifier(input: string, pos: number): LanguageToken | null;
    /**
     * Try to extract a string literal at the current position.
     */
    protected tryString(input: string, pos: number): LanguageToken | null;
    /**
     * Try to extract a number at the current position.
     */
    protected tryNumber(input: string, pos: number): LanguageToken | null;
    /**
     * Configuration for native language time units.
     * Maps patterns to their standard suffix (ms, s, m, h).
     */
    protected static readonly STANDARD_TIME_UNITS: readonly TimeUnitMapping[];
    /**
     * Try to match a time unit from a list of patterns.
     *
     * @param input - Input string
     * @param pos - Position after the number
     * @param timeUnits - Array of time unit mappings (native pattern → standard suffix)
     * @param skipWhitespace - Whether to skip whitespace before time unit (default: false)
     * @returns Object with matched suffix and new position, or null if no match
     */
    protected tryMatchTimeUnit(input: string, pos: number, timeUnits: readonly TimeUnitMapping[], skipWhitespace?: boolean): {
        suffix: string;
        endPos: number;
    } | null;
    /**
     * Parse a base number (sign, integer, decimal) without time units.
     * Returns the number string and end position.
     *
     * @param input - Input string
     * @param startPos - Start position
     * @param allowSign - Whether to allow +/- sign (default: true)
     * @returns Object with number string and end position, or null
     */
    protected parseBaseNumber(input: string, startPos: number, allowSign?: boolean): {
        number: string;
        endPos: number;
    } | null;
    /**
     * Try to extract a number with native language time units.
     *
     * This is a template method that handles the common pattern:
     * 1. Parse the base number (sign, integer, decimal)
     * 2. Try to match native language time units
     * 3. Fall back to standard time units (ms, s, m, h)
     *
     * @param input - Input string
     * @param pos - Start position
     * @param nativeTimeUnits - Language-specific time unit mappings
     * @param options - Configuration options
     * @returns Token if number found, null otherwise
     */
    protected tryNumberWithTimeUnits(input: string, pos: number, nativeTimeUnits: readonly TimeUnitMapping[], options?: {
        allowSign?: boolean;
        skipWhitespace?: boolean;
    }): LanguageToken | null;
    /**
     * Try to extract a URL at the current position.
     * Handles /path, ./path, ../path, //domain.com, http://, https://
     */
    protected tryUrl(input: string, pos: number): LanguageToken | null;
    /**
     * Try to extract a variable reference (:varname) at the current position.
     * In hyperscript, :x refers to a local variable named x.
     */
    protected tryVariableRef(input: string, pos: number): LanguageToken | null;
    /**
     * Try to extract an operator or punctuation token at the current position.
     * Handles two-character operators (==, !=, etc.) and single-character operators.
     */
    protected tryOperator(input: string, pos: number): LanguageToken | null;
    /**
     * Try to match a multi-character particle from a list.
     *
     * Used by languages like Japanese, Korean, and Chinese that have
     * multi-character particles (e.g., Japanese から, まで, より).
     *
     * @param input - Input string
     * @param pos - Current position
     * @param particles - Array of multi-character particles to match
     * @returns Token if matched, null otherwise
     */
    protected tryMultiCharParticle(input: string, pos: number, particles: readonly string[]): LanguageToken | null;
}

/**
 * Language Profile Types
 *
 * Type definitions for language profiles, separated for tree-shaking.
 */

/**
 * Word order in a language (for declarative statements).
 */
type WordOrder = 'SVO' | 'SOV' | 'VSO' | 'VOS' | 'OSV' | 'OVS';
/**
 * How grammatical relationships are marked.
 */
type MarkingStrategy = 'preposition' | 'postposition' | 'particle' | 'case-suffix';
/**
 * A grammatical marker (preposition, particle, etc.) for a semantic role.
 */
interface RoleMarker {
    /** Primary marker for this role */
    readonly primary: string;
    /** Alternative markers that also work */
    readonly alternatives?: string[];
    /** Position relative to the role value */
    readonly position: 'before' | 'after';
}
/**
 * Verb form configuration for a language.
 */
interface VerbConfig {
    /** Position of verb in the sentence */
    readonly position: 'start' | 'end' | 'second';
    /** Common verb suffixes/conjugations to recognize */
    readonly suffixes?: string[];
    /** Whether the language commonly drops subjects */
    readonly subjectDrop?: boolean;
}
/**
 * Configuration for possessive expression construction.
 * Defines how "X's property" is expressed in a language.
 */
interface PossessiveConfig {
    /** Possessive marker (e.g., "'s" in English, "の" in Japanese) */
    readonly marker: string;
    /** Position of marker: 'after-object' (X's Y), 'between' (X の Y), 'before-property' */
    readonly markerPosition: 'after-object' | 'between' | 'before-property';
    /** Special possessive forms (e.g., 'me' → 'my' in English) */
    readonly specialForms?: Record<string, string>;
    /** Whether to use possessive adjectives instead of marker (e.g., Spanish mi/tu/su) */
    readonly usePossessiveAdjectives?: boolean;
    /**
     * Possessive keywords mapped to their corresponding reference.
     * Used by pattern-matcher to recognize possessive expressions.
     * Example: { my: 'me', your: 'you', its: 'it' }
     */
    readonly keywords?: Record<string, string>;
}
/**
 * Complete language profile for pattern generation.
 */
interface LanguageProfile {
    /** ISO 639-1 or BCP 47 language code (e.g., 'es' or 'es-MX') */
    readonly code: string;
    /** Human-readable language name */
    readonly name: string;
    /** Native name */
    readonly nativeName: string;
    /** Text direction */
    readonly direction: 'ltr' | 'rtl';
    /** Primary word order */
    readonly wordOrder: WordOrder;
    /** How this language marks grammatical roles */
    readonly markingStrategy: MarkingStrategy;
    /** Markers for each semantic role */
    readonly roleMarkers: Partial<Record<SemanticRole, RoleMarker>>;
    /** Verb configuration */
    readonly verb: VerbConfig;
    /** Command keyword translations */
    readonly keywords: Record<string, KeywordTranslation>;
    /** Whether the language uses spaces between words */
    readonly usesSpaces: boolean;
    /** Special tokenization notes */
    readonly tokenization?: TokenizationConfig;
    /** Reference translations (me, it, you, etc.) */
    readonly references?: Record<string, string>;
    /** Possessive expression configuration */
    readonly possessive?: PossessiveConfig;
    /** Event handler pattern configuration (for simple SVO languages) */
    readonly eventHandler?: EventHandlerConfig;
    /**
     * Default verb form for command keywords. Defaults to 'infinitive'.
     *
     * Based on software UI localization research:
     * - 'infinitive': Spanish, French, German, Portuguese, Russian (industry standard)
     * - 'imperative': Polish
     * - 'base': English, Japanese, Korean (no distinction or same form)
     *
     * Individual keywords can override this via KeywordTranslation.form
     */
    readonly defaultVerbForm?: VerbForm;
    /**
     * Base language code to extend (for regional variants).
     * When set, this profile inherits from the base and overrides specific fields.
     * Example: 'es-MX' profile with extends: 'es' inherits from Spanish base.
     */
    readonly extends?: string;
}
/**
 * Configuration for event handler pattern generation.
 * Supports both SVO and SOV/VSO languages.
 */
interface EventHandlerConfig {
    /** Primary event keyword (e.g., 'on', 'bei', 'sur') for SVO */
    readonly keyword?: KeywordTranslation;
    /** Source filter marker (e.g., 'from', 'von', 'de') */
    readonly sourceMarker?: RoleMarker;
    /** Conditional keyword (e.g., 'when', 'wenn', 'quand') */
    readonly conditionalKeyword?: KeywordTranslation;
    /** Event marker for SOV/VSO languages (e.g., で (Japanese), 할 때 (Korean), da (Turkish), عند (Arabic)) */
    readonly eventMarker?: RoleMarker;
    /** Temporal/conditional markers that can optionally appear with events */
    readonly temporalMarkers?: string[];
    /**
     * Negation marker for expressing negated events (e.g., Arabic عدم = "not/lack of").
     * Used in patterns like: عند عدم التركيز = "when not focusing" = "on blur"
     */
    readonly negationMarker?: RoleMarker;
}
/**
 * Verb form used for command keywords.
 *
 * Based on software localization research:
 * - 'infinitive': Standard for most languages (Spanish, French, German, Russian)
 *   Example: "Guardar", "Enregistrer", "Speichern"
 * - 'imperative': Used by some languages (Polish)
 *   Example: "Zapisz", "Otwórz"
 * - 'base': For languages where forms are identical (English, Japanese, Korean)
 *   or where the distinction doesn't apply
 */
type VerbForm = 'infinitive' | 'imperative' | 'base';
/**
 * Translation of a command keyword.
 */
interface KeywordTranslation {
    /** Primary translation (used for output/rendering) */
    readonly primary: string;
    /** Alternative forms for parsing (conjugations, synonyms, informal variants) */
    readonly alternatives?: string[];
    /** Normalized English form for internal matching */
    readonly normalized?: string;
    /**
     * The grammatical form of 'primary'. Defaults to 'infinitive'.
     * This documents the form used and enables future form-switching features.
     * - 'infinitive': Dictionary form (alternar, basculer) - industry standard
     * - 'imperative': Command form (alterna, bascule) - for Polish, etc.
     * - 'base': Same form for both (toggle, トグル) - English, Japanese, Korean
     */
    readonly form?: VerbForm;
}
/**
 * Special tokenization configuration.
 */
interface TokenizationConfig {
    /** Particles to recognize (for particle languages) */
    readonly particles?: string[];
    /** Prefixes to recognize (for prefixing languages) */
    readonly prefixes?: string[];
    /** Word boundary detection strategy */
    readonly boundaryStrategy?: 'space' | 'particle' | 'character';
}

export { BaseTokenizer as B, type LanguageProfile as L, type TokenStream as T, type TokenKind as a };
