/** * Simple pinyin initial matching for Chinese oil names. * Maps common Chinese characters used in essential oil names to their pinyin initials. * This is a lightweight approach - no full pinyin library needed. */ // Common characters in essential oil / herb names mapped to pinyin initials const PINYIN_MAP = { '薰': 'x', '衣': 'y', '草': 'c', '茶': 'c', '树': 's', '柠': 'n', '檬': 'm', '薄': 'b', '荷': 'h', '迷': 'm', '迭': 'd', '香': 'x', '乳': 'r', '沉': 'c', '丝': 's', '柏': 'b', '尤': 'y', '加': 'j', '利': 'l', '丁': 'd', '肉': 'r', '桂': 'g', '罗': 'l', '勒': 'l', '百': 'b', '里': 'l', '牛': 'n', '至': 'z', '马': 'm', '鞭': 'b', '天': 't', '竺': 'z', '葵': 'k', '生': 's', '姜': 'j', '黑': 'h', '胡': 'h', '椒': 'j', '玫': 'm', '瑰': 'g', '茉': 'm', '莉': 'l', '依': 'y', '兰': 'l', '花': 'h', '橙': 'c', '佛': 'f', '手': 's', '柑': 'g', '葡': 'p', '萄': 't', '柚': 'y', '甜': 't', '苦': 'k', '野': 'y', '山': 's', '松': 's', '杉': 's', '杜': 'd', '雪': 'x', '莲': 'l', '芦': 'l', '荟': 'h', '白': 'b', '芷': 'z', '当': 'd', '归': 'g', '川': 'c', '芎': 'x', '红': 'h', '枣': 'z', '枸': 'g', '杞': 'q', '菊': 'j', '洋': 'y', '甘': 'g', '菘': 's', '蓝': 'l', '永': 'y', '久': 'j', '快': 'k', '乐': 'l', '鼠': 's', '尾': 'w', '岩': 'y', '冷': 'l', '杰': 'j', '绿': 'lv', '芫': 'y', '荽': 's', '椰': 'y', '子': 'z', '油': 'y', '基': 'j', '底': 'd', '精': 'j', '纯': 'c', '露': 'l', '木': 'm', '果': 'g', '叶': 'y', '根': 'g', '皮': 'p', '籽': 'z', '仁': 'r', '大': 'd', '小': 'x', '西': 'x', '东': 'd', '南': 'n', '北': 'b', '中': 'z', '新': 'x', '古': 'g', '老': 'l', '春': 'c', '夏': 'x', '秋': 'q', '冬': 'd', '温': 'w', '热': 'r', '凉': 'l', '冰': 'b', '火': 'h', '水': 's', '金': 'j', '银': 'y', '铜': 't', '铁': 't', '玉': 'y', '珍': 'z', '珠': 'z', '翠': 'c', '碧': 'b', '紫': 'z', '青': 'q', '蓝': 'l', '绿': 'lv', '黄': 'h', '棕': 'z', '褐': 'h', '灰': 'h', '粉': 'f', '豆': 'd', '蔻': 'k', '藿': 'h', '苏': 's', '萃': 'c', '缬': 'x', '安': 'a', '息': 'x', '宁': 'n', '静': 'j', '和': 'h', '平': 'p', '舒': 's', '缓': 'h', '放': 'f', '松': 's', '活': 'h', '力': 'l', '能': 'n', '量': 'l', '保': 'b', '护': 'h', '防': 'f', '御': 'y', '健': 'j', '康': 'k', '美': 'm', '丽': 'l', '清': 'q', '新': 'x', '自': 'z', '然': 'r', '植': 'z', '物': 'w', '芳': 'f', '疗': 'l', '复': 'f', '方': 'f', '单': 'd', '配': 'p', '调': 'd', '忍': 'r', '圆': 'y', '侧': 'c', '呵': 'h', '铠': 'k', '浆': 'j', '萸': 'y', '瑞': 'r', '芙': 'f', '蓉': 'r', '桃': 't', '梅': 'm', '兰': 'l', '竹': 'z', '荆': 'j', '藏': 'z', '蒿': 'h', '艾': 'a', '牡': 'm', '丹': 'd', '参': 's', '芝': 'z', '灵': 'l', '芍': 's', '药': 'y', '枫': 'f', '桦': 'h', '柳': 'l', '榉': 'j', '楠': 'n', '海': 'h', '滨': 'b', '泽': 'z', '湖': 'h', '溪': 'x', '威': 'w', '夷': 'y', '亚': 'y', '欧': 'o', '非': 'f', '印': 'y', '澳': 'a', '美': 'm', '德': 'd', '法': 'f', '意': 'y', '英': 'y', '日': 'r', '韩': 'h', '泰': 't', '醒': 'x', '提': 't', '振': 'z', '镇': 'z', '抚': 'f', '触': 'c', '修': 'x', '养': 'y', '滋': 'z', '润': 'r', '呼': 'h', '吸': 'x', '消': 'x', '化': 'h', '排': 'p', '毒': 'd', '净': 'j', '纤': 'x', '体': 't', '塑': 's', // Extended: all oil name chars '麦': 'm', '卢': 'l', '卡': 'k', '檀': 't', '橘': 'j', '茅': 'm', '茴': 'h', '芹': 'q', '菜': 'c', '蕾': 'l', '蜂': 'f', '蓍': 's', '莱': 'l', '姆': 'm', '莎': 's', '穗': 's', '醇': 'c', '郁': 'y', '没': 'm', '脂': 'z', '巴': 'b', '样': 'y', '班': 'b', '牙': 'y', '鸡': 'j', '苍': 'c', '卫': 'w', '畅': 'c', '顺': 's', '释': 's', '悦': 'y', '柔': 'r', '压': 'y', '定': 'd', '情': 'q', '绪': 'x', '神': 's', '气': 'q', '宽': 'k', '容': 'r', '恬': 't', '家': 'j', '欢': 'h', '欣': 'x', '舞': 'w', '鼓': 'g', '赋': 'f', '谧': 'm', '睡': 's', '烂': 'l', '绚': 'x', '焕': 'h', '肤': 'f', '年': 'n', '华': 'h', '完': 'w', '理': 'l', '注': 'z', '贯': 'g', '全': 'q', '仕': 's', '女': 'nv', '伯': 'b', '斯': 's', '道': 'd', '格': 'g', '拉': 'l', '元': 'y', '肌': 'j', '栀': 'z', '鹅': 'e', '掌': 'z', '柴': 'c', '胶': 'j', '囊': 'n', '空': 'k', '风': 'f', '文': 'w', '月': 'y', '云': 'y', '五': 'w', '味': 'w', '愈': 'y', '创': 'c', '慰': 'w', '扁': 'b', '广': 'g', '州': 'z', '热': 'r', // Product name chars '身': 's', '紧': 'j', '致': 'z', '霜': 's', '膏': 'g', '膜': 'm', '乳': 'r', '液': 'y', '瓶': 'p', '盒': 'h', '深': 's', '层': 'c', '肤': 'f', '磨': 'm', '砂': 's', '龄': 'l', '无': 'w', '年': 'n', '华': 'h', '娇': 'j', '颜': 'y', '喷': 'p', '雾': 'w', '面': 'm', '湿': 's', } /** * Get pinyin initials string for a Chinese name. * e.g. "薰衣草" -> "xyc" */ export function getPinyinInitials(name) { let result = '' for (const char of name) { const initial = PINYIN_MAP[char] if (initial) { result += initial } } return result } /** * Check if a query matches a name by pinyin initials. * Supports: prefix match, substring match, and subsequence match. */ export function matchesPinyinInitials(name, query) { if (!query || !name) return false const initials = getPinyinInitials(name) if (!initials) return false const q = query.toLowerCase() // Prefix or substring (consecutive) if (initials.includes(q)) return true // Subsequence: each char of q appears in order in initials let pos = 0 for (const ch of q) { pos = initials.indexOf(ch, pos) if (pos === -1) return false pos++ } return true } /** * Score how well a query matches pinyin initials. * 0 = prefix, 1 = substring, 2 = subsequence, -1 = no match */ export function pinyinMatchScore(name, query) { if (!query || !name) return -1 const initials = getPinyinInitials(name) if (!initials) return -1 const q = query.toLowerCase() if (initials.startsWith(q)) return 0 if (initials.includes(q)) return 1 // Subsequence check let pos = 0 for (const ch of q) { pos = initials.indexOf(ch, pos) if (pos === -1) return -1 pos++ } return 2 }