/* * short-questions.js — one-word questions that must never be guessed at. * * MEASURED: "What?" is the single most frequent invented line left after every * other guard — the shipped NLLB renders it "¿Qué es eso?" (15 archive rows), * "Yeah?" -> "¿Qué es eso?" (6), "Hello?" -> "¿Qué pasa?" (6), "How?" -> "¿Cómo * es que lo hizo?" (3). The preacher says "What?" about three times a service. * Because the SOURCE is itself a question, the hallucination guard rightly * refuses to blank the output (a Spanish question is the correct shape) — so * these bypass the model altogether, the way liturgy.js does for "Amen". * * Whole-utterance match only, one word, terminal '?' or '.' or nothing. The * table holds only words whose one-word rendering is not a matter of register * or denomination. Languages not listed fall through to the model unchanged. */ (function (root, factory) { if (typeof module === 'object' && module.exports) module.exports = factory(); else root.ShortQuestions = factory(); }(typeof self !== 'undefined' ? self : this, function () { 'use strict'; /* word -> { lang: rendering } — the base language stands for its variants. */ const TABLE = { what: { spa_Latn: '¿Qué?', por_Latn: 'O quê?', fra_Latn: 'Quoi ?', deu_Latn: 'Was?', ita_Latn: 'Cosa?' }, why: { spa_Latn: '¿Por qué?', por_Latn: 'Por quê?', fra_Latn: 'Pourquoi ?', deu_Latn: 'Warum?', ita_Latn: 'Perché?' }, who: { spa_Latn: '¿Quién?', por_Latn: 'Quem?', fra_Latn: 'Qui ?', deu_Latn: 'Wer?', ita_Latn: 'Chi?' }, how: { spa_Latn: '¿Cómo?', por_Latn: 'Como?', fra_Latn: 'Comment ?', deu_Latn: 'Wie?', ita_Latn: 'Come?' }, where: { spa_Latn: '¿Dónde?', por_Latn: 'Onde?', fra_Latn: 'Où ?', deu_Latn: 'Wo?', ita_Latn: 'Dove?' }, when: { spa_Latn: '¿Cuándo?', por_Latn: 'Quando?', fra_Latn: 'Quand ?', deu_Latn: 'Wann?', ita_Latn: 'Quando?' }, which: { spa_Latn: '¿Cuál?', por_Latn: 'Qual?', fra_Latn: 'Lequel ?', deu_Latn: 'Welche?', ita_Latn: 'Quale?' }, yeah: { spa_Latn: '¿Sí?', por_Latn: 'Sim?', fra_Latn: 'Oui ?', deu_Latn: 'Ja?', ita_Latn: 'Sì?' }, yes: { spa_Latn: '¿Sí?', por_Latn: 'Sim?', fra_Latn: 'Oui ?', deu_Latn: 'Ja?', ita_Latn: 'Sì?' }, hello: { spa_Latn: '¿Hola?', por_Latn: 'Olá?', fra_Latn: 'Allô ?', deu_Latn: 'Hallo?', ita_Latn: 'Pronto?' }, right: { spa_Latn: '¿Verdad?', por_Latn: 'Certo?', fra_Latn: "N'est-ce pas ?", deu_Latn: 'Oder?', ita_Latn: 'Vero?' }, really: { spa_Latn: '¿En serio?', por_Latn: 'Sério?', fra_Latn: 'Vraiment ?', deu_Latn: 'Wirklich?', ita_Latn: 'Davvero?' }, okay: { spa_Latn: '¿Está bien?', por_Latn: 'Está bem?', fra_Latn: "D'accord ?", deu_Latn: 'Okay?', ita_Latn: 'Va bene?' }, ok: { spa_Latn: '¿Está bien?', por_Latn: 'Está bem?', fra_Latn: "D'accord ?", deu_Latn: 'Okay?', ita_Latn: 'Va bene?' }, ready: { spa_Latn: '¿Listos?', por_Latn: 'Prontos?', fra_Latn: 'Prêts ?', deu_Latn: 'Bereit?', ita_Latn: 'Pronti?' }, huh: { spa_Latn: '¿Eh?', por_Latn: 'Hã?', fra_Latn: 'Hein ?', deu_Latn: 'Hä?', ita_Latn: 'Eh?' } }; const VARIANT_OF = { spa_ES: 'spa_Latn', spa_MX: 'spa_Latn', por_PT: 'por_Latn' }; /* "What?", "what.", "WHAT", '"What?"' — one word, optionally punctuated. */ function key(text) { const t = String(text || '').trim().replace(/^[\s"'“‘(\[]+/u, '').replace(/[\s"'”’)\]]+$/u, ''); const m = t.match(/^([A-Za-z]+)[?.!…]*$/); return m ? m[1].toLowerCase() : null; } /* * Only a source that IS a question (ends in '?') or is a bare interrogative * word: "What." is Whisper dropping the mark; "What" alone is the same. A * bare "yes"/"okay"/"right"/"ready" with a period is an ANSWER, not a * question, and must reach the model as one — so those need the '?'. */ const NEEDS_MARK = new Set(['yeah', 'yes', 'hello', 'right', 'really', 'okay', 'ok', 'ready', 'huh']); function lookup(text, lang) { const k = key(text); if (!k || !TABLE[k]) return null; const asked = /\?[?!.…]*\s*["'”’)\]]*$/.test(String(text || '').trim()); if (!asked && NEEDS_MARK.has(k)) return null; const row = TABLE[k]; return row[lang] || row[VARIANT_OF[lang]] || null; } return { lookup, TABLE }; }));