"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.fuzzyFilter = fuzzyFilter;exports.fuzzyMatch = fuzzyMatch; /** * Fuzzy matching utilities. * Matches if all query characters appear in order (not necessarily consecutive). * Lower score = better match. */ function fuzzyMatch(query, text) { const queryLower = query.toLowerCase(); const textLower = text.toLowerCase(); const matchQuery = (normalizedQuery) => { if (normalizedQuery.length === 0) { return { matches: true, score: 0 }; } if (normalizedQuery.length > textLower.length) { return { matches: false, score: 0 }; } let queryIndex = 0; let score = 0; let lastMatchIndex = -1; let consecutiveMatches = 0; for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) { if (textLower[i] === normalizedQuery[queryIndex]) { const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]); // Reward consecutive matches if (lastMatchIndex === i - 1) { consecutiveMatches++; score -= consecutiveMatches * 5; } else { consecutiveMatches = 0; // Penalize gaps if (lastMatchIndex >= 0) { score += (i - lastMatchIndex - 1) * 2; } } // Reward word boundary matches if (isWordBoundary) { score -= 10; } // Slight penalty for later matches score += i * 0.1; lastMatchIndex = i; queryIndex++; } } if (queryIndex < normalizedQuery.length) { return { matches: false, score: 0 }; } return { matches: true, score }; }; const primaryMatch = matchQuery(queryLower); if (primaryMatch.matches) { return primaryMatch; } const alphaNumericMatch = queryLower.match(/^(?[a-z]+)(?[0-9]+)$/); const numericAlphaMatch = queryLower.match(/^(?[0-9]+)(?[a-z]+)$/); const swappedQuery = alphaNumericMatch ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}` : numericAlphaMatch ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}` : ""; if (!swappedQuery) { return primaryMatch; } const swappedMatch = matchQuery(swappedQuery); if (!swappedMatch.matches) { return primaryMatch; } return { matches: true, score: swappedMatch.score + 5 }; } /** * Filter and sort items by fuzzy match quality (best matches first). * Supports space-separated tokens: all tokens must match. */ function fuzzyFilter(items, query, getText) { if (!query.trim()) { return items; } const tokens = query. trim(). split(/\s+/). filter((t) => t.length > 0); if (tokens.length === 0) { return items; } const results = []; for (const item of items) { const text = getText(item); let totalScore = 0; let allMatch = true; for (const token of tokens) { const match = fuzzyMatch(token, text); if (match.matches) { totalScore += match.score; } else { allMatch = false; break; } } if (allMatch) { results.push({ item, totalScore }); } } results.sort((a, b) => a.totalScore - b.totalScore); return results.map((r) => r.item); } /* v9-c1b864ec9238fcc5 */