Files
church-translate/app/_test-guard-real.js
T
christianandClaude Opus 5 c9eef0672c Church Translate, as it runs at the campuses
Live sermon translation into 100+ languages, running entirely on one Mac per
campus: audio in, voice detection, Whisper on the GPU, NLLB-200 in its own
process, and a built-in web server the congregation reads from on their
phones. No audio leaves the building.

This is the source only. What used to sit beside it — 14 GB of speech and
translation models, 8 GB of voice bundles, 6 GB of natural voices, the Electron
caches, and the app data holding the operator PIN and every service transcript
— is machine state and downloaded assets, and stays in the NAS backup where it
belongs. The vendored node, cloudflared and Windows ffmpeg binaries are out too
(533 MB, re-fetched for packaging); the browser-side runtime beside them is
kept, so a checkout still serves the congregation page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 15:41:21 -04:00

44 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Run the guard over MEASURED NLLB output: 9 inputs x 10 languages.
The question is not "does it catch the bad one" — it is "does it leave the
other 89 alone". A guard that corrupts good output is worse than no guard,
because nobody in the building can read most of these. */
const G = require('./mt-guard.js');
const D = {
spa_Latn:["Donald Trump. ¿Qué es eso?","- Sí, estoy bien.","¡Aleluya!","Se llamaba John.","Abre al libro, Matthew.","Vuelva conmigo a Juan capítulo 3.","Jesús lloró.","¡Alabado sea el Señor!","Pedro lo negó tres veces."],
por_Latn:["Donald Trump.","- Não, não.","Aleluia!","O nome dele era John.","Abre-te ao livro, Matthew.","Virem comigo para João capítulo 3.","Jesus chorou.","Louvem o Senhor.","Pedro negou-o três vezes."],
fra_Latn:["Donald Trump est là.","Je vous en prie.","Je vous en prie.","Il s'appelait John.","Ouvre-toi au livre, Matthew.","Tournez- vous avec moi vers Jean chapitre 3.","Jésus pleurait.","Louez le Seigneur.","Pierre le nia trois fois."],
deu_Latn:["Donald Trump.","- Das ist doch gut.","Halleluja!","Sein Name war John.","Mach dir das Buch zu, Matthew.","Wenden Sie sich mit mir an Johannes Kapitel 3.","Jesus weinte.","Lob dem Herrn.","Petrus verleugnete ihn dreimal."],
kor_Hang:["도널드 트럼프","아멘","할렐루야","그의 이름은 존이었다.","책에 들어봐, 매튜","요한 3 장에 나와 함께 가십시오.","예수께서는 울었습니다.","하나님께 영광을 돌리소서","베드로가 그를 세 번 부인했다."],
zho_Hans:["唐纳德特朗普.","现在,我们要去.","哈利鲁亚!","他的名字是约翰.","开放给书,马修.","转向约翰第三章.","耶稣哭了.","赞美上帝.","彼得否认他三次."],
rus_Cyrl:["Дональд Трамп.","- Да, да.","- Хэллюя.","Его звали Джон.","Открой глаза на книгу, Мэтью.","Повернись со мной к Иоанну, главе 3.","Иисус заплакал.","Слава Богу.","Петр трижды отрицал его."],
arb_Arab:["دونالد ترامب","آمين","هليليا","اسمه كان جون","افتح نفسك للكتب يا (ماثيو)","انعطف معي إلى يوحنا الفصل الثالث","يسوع يبكي","-حمد الله","بـطـرس نـكره ثلاث مرات"],
hat_Latn:["Donald Trump.","Amen.","Aleluya.","Non l te rele John.","Ouvri pou liv la, Matthew.","Fè m 'konnen Jan chapit 3.","Jezi te kriye.","Fè Bondye lwanj.","Pyè te refize l twa fwa."],
vie_Latn:["Donald Trump.","- A-men.","Hallelujah.","Tên anh ta là John.","Mở ra sách, Matthew.","Hãy cùng tôi đọc Giăng chương 3.","Chúa Giêsu khóc.","Chúc mừng Chúa.","Phi-e-rơ đã từ chối ông ba lần."]
};
const SRC = ["Donald Trump.","Amen.","Hallelujah.","His name was John.","Open up to the book, Matthew.","Turn with me to John chapter 3.","Jesus wept.","Praise the Lord.","Peter denied him three times."];
/* The ONLY output that should lose words. Everything else may lose a leading
dash and nothing more. */
/* index 0 is "Donald Trump." (invented question); index 1 is "Amen.", a
one-word source whose comma-clause is invented in several languages. */
const MAY_LOSE_WORDS = new Set(['spa_Latn|0','spa_Latn|1','por_Latn|1','zho_Hans|1','rus_Cyrl|1']);
let touched = 0, dashOnly = 0, wordLoss = 0, bad = 0;
for (const lang of Object.keys(D)) {
D[lang].forEach((tgt, i) => {
const r = G.clean(SRC[i], tgt);
if (r.text === tgt) return;
touched++;
const strippedDash = tgt.replace(/^\s*[-‐-―−]\s*/, '').trim();
if (r.text === strippedDash) { dashOnly++; console.log(' dash ' + lang + ' "' + tgt + '" -> "' + r.text + '"'); return; }
wordLoss++;
const allowed = MAY_LOSE_WORDS.has(lang + '|' + i);
console.log((allowed ? ' TRIM ' : ' !!BAD ') + lang + ' "' + tgt + '" -> "' + r.text + '"');
if (r.reason) console.log(' ' + r.reason);
if (!allowed) bad++;
});
}
console.log('\n90 measured outputs: ' + touched + ' touched, ' + dashOnly + ' dash-only, ' +
wordLoss + ' word-loss, ' + bad + ' UNEXPECTED');
process.exit(bad ? 1 : 0);