Censor profanity: "..." on screen, spoken as "beep"
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 29s

New profanity.js does whole-word matching against a Russian/English
root list (avoids false positives like "победа", "тебя", "сукно").
Applied once per message before it's used anywhere downstream
(display, TTS, AI reply input) — screen shows "..." in place of a
censored word, while the TTS text uses "бип" so it's heard as a beep
instead of read literally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
vrubelroman 2026-07-01 18:01:36 +00:00
parent f56b829054
commit 620c1e5427
4 changed files with 43 additions and 5 deletions

34
profanity.js Normal file
View file

@ -0,0 +1,34 @@
// Word-level profanity filter: matches whole words against a root list
// (so a root like "еб" only censors words that start with it, not every
// word containing that substring, e.g. "тебя", "победа").
// Deliberately simple (no leetspeak/homoglyph handling) — extend PROFANE_ROOTS
// below if you need broader coverage.
const PROFANE_ROOTS = [
// Russian
'хуй', 'хуе', 'хуё', 'хуя', 'хует',
'пизд',
'бля',
'еб', 'ёб',
'муда', 'мудак', 'мудило',
'пидор', 'пидар', 'пидр',
'гондон', 'гандон',
'долбоеб', 'долбоёб',
'сука', 'суки', 'суке', 'суку', 'суками',
// English
'fuck', 'shit', 'bitch', 'cunt', 'dick', 'asshole', 'bastard',
'whore', 'slut', 'nigger', 'nigga', 'faggot', 'motherfuck',
];
const WORD_RE = /[а-яёА-ЯЁa-zA-Z]+/g;
function isProfaneWord(word) {
const normalized = word.toLowerCase();
return PROFANE_ROOTS.some((root) => normalized.startsWith(root));
}
function censorText(text, replacement) {
return text.replace(WORD_RE, (word) => (isProfaneWord(word) ? replacement : word));
}
module.exports = { censorText };