@sideid/id-profanity-filter 1.9.5 → 1.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -9
- package/dist/constants/categories/index.d.ts +9 -0
- package/dist/constants/regions/index.d.ts +8 -0
- package/examples/advanced.ts +120 -0
- package/examples/basic.ts +60 -41
- package/examples/custom-list.ts +140 -0
- package/package.json +1 -1
- package/src/constants/categories/index.ts +22 -22
- package/src/constants/regions/index.ts +46 -46
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Library JavaScript/TypeScript untuk mendeteksi, menyensor, dan menganalisis kata
|
|
|
12
12
|
- ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor
|
|
13
13
|
- 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi
|
|
14
14
|
- 🗺️ **Dukungan Bahasa Daerah** - Mencakup kata-kata dari berbagai daerah di Indonesia (Jawa, Sunda, Batak, dll)
|
|
15
|
+
- 🧠 **Deteksi Cerdas** - Mendeteksi variasi ejaan, kata terpisah, dan kesamaan kata
|
|
16
|
+
- 🛡️ **Preset** - Preset filter siap pakai untuk berbagai kebutuhan
|
|
15
17
|
- 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom
|
|
16
18
|
|
|
17
19
|
## Instalasi
|
|
@@ -42,7 +44,7 @@ console.log(hasProfanity); // Output: true
|
|
|
42
44
|
|
|
43
45
|
// Filter kata kotor (sensorisasi)
|
|
44
46
|
const hasil = filter.filter(teks);
|
|
45
|
-
console.log(hasil.filtered); // Output: "Dasar
|
|
47
|
+
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
46
48
|
console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor)
|
|
47
49
|
|
|
48
50
|
// Analisis konten
|
|
@@ -51,6 +53,26 @@ console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan)
|
|
|
51
53
|
console.log(analisis.categories); // Output: ["profanity", "insult"]
|
|
52
54
|
```
|
|
53
55
|
|
|
56
|
+
### Menggunakan Preset
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import IDProfanityFilter from '@sideid/id-profanity-filter';
|
|
60
|
+
|
|
61
|
+
// Buat instance filter dengan preset
|
|
62
|
+
const filter = new IDProfanityFilter();
|
|
63
|
+
filter.usePreset('strict');
|
|
64
|
+
|
|
65
|
+
// Atau dengan opsi tambahan
|
|
66
|
+
filter.usePreset('childSafe', {
|
|
67
|
+
replaceWith: '#',
|
|
68
|
+
useRandomGrawlix: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
72
|
+
const hasil = filter.filter(teks);
|
|
73
|
+
console.log(hasil.filtered); // Output: "Dasar #@$%& kamu, jangan banyak $!@#%!"
|
|
74
|
+
```
|
|
75
|
+
|
|
54
76
|
### Utilitas Langsung
|
|
55
77
|
|
|
56
78
|
Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance:
|
|
@@ -60,7 +82,13 @@ import { idFilter } from '@sideid/id-profanity-filter';
|
|
|
60
82
|
|
|
61
83
|
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
62
84
|
const hasil = idFilter.filter(teks);
|
|
63
|
-
console.log(hasil.filtered); // Output: "Dasar
|
|
85
|
+
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
86
|
+
|
|
87
|
+
// Menggunakan preset dengan API fungsi statis
|
|
88
|
+
const presetResult = idFilter.filter(
|
|
89
|
+
teks,
|
|
90
|
+
idFilter.getPresetOptions('moderate'),
|
|
91
|
+
);
|
|
64
92
|
```
|
|
65
93
|
|
|
66
94
|
## Dokumentasi API
|
|
@@ -103,6 +131,7 @@ Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang dit
|
|
|
103
131
|
- `categories`: Kategori kata kotor yang ditemukan
|
|
104
132
|
- `regions`: Daerah asal kata kotor yang ditemukan
|
|
105
133
|
- `severityScore`: Skor keparahan (0-1)
|
|
134
|
+
- `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan)
|
|
106
135
|
|
|
107
136
|
##### `batchAnalyze(texts: string[])`
|
|
108
137
|
|
|
@@ -122,6 +151,13 @@ Menganalisis teks dengan konteks di sekitar kata kotor.
|
|
|
122
151
|
|
|
123
152
|
- **Hasil**: Array dari kata kotor dengan konteks di sekitarnya
|
|
124
153
|
|
|
154
|
+
##### `usePreset(presetName: string, additionalOptions?: Partial<FilterOptions>)`
|
|
155
|
+
|
|
156
|
+
Menggunakan preset filter yang telah ditentukan.
|
|
157
|
+
|
|
158
|
+
- **presetName**: Nama preset ('strict', 'moderate', 'light', 'childSafe', dll)
|
|
159
|
+
- **additionalOptions**: Opsi tambahan untuk override preset (opsional)
|
|
160
|
+
|
|
125
161
|
##### `setOptions(options: Partial<FilterOptions>)`
|
|
126
162
|
|
|
127
163
|
Mengubah opsi filter.
|
|
@@ -138,10 +174,25 @@ Menambahkan kata ke whitelist (akan diabaikan dalam filter).
|
|
|
138
174
|
|
|
139
175
|
Menghapus kata dari whitelist.
|
|
140
176
|
|
|
177
|
+
##### `enableIndonesianVariations()`
|
|
178
|
+
|
|
179
|
+
Mengaktifkan deteksi variasi ejaan Bahasa Indonesia.
|
|
180
|
+
|
|
181
|
+
##### `enableSplitWordDetection()`
|
|
182
|
+
|
|
183
|
+
Mengaktifkan deteksi kata yang dipisah.
|
|
184
|
+
|
|
185
|
+
##### `enableSimilarityDetection(threshold: number = 0.8)`
|
|
186
|
+
|
|
187
|
+
Mengaktifkan deteksi berdasarkan kesamaan kata.
|
|
188
|
+
|
|
189
|
+
- **threshold**: Ambang batas kesamaan (0-1, default: 0.8)
|
|
190
|
+
|
|
141
191
|
### Opsi Filter
|
|
142
192
|
|
|
143
193
|
```typescript
|
|
144
194
|
interface FilterOptions {
|
|
195
|
+
// Opsi dasar
|
|
145
196
|
wordList?: string[]; // List kata yang ingin difilter
|
|
146
197
|
replaceWith?: string; // Karakter pengganti untuk kata yang disensor
|
|
147
198
|
fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian
|
|
@@ -151,9 +202,42 @@ interface FilterOptions {
|
|
|
151
202
|
categories?: ProfanityCategory[]; // Kategori kata yang difilter
|
|
152
203
|
regions?: Region[]; // Daerah asal kata yang difilter
|
|
153
204
|
severityThreshold?: number; // Tingkat keparahan minimum (0-1)
|
|
205
|
+
|
|
206
|
+
// Opsi lanjutan
|
|
207
|
+
useRandomGrawlix?: boolean; // Gunakan karakter acak untuk sensor (#@$%&!)
|
|
208
|
+
keepFirstAndLast?: boolean; // Simpan huruf pertama dan terakhir (a***g)
|
|
209
|
+
indonesianVariation?: boolean; // Deteksi variasi ejaan Bahasa Indonesia
|
|
210
|
+
detectSimilarity?: boolean; // Deteksi kata berdasarkan kesamaan
|
|
211
|
+
similarityThreshold?: number; // Ambang batas kesamaan (0-1)
|
|
212
|
+
detectSplit?: boolean; // Deteksi kata yang dipisah (a-n-j-i-n-g)
|
|
154
213
|
}
|
|
155
214
|
```
|
|
156
215
|
|
|
216
|
+
## Preset Filter
|
|
217
|
+
|
|
218
|
+
Library ini menyediakan beberapa preset yang dapat digunakan:
|
|
219
|
+
|
|
220
|
+
### Preset Filter
|
|
221
|
+
|
|
222
|
+
- **strict**: Filter paling ketat, mendeteksi semua jenis kata kotor
|
|
223
|
+
- **moderate**: Filter tingkat menengah, mengabaikan kata-kata dengan tingkat keparahan rendah
|
|
224
|
+
- **light**: Filter ringan, hanya untuk kata-kata paling sensitif
|
|
225
|
+
- **childSafe**: Filter untuk konten anak-anak, sangat ketat
|
|
226
|
+
|
|
227
|
+
### Preset Kategori
|
|
228
|
+
|
|
229
|
+
- **sexual**: Hanya memfilter kata-kata berbau seksual
|
|
230
|
+
- **insults**: Hanya memfilter kata-kata penghinaan
|
|
231
|
+
- **profanity**: Hanya memfilter umpatan umum
|
|
232
|
+
|
|
233
|
+
### Preset Regional
|
|
234
|
+
|
|
235
|
+
- **general**: Hanya memfilter kata-kata umum di Indonesia
|
|
236
|
+
- **jawa**: Hanya memfilter kata-kata dari Jawa
|
|
237
|
+
- **sunda**: Hanya memfilter kata-kata dari Sunda
|
|
238
|
+
- **betawi**: Hanya memfilter kata-kata dari Betawi
|
|
239
|
+
- **batak**: Hanya memfilter kata-kata dari Batak
|
|
240
|
+
|
|
157
241
|
## Contoh Penggunaan Lanjutan
|
|
158
242
|
|
|
159
243
|
### Kustomisasi Opsi Filter
|
|
@@ -166,12 +250,14 @@ const filter = new IDProfanityFilter({
|
|
|
166
250
|
categories: ['sexual', 'slur'], // Hanya filter kategori tertentu
|
|
167
251
|
regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu
|
|
168
252
|
severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7
|
|
169
|
-
});
|
|
170
253
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
254
|
+
// Opsi lanjutan
|
|
255
|
+
useRandomGrawlix: true, // Gunakan #@$%&! sebagai karakter pengganti
|
|
256
|
+
keepFirstAndLast: true, // Simpan huruf pertama dan terakhir (a***g)
|
|
257
|
+
indonesianVariation: true, // Deteksi variasi ejaan Indonesia
|
|
258
|
+
detectSimilarity: true, // Deteksi kata yang mirip
|
|
259
|
+
similarityThreshold: 0.8, // Ambang batas kesamaan
|
|
260
|
+
detectSplit: true, // Deteksi kata yang dipisah
|
|
175
261
|
});
|
|
176
262
|
```
|
|
177
263
|
|
|
@@ -191,6 +277,74 @@ console.log(hasil.filtered);
|
|
|
191
277
|
// Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu"
|
|
192
278
|
```
|
|
193
279
|
|
|
280
|
+
### Deteksi Variasi Ejaan dan Kata Terpisah
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// Aktifkan deteksi variasi ejaan dan kata terpisah
|
|
284
|
+
const filter = new IDProfanityFilter({
|
|
285
|
+
indonesianVariation: true,
|
|
286
|
+
detectSplit: true,
|
|
287
|
+
detectLeetSpeak: true,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Uji dengan variasi ejaan
|
|
291
|
+
const teks1 = 'Dasar kamu ini sangat bodoh, benar-benar b0d0h dan b-o-d-o-h!';
|
|
292
|
+
const hasil1 = filter.filter(teks1);
|
|
293
|
+
console.log(hasil1.filtered);
|
|
294
|
+
// Output: "Dasar kamu ini sangat *****, benar-benar ***** dan *********!"
|
|
295
|
+
|
|
296
|
+
// Uji dengan ejaan Indonesia yang berbeda
|
|
297
|
+
const teks2 = 'Dia sangat djail dan djudes dengan temannya';
|
|
298
|
+
const hasil2 = filter.filter(teks2);
|
|
299
|
+
console.log(hasil2.filtered);
|
|
300
|
+
// Output: "Dia sangat ***** dan ****** dengan temannya"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Deteksi Berdasarkan Kesamaan
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
// Aktifkan deteksi kesamaan
|
|
307
|
+
const filter = new IDProfanityFilter();
|
|
308
|
+
filter.enableSimilarityDetection(0.75); // Set threshold kesamaan ke 0.75
|
|
309
|
+
|
|
310
|
+
const teks = 'Dia benar-benar anjiing dan gooblok!';
|
|
311
|
+
const analisis = filter.analyze(teks);
|
|
312
|
+
|
|
313
|
+
console.log(analisis.similarWords);
|
|
314
|
+
/* Output:
|
|
315
|
+
[
|
|
316
|
+
{ word: "anjiing", original: "anjing", similarity: 0.83 },
|
|
317
|
+
{ word: "gooblok", original: "goblok", similarity: 0.85 }
|
|
318
|
+
]
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
const hasil = filter.filter(teks);
|
|
322
|
+
console.log(hasil.filtered);
|
|
323
|
+
// Output: "Dia benar-benar ****** dan *******!"
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Variasi Sensor Kata
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// Sensor standar (asterisk)
|
|
330
|
+
const filter1 = new IDProfanityFilter();
|
|
331
|
+
console.log(filter1.filter('Dasar anjing kamu!').filtered);
|
|
332
|
+
// Output: "Dasar ***** kamu!"
|
|
333
|
+
|
|
334
|
+
// Sensor dengan grawlix random
|
|
335
|
+
const filter2 = new IDProfanityFilter({ useRandomGrawlix: true });
|
|
336
|
+
console.log(filter2.filter('Dasar anjing kamu!').filtered);
|
|
337
|
+
// Output: "Dasar #@$%& kamu!"
|
|
338
|
+
|
|
339
|
+
// Sensor dengan menyimpan huruf pertama dan terakhir
|
|
340
|
+
const filter3 = new IDProfanityFilter({
|
|
341
|
+
fullWordCensor: false,
|
|
342
|
+
keepFirstAndLast: true,
|
|
343
|
+
});
|
|
344
|
+
console.log(filter3.filter('Dasar anjing kamu!').filtered);
|
|
345
|
+
// Output: "Dasar a***g kamu!"
|
|
346
|
+
```
|
|
347
|
+
|
|
194
348
|
### Analisis Konten Mendalam
|
|
195
349
|
|
|
196
350
|
```typescript
|
|
@@ -217,6 +371,57 @@ console.log(analisis);
|
|
|
217
371
|
*/
|
|
218
372
|
```
|
|
219
373
|
|
|
374
|
+
### Analisis Konteks
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
const filter = new IDProfanityFilter();
|
|
378
|
+
const teks =
|
|
379
|
+
'Saya sangat marah dengan sikapnya, dia benar-benar anjing dan bajingan!';
|
|
380
|
+
|
|
381
|
+
// Analisis konteks
|
|
382
|
+
const konteks = filter.analyzeWithContext(teks, 3);
|
|
383
|
+
console.log(konteks);
|
|
384
|
+
|
|
385
|
+
/* Output:
|
|
386
|
+
[
|
|
387
|
+
{
|
|
388
|
+
word: "anjing",
|
|
389
|
+
context: "benar-benar anjing dan bajingan",
|
|
390
|
+
position: { start: 43, end: 62 }
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
word: "bajingan",
|
|
394
|
+
context: "anjing dan bajingan!",
|
|
395
|
+
position: { start: 54, end: 63 }
|
|
396
|
+
}
|
|
397
|
+
]
|
|
398
|
+
*/
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Analisis Per-Kalimat
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
const filter = new IDProfanityFilter();
|
|
405
|
+
const teks =
|
|
406
|
+
'Filmnya bagus sekali. Tetapi pemainnya seperti anjing, sangat buruk aktingnya.';
|
|
407
|
+
|
|
408
|
+
// Analisis per-kalimat
|
|
409
|
+
const kalimat = filter.analyzeBySentence(teks);
|
|
410
|
+
console.log(
|
|
411
|
+
kalimat.map(
|
|
412
|
+
(k) =>
|
|
413
|
+
k.sentence + (k.hasProfanity ? ' (Mengandung kata kotor)' : ' (Bersih)'),
|
|
414
|
+
),
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
/* Output:
|
|
418
|
+
[
|
|
419
|
+
"Filmnya bagus sekali. (Bersih)",
|
|
420
|
+
"Tetapi pemainnya seperti anjing, sangat buruk aktingnya. (Mengandung kata kotor)"
|
|
421
|
+
]
|
|
422
|
+
*/
|
|
423
|
+
```
|
|
424
|
+
|
|
220
425
|
### Analisis Batch
|
|
221
426
|
|
|
222
427
|
```typescript
|
|
@@ -258,8 +463,6 @@ Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia:
|
|
|
258
463
|
- 🏙️ **Betawi** - Kata-kata dari bahasa Betawi
|
|
259
464
|
- 🌋 **Batak** - Kata-kata dari bahasa Batak
|
|
260
465
|
|
|
261
|
-
Dan daerah lainnya yang terus bertambah.
|
|
262
|
-
|
|
263
466
|
## Kategori Kata
|
|
264
467
|
|
|
265
468
|
Kata-kata dikelompokkan berdasarkan kategori:
|
|
@@ -276,6 +479,24 @@ Kata-kata dikelompokkan berdasarkan kategori:
|
|
|
276
479
|
|
|
277
480
|
Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md).
|
|
278
481
|
|
|
482
|
+
### Menambahkan Kata Baru
|
|
483
|
+
|
|
484
|
+
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/`.
|
|
485
|
+
|
|
486
|
+
Format untuk menambahkan kata baru:
|
|
487
|
+
|
|
488
|
+
```json
|
|
489
|
+
{
|
|
490
|
+
"word": "kata_kotor", // Kata yang akan difilter
|
|
491
|
+
"category": "insult", // Kategori kata
|
|
492
|
+
"region": "general", // Daerah asal kata
|
|
493
|
+
"severity": 0.7, // Tingkat keparahan (0-1)
|
|
494
|
+
"aliases": ["k4t4_kotor", "kata_k0t0r"], // Alias atau variasi umum
|
|
495
|
+
"description": "Deskripsi tentang kata", // Penjelasan tentang kata (opsional)
|
|
496
|
+
"context": "Konteks penggunaan kata" // Konteks penggunaan (opsional)
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
279
500
|
## Lisensi
|
|
280
501
|
|
|
281
502
|
Proyek ini dilisensikan di bawah [MIT License](LICENSE).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { sexual } from './sexual';
|
|
2
|
+
import { insult } from './insult';
|
|
3
|
+
export declare const categories: {
|
|
4
|
+
sexual: import("../..").ProfanityWord[];
|
|
5
|
+
insult: import("../..").ProfanityWord[];
|
|
6
|
+
};
|
|
7
|
+
export { sexual, insult };
|
|
8
|
+
export declare const allCategoryWords: import("../..").ProfanityWord[];
|
|
9
|
+
export default allCategoryWords;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { general } from './general';
|
|
2
|
+
import { jawa } from './jawa';
|
|
3
|
+
import { sunda } from './sunda';
|
|
4
|
+
import { betawi } from './betawi';
|
|
5
|
+
import { batak } from './batak';
|
|
6
|
+
export { general, jawa, sunda, betawi, batak, };
|
|
7
|
+
export declare const allRegionWords: import("../..").ProfanityWord[];
|
|
8
|
+
export default allRegionWords;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { IDProfanityFilter, idFilter } from '../src/index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Contoh Penggunaan Lanjutan ID-Profanity-Filter
|
|
5
|
+
* ============================================
|
|
6
|
+
* File ini menunjukkan fitur-fitur lanjutan dari library.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
console.log('=== Contoh Penggunaan Lanjutan ID-Profanity-Filter ===\n');
|
|
10
|
+
|
|
11
|
+
// ===== Contoh 1: Menggunakan preset filter =====
|
|
12
|
+
const filter = new IDProfanityFilter();
|
|
13
|
+
filter.usePreset('strict');
|
|
14
|
+
|
|
15
|
+
console.log('=== Contoh Preset ===\n');
|
|
16
|
+
|
|
17
|
+
const teks1 = 'Saya sangat kesal dengan dia, benar-benar anjing!';
|
|
18
|
+
console.log('Teks asli:', teks1);
|
|
19
|
+
console.log('Preset Strict:', filter.filter(teks1).filtered);
|
|
20
|
+
|
|
21
|
+
// Ganti ke preset childSafe dengan grawlix random
|
|
22
|
+
filter.usePreset('childSafe', { useRandomGrawlix: true });
|
|
23
|
+
console.log('Preset ChildSafe + Grawlix:', filter.filter(teks1).filtered);
|
|
24
|
+
|
|
25
|
+
// Ganti ke preset light (hanya filter kata paling sensitif)
|
|
26
|
+
filter.usePreset('light');
|
|
27
|
+
console.log('Preset Light:', filter.filter(teks1).filtered);
|
|
28
|
+
|
|
29
|
+
// ===== Contoh 2: Deteksi Variasi Penulisan =====
|
|
30
|
+
console.log('\n=== Contoh Deteksi Variasi Penulisan ===\n');
|
|
31
|
+
|
|
32
|
+
filter.setOptions({
|
|
33
|
+
detectLeetSpeak: true,
|
|
34
|
+
indonesianVariation: true,
|
|
35
|
+
detectSplit: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const teks2 =
|
|
39
|
+
'b4b1 adalah binatang yang kotor, sama seperti a-n-j-i-n-g dan d-j-a-r-i-k.';
|
|
40
|
+
console.log('Teks dengan variasi:', teks2);
|
|
41
|
+
console.log('Hasil filter:', filter.filter(teks2).filtered);
|
|
42
|
+
|
|
43
|
+
const leetAnalisis = filter.analyze(teks2);
|
|
44
|
+
console.log('Kata terdeteksi:', leetAnalisis.matches);
|
|
45
|
+
|
|
46
|
+
// ===== Contoh 3: Deteksi Kesamaan Kata =====
|
|
47
|
+
console.log('\n=== Contoh Deteksi Kesamaan Kata ===\n');
|
|
48
|
+
|
|
49
|
+
filter.enableSimilarityDetection(0.8);
|
|
50
|
+
|
|
51
|
+
const teks3 = 'Dia benar-benar anjiing dan gooblok!';
|
|
52
|
+
console.log('Teks dengan typo:', teks3);
|
|
53
|
+
|
|
54
|
+
const similarAnalisis = filter.analyze(teks3);
|
|
55
|
+
console.log('Kata terdeteksi:', similarAnalisis.matches);
|
|
56
|
+
console.log('Analisis kesamaan:', similarAnalisis.similarWords);
|
|
57
|
+
console.log('Hasil filter:', filter.filter(teks3).filtered);
|
|
58
|
+
|
|
59
|
+
// ===== Contoh 4: Analisis dengan Konteks =====
|
|
60
|
+
console.log('\n=== Contoh Analisis dengan Konteks ===\n');
|
|
61
|
+
|
|
62
|
+
const teks4 =
|
|
63
|
+
'Para kritikus film sangat marah dengan kualitas filmnya, mereka menyebut sutradara itu anjing karena mengecewakan penonton dan membuang-buang anggaran.';
|
|
64
|
+
console.log('Teks panjang:', teks4);
|
|
65
|
+
|
|
66
|
+
const konteksAnalisis = filter.analyzeWithContext(teks4, 4);
|
|
67
|
+
console.log('Analisis konteks:');
|
|
68
|
+
konteksAnalisis.forEach((item) => {
|
|
69
|
+
console.log(`- Kata: ${item.word}`);
|
|
70
|
+
console.log(` Konteks: "${item.context}"`);
|
|
71
|
+
console.log(` Posisi: ${item.position.start}-${item.position.end}`);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// ===== Contoh 5: Batch Analisis =====
|
|
75
|
+
console.log('\n=== Contoh Batch Analisis ===\n');
|
|
76
|
+
|
|
77
|
+
const tekstBatch = [
|
|
78
|
+
'Film ini sangat bagus, ceritanya menarik sekali!',
|
|
79
|
+
'Dasar goblok, sialan kamu!',
|
|
80
|
+
'Anjing emang filmnya, sampah banget.',
|
|
81
|
+
'Saya setuju dengan pendapat kritikus tentang film tersebut.',
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
console.log('Batch teks untuk dianalisis:');
|
|
85
|
+
tekstBatch.forEach((t, i) => console.log(`${i + 1}. ${t}`));
|
|
86
|
+
|
|
87
|
+
const batchHasil = filter.batchAnalyze(tekstBatch);
|
|
88
|
+
console.log('\nHasil Batch Analisis:');
|
|
89
|
+
console.log(`- Total teks: ${batchHasil.totalTexts}`);
|
|
90
|
+
console.log(`- Teks dengan kata kotor: ${batchHasil.profaneTexts}`);
|
|
91
|
+
console.log(`- Teks bersih: ${batchHasil.cleanTexts}`);
|
|
92
|
+
console.log(`- Rata-rata keparahan: ${batchHasil.averageSeverity.toFixed(2)}`);
|
|
93
|
+
console.log(`- Kategori terbanyak: ${batchHasil.topCategories.join(', ')}`);
|
|
94
|
+
console.log(`- Daerah terbanyak: ${batchHasil.topRegions.join(', ')}`);
|
|
95
|
+
console.log('- Kata-kata terbanyak:');
|
|
96
|
+
batchHasil.mostFrequentWords.forEach((word) => {
|
|
97
|
+
console.log(` * ${word.word}: ${word.count} kali`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// ===== Contoh 6: Opsi Kustomisasi Lengkap =====
|
|
101
|
+
console.log('\n=== Contoh Kustomisasi Lengkap ===\n');
|
|
102
|
+
|
|
103
|
+
filter.setOptions({
|
|
104
|
+
replaceWith: '@',
|
|
105
|
+
fullWordCensor: false,
|
|
106
|
+
keepFirstAndLast: true,
|
|
107
|
+
detectLeetSpeak: true,
|
|
108
|
+
indonesianVariation: true,
|
|
109
|
+
detectSimilarity: true,
|
|
110
|
+
similarityThreshold: 0.75,
|
|
111
|
+
detectSplit: true,
|
|
112
|
+
useRandomGrawlix: false,
|
|
113
|
+
categories: ['sexual', 'profanity'],
|
|
114
|
+
regions: ['general', 'jawa'],
|
|
115
|
+
severityThreshold: 0.5,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const teks6 = 'Dasar b4b1 sialan, kamu ini memang anjiing ya!';
|
|
119
|
+
console.log('Teks asli:', teks6);
|
|
120
|
+
console.log('Hasil kustomisasi lengkap:', filter.filter(teks6).filtered);
|
package/examples/basic.ts
CHANGED
|
@@ -1,52 +1,71 @@
|
|
|
1
|
+
import { IDProfanityFilter, idFilter } from '../src/index';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* Contoh
|
|
4
|
+
* Contoh Penggunaan Dasar ID-Profanity-Filter
|
|
5
|
+
* ==========================================
|
|
6
|
+
* File ini menunjukkan fungsi dasar dari library.
|
|
3
7
|
*/
|
|
4
|
-
import IDProfanityFilter from '../src/index';
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
console.log('=== Contoh Penggunaan Dasar ID-Profanity-Filter ===\n');
|
|
7
10
|
|
|
8
|
-
// 1
|
|
11
|
+
// ===== Contoh 1: Inisialisasi dasar =====
|
|
9
12
|
const filter = new IDProfanityFilter();
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
const hasProfanity = filter.isProfane(
|
|
16
|
-
console.log('
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
const
|
|
20
|
-
console.log('Teks
|
|
21
|
-
console.log('
|
|
22
|
-
console.log('
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log('
|
|
29
|
-
console.log('-
|
|
30
|
-
console.log('
|
|
31
|
-
console.log('
|
|
32
|
-
console.log('
|
|
33
|
-
|
|
34
|
-
|
|
14
|
+
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
15
|
+
console.log('Teks asli:', teks);
|
|
16
|
+
|
|
17
|
+
// Cek apakah teks mengandung kata kotor
|
|
18
|
+
const hasProfanity = filter.isProfane(teks);
|
|
19
|
+
console.log('Mengandung kata kotor?', hasProfanity);
|
|
20
|
+
|
|
21
|
+
// Filter kata kotor (sensorisasi)
|
|
22
|
+
const hasil = filter.filter(teks);
|
|
23
|
+
console.log('Teks disensor:', hasil.filtered);
|
|
24
|
+
console.log('Jumlah kata disensor:', hasil.censored);
|
|
25
|
+
console.log('Detail penggantian:', hasil.replacements);
|
|
26
|
+
|
|
27
|
+
console.log('\n=== Contoh Analisis Dasar ===\n');
|
|
28
|
+
|
|
29
|
+
// Analisis konten
|
|
30
|
+
const analisis = filter.analyze(teks);
|
|
31
|
+
console.log('Mengandung kata kotor?', analisis.hasProfanity);
|
|
32
|
+
console.log('Kata-kata kotor yang ditemukan:', analisis.matches);
|
|
33
|
+
console.log('Kategori kata kotor:', analisis.categories);
|
|
34
|
+
console.log('Daerah asal kata:', analisis.regions);
|
|
35
|
+
console.log('Tingkat keparahan:', analisis.severityScore.toFixed(2));
|
|
36
|
+
|
|
37
|
+
console.log('\n=== Contoh Fungsi Statis ===\n');
|
|
38
|
+
|
|
39
|
+
// Menggunakan fungsi statis
|
|
40
|
+
const staticResult = idFilter.filter(teks);
|
|
41
|
+
console.log('Teks disensor (fungsi statis):', staticResult.filtered);
|
|
42
|
+
|
|
43
|
+
// ===== Contoh 2: Mengubah karakter pengganti =====
|
|
44
|
+
filter.setOptions({ replaceWith: '#' });
|
|
45
|
+
console.log('\nTeks disensor dengan #:', filter.filter(teks).filtered);
|
|
46
|
+
|
|
47
|
+
// ===== Contoh 3: Hanya menyensor sebagian kata =====
|
|
35
48
|
filter.setOptions({
|
|
36
|
-
replaceWith: '
|
|
49
|
+
replaceWith: '*',
|
|
37
50
|
fullWordCensor: false,
|
|
51
|
+
keepFirstAndLast: true,
|
|
38
52
|
});
|
|
53
|
+
console.log(
|
|
54
|
+
'\nTeks disensor sebagian (first & last):',
|
|
55
|
+
filter.filter(teks).filtered,
|
|
56
|
+
);
|
|
39
57
|
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
// ===== Contoh 4: Metode analisis lain =====
|
|
59
|
+
const kalimat =
|
|
60
|
+
'Saya sangat suka filmnya. Tapi pemainnya seperti anjing, aktingnya buruk.';
|
|
61
|
+
console.log('\nContoh kalimat untuk analisis per-kalimat:', kalimat);
|
|
42
62
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
console.log(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
console.log(idFilter.filter(text, { replaceWith: '@' }).filtered);
|
|
63
|
+
const kalimatAnalisis = filter.analyzeBySentence(kalimat);
|
|
64
|
+
console.log('\nAnalisis per-kalimat:');
|
|
65
|
+
kalimatAnalisis.forEach((hasil, index) => {
|
|
66
|
+
console.log(`Kalimat ${index + 1}: ${hasil.sentence}`);
|
|
67
|
+
console.log(`- Mengandung kata kotor: ${hasil.hasProfanity}`);
|
|
68
|
+
if (hasil.hasProfanity) {
|
|
69
|
+
console.log(`- Kata kotor: ${hasil.matches.join(', ')}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { IDProfanityFilter, idFilter, FilterOptions } from '../src/index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Contoh Penggunaan ID-Profanity-Filter dengan Daftar Kustom
|
|
5
|
+
* =======================================================
|
|
6
|
+
* File ini menunjukkan cara menggunakan library dengan daftar kata kustom.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
console.log('=== Contoh Penggunaan dengan Daftar Kata Kustom ===\n');
|
|
10
|
+
|
|
11
|
+
// ===== Contoh 1: Menggunakan daftar kata kustom =====
|
|
12
|
+
// Daftar kata kotor kustom
|
|
13
|
+
const customBadWords = ['jelek', 'buruk', 'sampah', 'payah', 'lemah', 'amatir'];
|
|
14
|
+
|
|
15
|
+
// Buat instance dengan daftar kata kustom
|
|
16
|
+
const filter = new IDProfanityFilter({
|
|
17
|
+
wordList: customBadWords,
|
|
18
|
+
replaceWith: '#',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const teks1 = 'Film itu sangat jelek dan payah, sepertinya dibuat oleh amatir.';
|
|
22
|
+
console.log('Teks asli:', teks1);
|
|
23
|
+
console.log('Hasil filter kustom:', filter.filter(teks1).filtered);
|
|
24
|
+
|
|
25
|
+
// ===== Contoh 2: Menggabungkan daftar kata kustom dengan daftar bawaan =====
|
|
26
|
+
console.log('\n=== Menggabungkan Daftar Kata ===\n');
|
|
27
|
+
|
|
28
|
+
// Reset filter ke pengaturan default
|
|
29
|
+
filter.setOptions({});
|
|
30
|
+
|
|
31
|
+
// Tambahkan kata-kata kustom tapi tetap deteksi kata-kata bawaan
|
|
32
|
+
const teks2 = 'Film itu sangat jelek dan payah, dibuat oleh anjing amatir.';
|
|
33
|
+
console.log('Teks asli:', teks2);
|
|
34
|
+
|
|
35
|
+
// Analisis hanya dengan kata bawaan
|
|
36
|
+
console.log('Analisis standar:');
|
|
37
|
+
const standarAnalisis = filter.analyze(teks2);
|
|
38
|
+
console.log('- Kata terdeteksi:', standarAnalisis.matches);
|
|
39
|
+
|
|
40
|
+
// Tambahkan kata kustom
|
|
41
|
+
filter.setWordList([...customBadWords]);
|
|
42
|
+
console.log('\nAnalisis dengan kata kustom ditambahkan:');
|
|
43
|
+
const customAnalisis = filter.analyze(teks2);
|
|
44
|
+
console.log('- Kata terdeteksi:', customAnalisis.matches);
|
|
45
|
+
|
|
46
|
+
// ===== Contoh 3: Whitelist untuk pengecualian kontekstual =====
|
|
47
|
+
console.log('\n=== Penggunaan Whitelist ===\n');
|
|
48
|
+
|
|
49
|
+
// Kita ingin kata "anjing" diperbolehkan jika dalam konteks binatang
|
|
50
|
+
filter.setOptions({});
|
|
51
|
+
filter.addToWhitelist('anjing');
|
|
52
|
+
|
|
53
|
+
const teks3a = 'Anjing adalah hewan peliharaan yang setia.';
|
|
54
|
+
const teks3b = 'Dasar anjing kamu, tidak punya perasaan!';
|
|
55
|
+
|
|
56
|
+
console.log('Teks dengan konteks binatang:', teks3a);
|
|
57
|
+
console.log('Terdeteksi sebagai kata kotor?', filter.isProfane(teks3a));
|
|
58
|
+
|
|
59
|
+
// Tambahkan kembali "anjing" ke daftar kata kotor
|
|
60
|
+
filter.removeFromWhitelist('anjing');
|
|
61
|
+
console.log('\nSetelah dihapus dari whitelist:');
|
|
62
|
+
console.log('Terdeteksi sebagai kata kotor?', filter.isProfane(teks3a));
|
|
63
|
+
|
|
64
|
+
// ===== Contoh 4: Membuat preset kustom =====
|
|
65
|
+
console.log('\n=== Membuat Preset Kustom ===\n');
|
|
66
|
+
|
|
67
|
+
// Kita bisa membuat preset filter kustom
|
|
68
|
+
const myCustomPreset: FilterOptions = {
|
|
69
|
+
replaceWith: '●', // Karakter pengganti
|
|
70
|
+
fullWordCensor: false,
|
|
71
|
+
keepFirstAndLast: true,
|
|
72
|
+
detectLeetSpeak: true,
|
|
73
|
+
indonesianVariation: true,
|
|
74
|
+
detectSplit: false,
|
|
75
|
+
useRandomGrawlix: false,
|
|
76
|
+
categories: ['insult', 'profanity'],
|
|
77
|
+
severityThreshold: 0.3,
|
|
78
|
+
whitelist: ['anjing'], // Untuk konteks binatang
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const teks4 = 'Anjing itu lucu, tidak seperti si goblok dan bego itu.';
|
|
82
|
+
console.log('Teks asli:', teks4);
|
|
83
|
+
|
|
84
|
+
// Gunakan preset kustom
|
|
85
|
+
filter.setOptions(myCustomPreset);
|
|
86
|
+
console.log('Hasil preset kustom:', filter.filter(teks4).filtered);
|
|
87
|
+
|
|
88
|
+
// ===== Contoh 5: Filter berdasarkan kategori atau daerah saja =====
|
|
89
|
+
console.log('\n=== Filter Berdasarkan Kategori atau Daerah ===\n');
|
|
90
|
+
|
|
91
|
+
// Filter hanya kata dari kategori "sexual"
|
|
92
|
+
filter.setOptions({
|
|
93
|
+
categories: ['sexual'],
|
|
94
|
+
wordList: [], // Reset daftar kata kustom
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const teks5 =
|
|
98
|
+
'Ngewe dan bokep itu kata kotor, bego dan anjing tidak terfilter.';
|
|
99
|
+
console.log('Teks asli:', teks5);
|
|
100
|
+
console.log('Filter hanya kategori sexual:', filter.filter(teks5).filtered);
|
|
101
|
+
|
|
102
|
+
// Filter hanya kata dari daerah "jawa"
|
|
103
|
+
filter.setOptions({
|
|
104
|
+
categories: [],
|
|
105
|
+
regions: ['jawa'],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const teks5b = 'Kata jancuk dan cuk dari Jawa, anjing adalah kata umum.';
|
|
109
|
+
console.log('\nTeks asli:', teks5b);
|
|
110
|
+
console.log('Filter hanya daerah jawa:', filter.filter(teks5b).filtered);
|
|
111
|
+
|
|
112
|
+
// ===== Contoh 6: Custom wordList dengan metadata =====
|
|
113
|
+
console.log('\n=== Custom wordList dengan Metadata ===\n');
|
|
114
|
+
|
|
115
|
+
// Ini contoh jika Anda ingin membuat daftar kata lengkap dengan metadata
|
|
116
|
+
const customWordsWithMetadata = [
|
|
117
|
+
{
|
|
118
|
+
word: 'jelek',
|
|
119
|
+
category: 'insult' as any,
|
|
120
|
+
region: 'general' as any,
|
|
121
|
+
severity: 0.4,
|
|
122
|
+
aliases: ['jelex', 'jlk'],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
word: 'payah',
|
|
126
|
+
category: 'insult' as any,
|
|
127
|
+
region: 'general' as any,
|
|
128
|
+
severity: 0.3,
|
|
129
|
+
aliases: ['pyh', 'payaah'],
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// Namun untuk filter sederhana, cukup gunakan kata-kata saja
|
|
134
|
+
filter.setOptions({
|
|
135
|
+
wordList: customWordsWithMetadata.map((w) => w.word),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const teks6 = 'Performanya sangat jelek dan payah sekali.';
|
|
139
|
+
console.log('Teks asli:', teks6);
|
|
140
|
+
console.log('Filter dengan wordList kustom:', filter.filter(teks6).filtered);
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { sexual } from './sexual';
|
|
2
|
+
import { insult } from './insult';
|
|
3
3
|
// import { profanity } from './profanity';
|
|
4
4
|
// import { slur } from './slur';
|
|
5
5
|
// import { drugs } from './drugs';
|
|
6
6
|
// import { disgusting } from './disgusting';
|
|
7
7
|
// import { blasphemy } from './blasphemy';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
|
|
9
|
+
export const categories = {
|
|
10
|
+
sexual, // Kata-kata berbau seksual
|
|
11
|
+
insult, // Kata-kata penghinaan
|
|
12
|
+
// profanity, // Umpatan umum
|
|
13
|
+
// slur, // Perkataan merendahkan berdasarkan identitas
|
|
14
|
+
// drugs, // Terkait narkoba
|
|
15
|
+
// disgusting, // Kata-kata menjijikkan
|
|
16
|
+
// blasphemy, // Penistaan agama
|
|
17
|
+
};
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
export { sexual, insult };
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
21
|
+
export const allCategoryWords = [
|
|
22
|
+
...sexual,
|
|
23
|
+
...insult,
|
|
24
|
+
// ...profanity,
|
|
25
|
+
// ...slur,
|
|
26
|
+
// ...drugs,
|
|
27
|
+
// ...disgusting,
|
|
28
|
+
// ...blasphemy,
|
|
29
|
+
];
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
export default allCategoryWords;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { general } from './general';
|
|
2
|
+
import { jawa } from './jawa';
|
|
3
|
+
import { sunda } from './sunda';
|
|
4
|
+
import { betawi } from './betawi';
|
|
5
|
+
import { batak } from './batak';
|
|
6
6
|
// import { minang } from './minang';
|
|
7
7
|
// import { bali } from './bali';
|
|
8
8
|
// import { madura } from './madura';
|
|
@@ -17,46 +17,46 @@
|
|
|
17
17
|
// import { ntt } from './ntt';
|
|
18
18
|
// import { ntb } from './ntb';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
20
|
+
export {
|
|
21
|
+
general,
|
|
22
|
+
jawa,
|
|
23
|
+
sunda,
|
|
24
|
+
betawi,
|
|
25
|
+
batak,
|
|
26
|
+
// minang,
|
|
27
|
+
// bali,
|
|
28
|
+
// madura,
|
|
29
|
+
// bugis,
|
|
30
|
+
// aceh,
|
|
31
|
+
// ambon,
|
|
32
|
+
// papua,
|
|
33
|
+
// manado,
|
|
34
|
+
// banjar,
|
|
35
|
+
// palembang,
|
|
36
|
+
// lampung,
|
|
37
|
+
// ntt,
|
|
38
|
+
// ntb,
|
|
39
|
+
};
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
41
|
+
export const allRegionWords = [
|
|
42
|
+
...general,
|
|
43
|
+
...jawa,
|
|
44
|
+
...sunda,
|
|
45
|
+
...betawi,
|
|
46
|
+
...batak,
|
|
47
|
+
// ...minang,
|
|
48
|
+
// ...bali,
|
|
49
|
+
// ...madura,
|
|
50
|
+
// ...bugis,
|
|
51
|
+
// ...aceh,
|
|
52
|
+
// ...ambon,
|
|
53
|
+
// ...papua,
|
|
54
|
+
// ...manado,
|
|
55
|
+
// ...banjar,
|
|
56
|
+
// ...palembang,
|
|
57
|
+
// ...lampung,
|
|
58
|
+
// ...ntt,
|
|
59
|
+
// ...ntb,
|
|
60
|
+
];
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
export default allRegionWords;
|