UNPKG

@sideid/id-profanity-filter

Version:

Library filter kata kotor dalam Bahasa Indonesia

568 lines (427 loc) 17.6 kB
<div align="center"> <img alt="SideID - Profanity Filter" src="https://socialify.git.ci/SideeID/id-profanity-filter/image?custom_description=Library+JavaScript%2FTypeScript+untuk+mendeteksi%2C+menyensor%2C+dan+menganalisis+kata-kata+kotor+dalam+Indonesia+dan+daerah.&description=1&font=Inter&forks=1&language=1&name=1&owner=1&pattern=Circuit+Board&stargazers=1&theme=Auto"> </div> --- <div align="center"> <a href="https://www.npmjs.com/package/@sideid/id-profanity-filter"> <img src="https://img.shields.io/npm/v/@sideid/id-profanity-filter.svg" alt="NPM Version"> </a> <a href="https://www.npmjs.com/package/@sideid/id-profanity-filter"> <img src="https://img.shields.io/npm/dt/@sideid/id-profanity-filter?label=npm&color=%23CB3837" alt="NPM Downloads"> </a> <a href="https://github.com/SideeID/id-profanity-filter"> <img src="https://img.shields.io/github/languages/code-size/SideeID/id-profanity-filter" alt="GitHub Code Size"> </a> <a href="https://github.com/SideeID/id-profanity-filter"> <img src="https://img.shields.io/github/license/SideeID/id-profanity-filter" alt="GitHub License"> </a> <a href="https://github.com/SideeID/id-profanity-filter"> <img src="https://img.shields.io/github/stars/SideeID/id-profanity-filter" alt="GitHub Stars"> </a> <a href="https://github.com/SideeID/id-profanity-filter"> <img src="https://img.shields.io/github/forks/SideeID/id-profanity-filter" alt="GitHub Forks"> </a> </div> ## Fitur Utama - 🔍 **Deteksi Kata Kotor** - Mendeteksi kata-kata kasar/kotor dalam teks Bahasa Indonesia - ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor - 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi - 🗺️ **Dukungan Bahasa Daerah** - Mencakup kata-kata dari berbagai daerah di Indonesia (Jawa, Sunda, Batak, dll) - 🧠 **Deteksi Cerdas** - Mendeteksi variasi ejaan, kata terpisah, dan kesamaan kata - 🔠 **Deteksi Levenshtein** - Mendeteksi kata kotor yang dimodifikasi dengan typo atau sengaja disamarkan - 🛡️ **Preset** - Preset filter siap pakai untuk berbagai kebutuhan - 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom ## Instalasi ```bash npm install @sideid/id-profanity-filter # atau yarn add @sideid/id-profanity-filter # atau pnpm add @sideid/id-profanity-filter ``` ## Penggunaan Dasar ### JavaScript / TypeScript ```typescript import IDProfanityFilter from '@sideid/id-profanity-filter'; // Buat instance filter const filter = new IDProfanityFilter(); // Cek apakah teks mengandung kata kotor const teks = 'Dasar anjing kamu, jangan banyak bacot!'; const hasProfanity = filter.isProfane(teks); console.log(hasProfanity); // Output: true // Filter kata kotor (sensorisasi) const hasil = filter.filter(teks); console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!" console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor) // Analisis konten const analisis = filter.analyze(teks); console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan) console.log(analisis.categories); // Output: ["profanity", "insult"] ``` ### Menggunakan Preset ```typescript import IDProfanityFilter from '@sideid/id-profanity-filter'; // Buat instance filter dengan preset const filter = new IDProfanityFilter(); filter.usePreset('strict'); // Atau dengan opsi tambahan filter.usePreset('childSafe', { replaceWith: '#', useRandomGrawlix: true, }); const teks = 'Dasar anjing kamu, jangan banyak bacot!'; const hasil = filter.filter(teks); console.log(hasil.filtered); // Output: "Dasar #@$%& kamu, jangan banyak $!@#%!" ``` ### Utilitas Langsung Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance: ```typescript import { idFilter } from '@sideid/id-profanity-filter'; const teks = 'Dasar anjing kamu, jangan banyak bacot!'; const hasil = idFilter.filter(teks); console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!" // Menggunakan preset dengan API fungsi statis const presetResult = idFilter.filter( teks, idFilter.getPresetOptions('moderate'), ); ``` ## Dokumentasi API ### Kelas `IDProfanityFilter` #### Konstruktor ```typescript constructor(options?: FilterOptions) ``` - **options**: Opsi konfigurasi filter (opsional) #### Metode ##### `filter(text: string): FilterResult` Menyensor kata kotor dalam teks. - **Hasil**: Objek `FilterResult` dengan properti: - `filtered`: String teks yang sudah disensor - `censored`: Jumlah kata yang disensor - `replacements`: Array berisi detail kata yang disensor ##### `isProfane(text: string): boolean` Memeriksa apakah teks mengandung kata kotor. - **Hasil**: Boolean `true` jika teks mengandung kata kotor, `false` jika tidak ##### `analyze(text: string): AnalysisResult` Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang ditemukan. - **Hasil**: Objek `AnalysisResult` dengan properti: - `hasProfanity`: Apakah teks mengandung kata kotor - `matches`: Array kata kotor yang ditemukan - `matchDetails`: Array objek kata kotor dengan metadata - `categories`: Kategori kata kotor yang ditemukan - `regions`: Daerah asal kata kotor yang ditemukan - `severityScore`: Skor keparahan (0-1) - `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan) ##### `batchAnalyze(texts: string[])` Menganalisis batch teks sekaligus dan memberikan ringkasan. - **Hasil**: Objek yang berisi ringkasan analisis ##### `analyzeBySentence(text: string)` Menganalisis teks per-kalimat. - **Hasil**: Array dari hasil analisis per-kalimat ##### `analyzeWithContext(text: string, contextWindowSize?: number)` Menganalisis teks dengan konteks di sekitar kata kotor. - **Hasil**: Array dari kata kotor dengan konteks di sekitarnya ##### `usePreset(presetName: string, additionalOptions?: Partial<FilterOptions>)` Menggunakan preset filter yang telah ditentukan. - **presetName**: Nama preset ('strict', 'moderate', 'light', 'childSafe', dll) - **additionalOptions**: Opsi tambahan untuk override preset (opsional) ##### `setOptions(options: Partial<FilterOptions>)` Mengubah opsi filter. ##### `setWordList(wordList: string[])` Menetapkan daftar kata kustom. ##### `addToWhitelist(word: string)` Menambahkan kata ke whitelist (akan diabaikan dalam filter). ##### `removeFromWhitelist(word: string)` Menghapus kata dari whitelist. ##### `enableIndonesianVariations()` Mengaktifkan deteksi variasi ejaan Bahasa Indonesia. ##### `enableSplitWordDetection()` Mengaktifkan deteksi kata yang dipisah. ##### `enableSimilarityDetection(threshold: number = 0.8, useLevenshtein: boolean = false, maxLevenshteinDistance: number = 2)` Mengaktifkan deteksi berdasarkan kesamaan kata. - **threshold**: Ambang batas kesamaan (0-1, default: 0.8) - **useLevenshtein**: Gunakan algoritma Levenshtein untuk deteksi (default: false) - **maxLevenshteinDistance**: Jarak edit maksimum yang diizinkan (default: 2) ##### `enableLevenshteinDetection(threshold: number = 0.8, maxDistance: number = 2)` Mengaktifkan deteksi berbasis jarak Levenshtein. - **threshold**: Ambang batas kesamaan (0-1, default: 0.8) - **maxDistance**: Jarak edit maksimum yang diizinkan (default: 2) ### Opsi Filter ```typescript interface FilterOptions { // Opsi dasar wordList?: string[]; // List kata yang ingin difilter replaceWith?: string; // Karakter pengganti untuk kata yang disensor fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian detectLeetSpeak?: boolean; // Deteksi variasi penulisan (mis: a=4, e=3) whitelist?: string[]; // Kata-kata yang dikecualikan dari filter checkSubstring?: boolean; // Memeriksa substring (lebih ketat) categories?: ProfanityCategory[]; // Kategori kata yang difilter regions?: Region[]; // Daerah asal kata yang difilter severityThreshold?: number; // Tingkat keparahan minimum (0-1) // Opsi lanjutan useRandomGrawlix?: boolean; // Gunakan karakter acak untuk sensor (#@$%&!) keepFirstAndLast?: boolean; // Simpan huruf pertama dan terakhir (a***g) indonesianVariation?: boolean; // Deteksi variasi ejaan Bahasa Indonesia detectSimilarity?: boolean; // Deteksi kata berdasarkan kesamaan similarityThreshold?: number; // Ambang batas kesamaan (0-1) detectSplit?: boolean; // Deteksi kata yang dipisah (a-n-j-i-n-g) useLevenshtein?: boolean; // Gunakan algoritma Levenshtein untuk deteksi kesamaan maxLevenshteinDistance?: number; // Jarak edit maksimum untuk deteksi Levenshtein } ``` ## Preset Filter Library ini menyediakan beberapa preset yang dapat digunakan: ### Preset Filter - **strict**: Filter paling ketat, mendeteksi semua jenis kata kotor - **moderate**: Filter tingkat menengah, mengabaikan kata-kata dengan tingkat keparahan rendah - **light**: Filter ringan, hanya untuk kata-kata paling sensitif - **childSafe**: Filter untuk konten anak-anak, sangat ketat ### Preset Kategori - **sexual**: Hanya memfilter kata-kata berbau seksual - **insults**: Hanya memfilter kata-kata penghinaan - **profanity**: Hanya memfilter umpatan umum ### Preset Regional - **general**: Hanya memfilter kata-kata umum di Indonesia - **jawa**: Hanya memfilter kata-kata dari Jawa - **sunda**: Hanya memfilter kata-kata dari Sunda - **betawi**: Hanya memfilter kata-kata dari Betawi - **batak**: Hanya memfilter kata-kata dari Batak ## Contoh Penggunaan Lanjutan ### Kustomisasi Opsi Filter ```typescript const filter = new IDProfanityFilter({ replaceWith: '#', // Menggunakan # sebagai karakter pengganti fullWordCensor: false, // Hanya menyensor sebagian kata detectLeetSpeak: true, // Mendeteksi variasi seperti "b4b1" untuk "babi" categories: ['sexual', 'slur'], // Hanya filter kategori tertentu regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7 // Opsi lanjutan useRandomGrawlix: true, // Gunakan #@$%&! sebagai karakter pengganti keepFirstAndLast: true, // Simpan huruf pertama dan terakhir (a***g) indonesianVariation: true, // Deteksi variasi ejaan Indonesia detectSimilarity: true, // Deteksi kata yang mirip similarityThreshold: 0.8, // Ambang batas kesamaan detectSplit: true, // Deteksi kata yang dipisah useLevenshtein: true, // Gunakan algoritma Levenshtein maxLevenshteinDistance: 2, // Jarak Levenshtein maksimum }); ``` ### Menggunakan Whitelist ```typescript const filter = new IDProfanityFilter(); // Menambahkan kata ke whitelist (akan diabaikan) filter.addToWhitelist('anjing'); const teks = 'Anjing itu hewan peliharaan yang setia, tidak seperti bajingan itu'; const hasil = filter.filter(teks); console.log(hasil.filtered); // Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu" ``` ### Deteksi Variasi Ejaan dan Kata Terpisah ```typescript // Aktifkan deteksi variasi ejaan dan kata terpisah const filter = new IDProfanityFilter({ indonesianVariation: true, detectSplit: true, detectLeetSpeak: true, }); // Uji dengan variasi ejaan const teks1 = 'Dasar kamu ini sangat bodoh, benar-benar b0d0h dan b-o-d-o-h!'; const hasil1 = filter.filter(teks1); console.log(hasil1.filtered); // Output: "Dasar kamu ini sangat *****, benar-benar ***** dan *********!" // Uji dengan ejaan Indonesia yang berbeda const teks2 = 'Dia sangat djail dan djudes dengan temannya'; const hasil2 = filter.filter(teks2); console.log(hasil2.filtered); // Output: "Dia sangat ***** dan ****** dengan temannya" ``` ### Deteksi Berdasarkan Kesamaan (Similarity Detection) ```typescript // Aktifkan deteksi kesamaan standar const filter = new IDProfanityFilter(); filter.enableSimilarityDetection(0.75); // Set threshold kesamaan ke 0.75 const teks = 'Dia benar-benar anjiing dan gooblok!'; const analisis = filter.analyze(teks); console.log(analisis.similarWords); /* Output: [ { word: "anjiing", original: "anjing", similarity: 0.83 }, { word: "gooblok", original: "goblok", similarity: 0.85 } ] */ const hasil = filter.filter(teks); console.log(hasil.filtered); // Output: "Dia benar-benar ****** dan *******!" ``` ### Deteksi dengan Algoritma Levenshtein Distance ```typescript // Aktifkan deteksi menggunakan algoritma Levenshtein Distance const filter = new IDProfanityFilter(); filter.enableLevenshteinDetection(0.85, 2); // Threshold 0.85, maksimal 2 karakter berbeda const teks = 'Dia benar-benar konntol dan anjiing sekali!'; const hasil = filter.filter(teks); console.log(hasil.filtered); // Output: "Dia benar-benar ******* dan ****** sekali!" // Atau menggunakan opsi langsung: const filterCustom = new IDProfanityFilter({ detectSimilarity: true, useLevenshtein: true, similarityThreshold: 0.85, maxLevenshteinDistance: 2, }); // Mendeteksi typo atau variasi disengaja const teksVariasi = 'kontool kamu kwontol anjiing'; console.log(filterCustom.filter(teksVariasi).filtered); // Output: "******* kamu ******* ******" ``` ### Variasi Sensor Kata ```typescript // Sensor standar (asterisk) const filter1 = new IDProfanityFilter(); console.log(filter1.filter('Dasar anjing kamu!').filtered); // Output: "Dasar ***** kamu!" // Sensor dengan grawlix random const filter2 = new IDProfanityFilter({ useRandomGrawlix: true }); console.log(filter2.filter('Dasar anjing kamu!').filtered); // Output: "Dasar #@$%& kamu!" // Sensor dengan menyimpan huruf pertama dan terakhir const filter3 = new IDProfanityFilter({ fullWordCensor: false, keepFirstAndLast: true, }); console.log(filter3.filter('Dasar anjing kamu!').filtered); // Output: "Dasar a***g kamu!" ``` ### Analisis Konten Mendalam ```typescript const filter = new IDProfanityFilter(); const teks = 'Dasar anjing sialan! Kamu ini memang bego dan goblok.'; // Analisis teks const analisis = filter.analyze(teks); console.log(analisis); /* Output: { hasProfanity: true, matches: ['anjing', 'sialan', 'bego', 'goblok'], matchDetails: [ { word: 'anjing', category: 'profanity', region: 'general', severity: 0.7, ... }, { word: 'bego', category: 'insult', region: 'general', severity: 0.5, ... }, ... ], categories: ['profanity', 'insult'], regions: ['general'], severityScore: 0.64 } */ ``` ### Analisis Konteks ```typescript const filter = new IDProfanityFilter(); const teks = 'Saya sangat marah dengan sikapnya, dia benar-benar anjing dan bajingan!'; // Analisis konteks const konteks = filter.analyzeWithContext(teks, 3); console.log(konteks); /* Output: [ { word: "anjing", context: "benar-benar anjing dan bajingan", position: { start: 43, end: 62 } }, { word: "bajingan", context: "anjing dan bajingan!", position: { start: 54, end: 63 } } ] */ ``` ### Analisis Per-Kalimat ```typescript const filter = new IDProfanityFilter(); const teks = 'Filmnya bagus sekali. Tetapi pemainnya seperti anjing, sangat buruk aktingnya.'; // Analisis per-kalimat const kalimat = filter.analyzeBySentence(teks); console.log( kalimat.map( (k) => k.sentence + (k.hasProfanity ? ' (Mengandung kata kotor)' : ' (Bersih)'), ), ); /* Output: [ "Filmnya bagus sekali. (Bersih)", "Tetapi pemainnya seperti anjing, sangat buruk aktingnya. (Mengandung kata kotor)" ] */ ``` ### Analisis Batch ```typescript const filter = new IDProfanityFilter(); const komentar = [ 'Film ini sangat bagus, ceritanya menarik sekali!', 'Dasar goblok, sialan kamu!', 'Anjing emang filmnya, sampah banget.', ]; const hasil = filter.batchAnalyze(komentar); console.log(hasil); /* Output: { totalTexts: 3, profaneTexts: 2, cleanTexts: 1, averageSeverity: 0.62, topCategories: ['profanity', 'insult'], topRegions: ['general'], mostFrequentWords: [ { word: 'anjing', count: 1 }, { word: 'goblok', count: 1 }, { word: 'sialan', count: 1 }, { word: 'sampah', count: 1 } ] } */ ``` ## Dukungan Regional Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia: - 🇮🇩 **General** - Kata-kata yang umum di seluruh Indonesia - 🏝️ **Jawa** - Kata-kata dari bahasa Jawa - 🏞️ **Sunda** - Kata-kata dari bahasa Sunda - 🏙️ **Betawi** - Kata-kata dari bahasa Betawi - 🌋 **Batak** - Kata-kata dari bahasa Batak ## Kategori Kata Kata-kata dikelompokkan berdasarkan kategori: - `sexual`: Kata-kata berbau seksual - `insult`: Kata-kata penghinaan - `profanity`: Umpatan umum - `slur`: Perkataan merendahkan berdasarkan identitas - `drugs`: Terkait narkoba - `disgusting`: Kata-kata menjijikkan - `blasphemy`: Penistaan agama ## Berkontribusi Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md). ### Menambahkan Kata Baru Jika Anda ingin menambahkan kata baru ke database, silakan buat pull request dengan mengubah file yang sesuai di `src/constants/categories/` atau `src/constants/regions/`. Format untuk menambahkan kata baru: ```json { "word": "kata_kotor", // Kata yang akan difilter "category": "insult", // Kategori kata "region": "general", // Daerah asal kata "severity": 0.7, // Tingkat keparahan (0-1) "aliases": ["k4t4_kotor", "kata_k0t0r"], // Alias atau variasi umum "description": "Deskripsi tentang kata", // Penjelasan tentang kata (opsional) "context": "Konteks penggunaan kata" // Konteks penggunaan (opsional) } ``` ## Lisensi Proyek ini dilisensikan di bawah [MIT License](LICENSE). ## Kontak & Dukungan Jika Anda memiliki pertanyaan atau saran, silakan buka issue di repositori GitHub kami.