/** * Shared text-matching utilities (used by scoring detection and query * competitor exclusion). Pure, no dependencies. * * Matching is Unicode-aware: names in space-delimited scripts (Latin, Cyrillic, * Greek, ...) match on word boundaries; names in scripts without word * separators (CJK) match by substring, since a `\b`-style boundary never fires * there and would silently miss every mention. */ /** Lowercase and strip diacritics so "Café" folds to "cafe". */ export declare function fold(text: string): string; /** * First index of `term` in an already-folded `haystack`, respecting a * Unicode-aware word boundary, or -1. `term` is folded internally. * * A boundary holds at an edge when the character just outside the match and the * term's own edge character are not both word characters - so "ace" matches in * "Ace Hardware" but not in "space", "C++" matches next to spaces/punctuation, * and "acme.com" matches "shop.acme.com" but not "myacme.com". CJK terms skip * the boundary check (their scripts have no word separators). */ export declare function indexOfTerm(haystack: string, term: string): number; /** Whether `term` appears in an already-folded `haystack` (boundary-aware). */ export declare function mentionsTerm(haystack: string, term: string): boolean; /** * Extract the first balanced `open`...`close` block from `text`, or null. * * Depth-tracks nested delimiters and ignores any that appear inside a JSON * string literal (respecting `\"` escapes), so trailing prose braces do not * corrupt the slice (`lastIndexOf` would). Used to pull a JSON object/array out * of chatty LLM output. */ export declare function extractBalanced(text: string, open: string, close: string): string | null;