@indodev/toolkit 0.2.0 → 0.3.0

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/dist/index.cjs CHANGED
@@ -210,6 +210,46 @@ function maskNIK(nik, options = {}) {
210
210
  return startPart + char.repeat(maskLength) + endPart;
211
211
  }
212
212
 
213
+ // src/nik/utils.ts
214
+ function getAge(nik, referenceDate = /* @__PURE__ */ new Date()) {
215
+ const info = parseNIK(nik);
216
+ if (!info || !info.birthDate) {
217
+ return null;
218
+ }
219
+ const birthDate = info.birthDate;
220
+ let age = referenceDate.getFullYear() - birthDate.getFullYear();
221
+ const m = referenceDate.getMonth() - birthDate.getMonth();
222
+ if (m < 0 || m === 0 && referenceDate.getDate() < birthDate.getDate()) {
223
+ age--;
224
+ }
225
+ return age;
226
+ }
227
+ function formatBirthDate(nik, options = {
228
+ day: "numeric",
229
+ month: "long",
230
+ year: "numeric"
231
+ }, locale = "id-ID") {
232
+ const info = parseNIK(nik);
233
+ if (!info || !info.birthDate) {
234
+ return null;
235
+ }
236
+ return new Intl.DateTimeFormat(locale, options).format(info.birthDate);
237
+ }
238
+ function isValidForGender(nik, gender) {
239
+ const info = parseNIK(nik);
240
+ if (!info) {
241
+ return false;
242
+ }
243
+ return info.gender === gender;
244
+ }
245
+ function isValidForBirthDate(nik, birthDate) {
246
+ const info = parseNIK(nik);
247
+ if (!info || !info.birthDate) {
248
+ return false;
249
+ }
250
+ return info.birthDate.getFullYear() === birthDate.getFullYear() && info.birthDate.getMonth() === birthDate.getMonth() && info.birthDate.getDate() === birthDate.getDate();
251
+ }
252
+
213
253
  // src/phone/constants.ts
214
254
  var OPERATOR_PREFIXES = {
215
255
  // Telkomsel (Halo, Simpati, by.U)
@@ -852,6 +892,37 @@ function maskPhoneNumber(phone, options = {}) {
852
892
  return masked;
853
893
  }
854
894
 
895
+ // src/phone/links.ts
896
+ function generateWALink(phone, message) {
897
+ if (!validatePhoneNumber(phone)) {
898
+ return "";
899
+ }
900
+ const e164 = toE164(phone);
901
+ let link = `https://wa.me/${e164}`;
902
+ if (message) {
903
+ link += `?text=${encodeURIComponent(message)}`;
904
+ }
905
+ return link;
906
+ }
907
+ function generateSmsLink(phone, body) {
908
+ if (!validatePhoneNumber(phone)) {
909
+ return "";
910
+ }
911
+ const e164 = toE164(phone);
912
+ let link = `sms:+${e164}`;
913
+ if (body) {
914
+ link += `?body=${encodeURIComponent(body)}`;
915
+ }
916
+ return link;
917
+ }
918
+ function generateTelLink(phone) {
919
+ if (!validatePhoneNumber(phone)) {
920
+ return "";
921
+ }
922
+ const e164 = toE164(phone);
923
+ return `tel:+${e164}`;
924
+ }
925
+
855
926
  // src/phone/parse.ts
856
927
  function parsePhoneNumber(phone) {
857
928
  if (!validatePhoneNumber(phone)) {
@@ -900,6 +971,13 @@ function getOperator(phone) {
900
971
  const prefix = normalized.substring(0, 4);
901
972
  return OPERATOR_PREFIXES[prefix] || null;
902
973
  }
974
+ function isProvider(phone, providerName) {
975
+ const operator = getOperator(phone);
976
+ if (!operator) {
977
+ return false;
978
+ }
979
+ return operator.toLowerCase() === providerName.toLowerCase();
980
+ }
903
981
  function getRegion(phone) {
904
982
  if (!phone.startsWith("0")) {
905
983
  return null;
@@ -925,6 +1003,184 @@ function normalizeToNational2(phone) {
925
1003
  return "";
926
1004
  }
927
1005
 
1006
+ // src/npwp/validate.ts
1007
+ function validateNPWP(npwp) {
1008
+ if (!npwp || typeof npwp !== "string") {
1009
+ return false;
1010
+ }
1011
+ const cleaned = npwp.replace(/[^\d]/g, "");
1012
+ if (cleaned.length !== 15 && cleaned.length !== 16) {
1013
+ return false;
1014
+ }
1015
+ if (!/^\d+$/.test(cleaned)) {
1016
+ return false;
1017
+ }
1018
+ return true;
1019
+ }
1020
+
1021
+ // src/npwp/format.ts
1022
+ function formatNPWP(npwp) {
1023
+ if (!validateNPWP(npwp)) {
1024
+ return npwp;
1025
+ }
1026
+ const cleaned = npwp.replace(/[^\d]/g, "");
1027
+ if (cleaned.length === 15) {
1028
+ return `${cleaned.substring(0, 2)}.${cleaned.substring(
1029
+ 2,
1030
+ 5
1031
+ )}.${cleaned.substring(5, 8)}.${cleaned.substring(8, 9)}-${cleaned.substring(
1032
+ 9,
1033
+ 12
1034
+ )}.${cleaned.substring(12, 15)}`;
1035
+ }
1036
+ return cleaned;
1037
+ }
1038
+ function parseNPWP(npwp) {
1039
+ if (!validateNPWP(npwp)) {
1040
+ return null;
1041
+ }
1042
+ const cleaned = npwp.replace(/[^\d]/g, "");
1043
+ const isNikBased = cleaned.length === 16;
1044
+ if (isNikBased) {
1045
+ return {
1046
+ npwp: cleaned,
1047
+ type: cleaned.substring(0, 2),
1048
+ serial: cleaned.substring(2, 8),
1049
+ checksum: cleaned.substring(8, 9),
1050
+ taxOfficeCode: cleaned.substring(9, 12),
1051
+ branchCode: cleaned.substring(12, 16),
1052
+ isNikBased: true
1053
+ };
1054
+ }
1055
+ return {
1056
+ npwp: cleaned,
1057
+ type: cleaned.substring(0, 2),
1058
+ serial: cleaned.substring(2, 8),
1059
+ checksum: cleaned.substring(8, 9),
1060
+ taxOfficeCode: cleaned.substring(9, 12),
1061
+ branchCode: cleaned.substring(12, 15),
1062
+ isNikBased: false
1063
+ };
1064
+ }
1065
+ function maskNPWP(npwp, options) {
1066
+ if (!npwp) return "";
1067
+ const { visibleStart = 2, visibleEnd = 3, maskChar = "*" } = options || {};
1068
+ if (npwp.includes(".") || npwp.includes("-")) {
1069
+ let digitCount = 0;
1070
+ const digitsOnly = npwp.replace(/[^\d]/g, "");
1071
+ const totalDigits = digitsOnly.length;
1072
+ return npwp.split("").map((char) => {
1073
+ if (/\d/.test(char)) {
1074
+ digitCount++;
1075
+ if (digitCount <= visibleStart || digitCount > totalDigits - visibleEnd) {
1076
+ return char;
1077
+ }
1078
+ return maskChar;
1079
+ }
1080
+ return char;
1081
+ }).join("");
1082
+ }
1083
+ const cleaned = npwp.replace(/[^\d]/g, "");
1084
+ if (cleaned.length < visibleStart + visibleEnd) {
1085
+ return cleaned.replace(/./g, maskChar);
1086
+ }
1087
+ const start = cleaned.substring(0, visibleStart);
1088
+ const end = cleaned.substring(cleaned.length - visibleEnd);
1089
+ const middle = maskChar.repeat(cleaned.length - visibleStart - visibleEnd);
1090
+ return `${start}${middle}${end}`;
1091
+ }
1092
+
1093
+ // src/plate/regions.ts
1094
+ var PLATE_REGIONS = {
1095
+ A: "Banten",
1096
+ B: "Jakarta, Depok, Tangerang, Bekasi",
1097
+ D: "Bandung, Cimahi",
1098
+ E: "Cirebon, Indramayu, Majalengka, Kuningan",
1099
+ F: "Bogor, Cianjur, Sukabumi",
1100
+ G: "Pekalongan, Pemalang, Batang, Tegal, Brebes",
1101
+ H: "Semarang, Salatiga, Kendal, Demak",
1102
+ K: "Pati, Kudus, Jepara, Rembang, Blora, Grobogan",
1103
+ L: "Surabaya",
1104
+ M: "Madura",
1105
+ N: "Malang, Probolinggo, Pasuruan, Lumajang, Batu",
1106
+ P: "Besuki, Bondowoso, Situbondo, Jember, Banyuwangi",
1107
+ R: "Banyumas, Cilacap, Purbalinggo, Banjarnegara",
1108
+ S: "Bojonegoro, Tuban, Lamongan, Jombang, Mojokerto",
1109
+ T: "Purwakarta, Subang, Karawang",
1110
+ AA: "Kedu, Magelang, Purworejo, Kebumen, Temanggung, Wonosobo",
1111
+ AB: "Yogyakarta",
1112
+ AD: "Surakarta, Boyolali, Sukoharjo, Karanganyar, Wonogiri, Sragen, Klaten",
1113
+ AE: "Madiun, Ngawi, Magetan, Ponorogo, Pacitan",
1114
+ AG: "Kediri, Blitar, Tulungagung, Nganjuk, Trenggalek",
1115
+ BA: "Sumatera Barat",
1116
+ BB: "Sumatera Utara (Pantai Barat)",
1117
+ BD: "Bengkulu",
1118
+ BE: "Lampung",
1119
+ BG: "Sumatera Selatan",
1120
+ BH: "Jambi",
1121
+ BK: "Sumatera Utara (Pantai Timur)",
1122
+ BL: "Aceh",
1123
+ BM: "Riau",
1124
+ BN: "Kepulauan Bangka Belitung",
1125
+ BP: "Kepulauan Riau",
1126
+ DA: "Kalimantan Selatan",
1127
+ DB: "Sulawesi Utara (Daratan)",
1128
+ DC: "Sulawesi Barat",
1129
+ DD: "Sulawesi Selatan (Selatan)",
1130
+ DE: "Maluku",
1131
+ DF: "Timor Timur (Historical)",
1132
+ DG: "Maluku Utara",
1133
+ DH: "NTT (Timor)",
1134
+ DK: "Bali",
1135
+ DL: "Sulawesi Utara (Kepulauan)",
1136
+ DM: "Gorontalo",
1137
+ DN: "Sulawesi Tengah",
1138
+ DP: "Sulawesi Selatan (Utara)",
1139
+ DR: "NTB (Lombok)",
1140
+ DS: "Papua",
1141
+ DT: "Sulawesi Tenggara",
1142
+ EA: "NTB (Sumbawa)",
1143
+ EB: "NTT (Flores)",
1144
+ ED: "NTT (Sumba)",
1145
+ KB: "Kalimantan Barat",
1146
+ KH: "Kalimantan Tengah",
1147
+ KT: "Kalimantan Timur",
1148
+ KU: "Kalimantan Utara",
1149
+ PA: "Papua",
1150
+ PB: "Papua Barat"
1151
+ };
1152
+
1153
+ // src/plate/utils.ts
1154
+ function validatePlate(plate) {
1155
+ if (!plate || typeof plate !== "string") {
1156
+ return false;
1157
+ }
1158
+ const cleaned = plate.replace(/\s+/g, "").toUpperCase();
1159
+ const regex = /^[A-Z]{1,2}\d{1,4}[A-Z]{1,3}$/;
1160
+ return regex.test(cleaned);
1161
+ }
1162
+ function getRegionFromPlate(plate) {
1163
+ if (!plate || typeof plate !== "string") {
1164
+ return null;
1165
+ }
1166
+ const cleaned = plate.replace(/\s+/g, "").toUpperCase();
1167
+ const match = cleaned.match(/^([A-Z]{1,2})/);
1168
+ if (!match) {
1169
+ return null;
1170
+ }
1171
+ const prefix = match[1];
1172
+ return PLATE_REGIONS[prefix] || null;
1173
+ }
1174
+ function formatPlate(plate) {
1175
+ if (!plate) return "";
1176
+ const cleaned = plate.replace(/\s+/g, "").toUpperCase();
1177
+ const match = cleaned.match(/^([A-Z]{1,2})(\d{1,4})([A-Z]{1,3})$/);
1178
+ if (!match) {
1179
+ return cleaned;
1180
+ }
1181
+ return `${match[1]} ${match[2]} ${match[3]}`;
1182
+ }
1183
+
928
1184
  // src/currency/format.ts
929
1185
  function formatRupiah(amount, options) {
930
1186
  const {
@@ -1150,6 +1406,37 @@ function capitalize(str) {
1150
1406
  return str.charAt(0).toUpperCase() + str.slice(1);
1151
1407
  }
1152
1408
 
1409
+ // src/currency/utils.ts
1410
+ function roundToClean(amount, unit = "ribu") {
1411
+ const divisors = {
1412
+ ribu: 1e3,
1413
+ "ratus-ribu": 1e5,
1414
+ juta: 1e6
1415
+ };
1416
+ const divisor = divisors[unit];
1417
+ return Math.round(amount / divisor) * divisor;
1418
+ }
1419
+ function formatAccounting(amount, options) {
1420
+ const isNegative = amount < 0;
1421
+ const formatted = formatRupiah(Math.abs(amount), options);
1422
+ if (isNegative) {
1423
+ return `(${formatted})`;
1424
+ }
1425
+ return formatted;
1426
+ }
1427
+ function calculateTax(amount, rate = 0.11) {
1428
+ return amount * rate;
1429
+ }
1430
+ function addRupiahSymbol(amount) {
1431
+ if (typeof amount === "number") {
1432
+ return `Rp ${amount.toLocaleString("id-ID")}`;
1433
+ }
1434
+ if (amount.trim().startsWith("Rp")) {
1435
+ return amount;
1436
+ }
1437
+ return `Rp ${amount.trim()}`;
1438
+ }
1439
+
1153
1440
  // src/text/constants.ts
1154
1441
  var LOWERCASE_WORDS = [
1155
1442
  // Indonesian prepositions (kata depan)
@@ -1600,6 +1887,741 @@ var ABBREVIATIONS = {
1600
1887
  "m3.": "meter kubik",
1601
1888
  "ha.": "hektar"
1602
1889
  };
1890
+ var PROFANITY = [
1891
+ "anjing",
1892
+ "babi",
1893
+ "bangsat",
1894
+ "bajingan",
1895
+ "brengsek",
1896
+ "goblok",
1897
+ "tolol",
1898
+ "idiot",
1899
+ "perek",
1900
+ "jablay",
1901
+ "kontol",
1902
+ "memek",
1903
+ "ngewe",
1904
+ "puki",
1905
+ "jembut",
1906
+ "asu",
1907
+ "itil",
1908
+ "lanjiao",
1909
+ "pantek",
1910
+ "anying",
1911
+ "anjrit"
1912
+ ];
1913
+ var STOPWORDS = [
1914
+ "ada",
1915
+ "adalah",
1916
+ "adanya",
1917
+ "adapun",
1918
+ "agak",
1919
+ "agaknya",
1920
+ "agar",
1921
+ "akan",
1922
+ "akankah",
1923
+ "akhir",
1924
+ "akhiri",
1925
+ "akhirnya",
1926
+ "aku",
1927
+ "akulah",
1928
+ "amat",
1929
+ "amatlah",
1930
+ "anda",
1931
+ "andalah",
1932
+ "antar",
1933
+ "antara",
1934
+ "antaranya",
1935
+ "apa",
1936
+ "apaan",
1937
+ "apabila",
1938
+ "apakah",
1939
+ "apalagi",
1940
+ "apatah",
1941
+ "artinya",
1942
+ "asal",
1943
+ "asalkan",
1944
+ "atas",
1945
+ "atau",
1946
+ "ataukah",
1947
+ "ataupun",
1948
+ "awal",
1949
+ "awalnya",
1950
+ "bagai",
1951
+ "bagaikan",
1952
+ "bagaimana",
1953
+ "bagaimanakah",
1954
+ "bagaimanapun",
1955
+ "bagi",
1956
+ "bagian",
1957
+ "bahkan",
1958
+ "bahwa",
1959
+ "bahwasanya",
1960
+ "baik",
1961
+ "bakal",
1962
+ "bakalan",
1963
+ "balik",
1964
+ "banyak",
1965
+ "bapak",
1966
+ "baru",
1967
+ "bawah",
1968
+ "beberapa",
1969
+ "begini",
1970
+ "beginian",
1971
+ "beginikah",
1972
+ "beginilah",
1973
+ "begitu",
1974
+ "begitukah",
1975
+ "begitulah",
1976
+ "begitupun",
1977
+ "bekerja",
1978
+ "belakang",
1979
+ "belakangan",
1980
+ "belum",
1981
+ "belumlah",
1982
+ "benar",
1983
+ "benarkah",
1984
+ "benarlah",
1985
+ "berada",
1986
+ "berakhir",
1987
+ "berakhirlah",
1988
+ "berakhirnya",
1989
+ "berapa",
1990
+ "berapakah",
1991
+ "berapalah",
1992
+ "berapapun",
1993
+ "berarti",
1994
+ "berawal",
1995
+ "berbagai",
1996
+ "berikut",
1997
+ "berikutnya",
1998
+ "berjumlah",
1999
+ "berkali-kali",
2000
+ "berkata",
2001
+ "berkeinginan",
2002
+ "berkenaan",
2003
+ "berlainan",
2004
+ "berlalu",
2005
+ "berlangsung",
2006
+ "berlebihan",
2007
+ "bermacam",
2008
+ "bermacam-macam",
2009
+ "bermaksud",
2010
+ "bermula",
2011
+ "bersama",
2012
+ "bersama-sama",
2013
+ "bersiap",
2014
+ "bersiap-siap",
2015
+ "bertanya",
2016
+ "bertanya-tanya",
2017
+ "berturut",
2018
+ "berturut-turut",
2019
+ "bertutur",
2020
+ "berujar",
2021
+ "berupa",
2022
+ "besar",
2023
+ "betul",
2024
+ "betulkah",
2025
+ "biasa",
2026
+ "biasanya",
2027
+ "bila",
2028
+ "bilakah",
2029
+ "bisa",
2030
+ "bisakah",
2031
+ "boleh",
2032
+ "bolehkah",
2033
+ "bolehlah",
2034
+ "buat",
2035
+ "bukan",
2036
+ "bukankah",
2037
+ "bukanlah",
2038
+ "bukannya",
2039
+ "bulan",
2040
+ "bung",
2041
+ "cara",
2042
+ "caranya",
2043
+ "cukup",
2044
+ "cukupkah",
2045
+ "cukuplah",
2046
+ "cuma",
2047
+ "dahulu",
2048
+ "dalam",
2049
+ "dan",
2050
+ "dapat",
2051
+ "dari",
2052
+ "daripada",
2053
+ "datang",
2054
+ "dekat",
2055
+ "demi",
2056
+ "demikian",
2057
+ "demikianlah",
2058
+ "dengan",
2059
+ "depan",
2060
+ "di",
2061
+ "dia",
2062
+ "diakhiri",
2063
+ "diakhirinya",
2064
+ "dialah",
2065
+ "diantara",
2066
+ "diantaranya",
2067
+ "diberi",
2068
+ "diberikan",
2069
+ "diberikannya",
2070
+ "dibuat",
2071
+ "dibuatnya",
2072
+ "didapat",
2073
+ "didatangkan",
2074
+ "digunakan",
2075
+ "diibaratkan",
2076
+ "diingat",
2077
+ "diingatkan",
2078
+ "diinginkan",
2079
+ "dijawab",
2080
+ "dijelaskan",
2081
+ "dijelaskannya",
2082
+ "dikarenakan",
2083
+ "dikatakan",
2084
+ "dikatakannya",
2085
+ "dikerjakan",
2086
+ "diketahui",
2087
+ "diketahuinya",
2088
+ "dikira",
2089
+ "dilakukan",
2090
+ "dilalui",
2091
+ "dilihat",
2092
+ "dimaksud",
2093
+ "dimaksudkan",
2094
+ "dimaksudkannya",
2095
+ "dimana",
2096
+ "dimanalah",
2097
+ "dimulai",
2098
+ "dimulailah",
2099
+ "dimulainya",
2100
+ "diminta",
2101
+ "dimintai",
2102
+ "dimisalkan",
2103
+ "dimungkinkan",
2104
+ "dini",
2105
+ "dipastikan",
2106
+ "diperbuat",
2107
+ "diperbuatnya",
2108
+ "dipergunakan",
2109
+ "diperkirakan",
2110
+ "diperlihatkan",
2111
+ "diperlukan",
2112
+ "diperlukannya",
2113
+ "dipersoalkan",
2114
+ "dipertanyakan",
2115
+ "dipunyai",
2116
+ "diri",
2117
+ "dirinya",
2118
+ "disampaikan",
2119
+ "disebut",
2120
+ "disebutkan",
2121
+ "disebutkannya",
2122
+ "disini",
2123
+ "disinilah",
2124
+ "disitulah",
2125
+ "diterangkan",
2126
+ "diterangkannya",
2127
+ "diteruskan",
2128
+ "ditujukan",
2129
+ "ditunjuk",
2130
+ "ditunjuki",
2131
+ "ditunjukkan",
2132
+ "ditunjukkannya",
2133
+ "ditunjuknya",
2134
+ "dituturkan",
2135
+ "dituturkannya",
2136
+ "diucapkan",
2137
+ "diucapkannya",
2138
+ "diungkapkan",
2139
+ "dua",
2140
+ "dulu",
2141
+ "empat",
2142
+ "enggak",
2143
+ "enggaknya",
2144
+ "entah",
2145
+ "entahlah",
2146
+ "guna",
2147
+ "gunakan",
2148
+ "hal",
2149
+ "hampir",
2150
+ "hanya",
2151
+ "hanyalah",
2152
+ "hari",
2153
+ "harus",
2154
+ "haruslah",
2155
+ "harusnya",
2156
+ "hendak",
2157
+ "hendaklah",
2158
+ "hendaknya",
2159
+ "hingga",
2160
+ "ia",
2161
+ "ialah",
2162
+ "ibarat",
2163
+ "ibaratkan",
2164
+ "ibaratnya",
2165
+ "ibu",
2166
+ "ikut",
2167
+ "ingat",
2168
+ "ingat-ingat",
2169
+ "ingin",
2170
+ "inginkah",
2171
+ "inginkan",
2172
+ "ini",
2173
+ "inikah",
2174
+ "inilah",
2175
+ "itu",
2176
+ "itukah",
2177
+ "itulah",
2178
+ "jadi",
2179
+ "jadilah",
2180
+ "jadinya",
2181
+ "jangan",
2182
+ "jangankan",
2183
+ "janganlah",
2184
+ "jauh",
2185
+ "jawab",
2186
+ "jawaban",
2187
+ "jawabnya",
2188
+ "jelas",
2189
+ "jelaskan",
2190
+ "jelaslah",
2191
+ "jelasnya",
2192
+ "jika",
2193
+ "jikalau",
2194
+ "juga",
2195
+ "jumlah",
2196
+ "jumlahnya",
2197
+ "justru",
2198
+ "kala",
2199
+ "kalau",
2200
+ "kalaulah",
2201
+ "kalaupun",
2202
+ "kali",
2203
+ "kalian",
2204
+ "kami",
2205
+ "kamilah",
2206
+ "kamu",
2207
+ "kamulah",
2208
+ "kan",
2209
+ "kapan",
2210
+ "kapankah",
2211
+ "kapanpun",
2212
+ "karena",
2213
+ "karenanya",
2214
+ "ke",
2215
+ "keadaan",
2216
+ "kebetulan",
2217
+ "kecil",
2218
+ "kedua",
2219
+ "keduanya",
2220
+ "keinginan",
2221
+ "kelak",
2222
+ "kelihatan",
2223
+ "kelihatannya",
2224
+ "kelima",
2225
+ "keluar",
2226
+ "kembali",
2227
+ "kemudian",
2228
+ "kemungkinan",
2229
+ "kemungkinannya",
2230
+ "kenapa",
2231
+ "kepada",
2232
+ "kepadanya",
2233
+ "kesampaian",
2234
+ "keseluruhan",
2235
+ "keseluruhannya",
2236
+ "keterlaluan",
2237
+ "ketika",
2238
+ "khususnya",
2239
+ "kini",
2240
+ "kinilah",
2241
+ "kira",
2242
+ "kira-kira",
2243
+ "kiranya",
2244
+ "kita",
2245
+ "kitalah",
2246
+ "kok",
2247
+ "kurang",
2248
+ "lagi",
2249
+ "lagian",
2250
+ "lah",
2251
+ "lain",
2252
+ "lainnya",
2253
+ "lalu",
2254
+ "lama",
2255
+ "lamanya",
2256
+ "lanjut",
2257
+ "lanjutnya",
2258
+ "lebih",
2259
+ "lewat",
2260
+ "luar",
2261
+ "macam",
2262
+ "maka",
2263
+ "makanya",
2264
+ "makin",
2265
+ "malah",
2266
+ "malahan",
2267
+ "mampu",
2268
+ "mampukah",
2269
+ "mana",
2270
+ "manakala",
2271
+ "manalagi",
2272
+ "masih",
2273
+ "masihkah",
2274
+ "masing",
2275
+ "masing-masing",
2276
+ "mau",
2277
+ "maupun",
2278
+ "melainkan",
2279
+ "melakukan",
2280
+ "melalui",
2281
+ "melihat",
2282
+ "melihatnya",
2283
+ "memang",
2284
+ "memastikan",
2285
+ "memberi",
2286
+ "memberikan",
2287
+ "membuat",
2288
+ "memerlukan",
2289
+ "memihak",
2290
+ "meminta",
2291
+ "memisalkan",
2292
+ "memperbuat",
2293
+ "mempergunakan",
2294
+ "memperkirakan",
2295
+ "memperlihatkan",
2296
+ "mempersiapkan",
2297
+ "mempersoalkan",
2298
+ "mempertanyakan",
2299
+ "mempunyai",
2300
+ "memulai",
2301
+ "memungkinkan",
2302
+ "memutuskan",
2303
+ "menanti",
2304
+ "menanti-nanti",
2305
+ "menantikan",
2306
+ "menunjuk",
2307
+ "menunjuknya",
2308
+ "menuju",
2309
+ "menurut",
2310
+ "menurutnya",
2311
+ "menurutmu",
2312
+ "menurutku",
2313
+ "menurutnya",
2314
+ "menurut mereka",
2315
+ "menyampaikan",
2316
+ "menyebut",
2317
+ "menyebutkan",
2318
+ "menjelaskan",
2319
+ "menjadi",
2320
+ "menjadikan",
2321
+ "menjalani",
2322
+ "menjelang",
2323
+ "menjawab",
2324
+ "menunjukkan",
2325
+ "menuangkan",
2326
+ "menulis",
2327
+ "menyatakan",
2328
+ "merupakan",
2329
+ "mereka",
2330
+ "merekalah",
2331
+ "meski",
2332
+ "meskipun",
2333
+ "mula",
2334
+ "mulai",
2335
+ "mulailah",
2336
+ "mulanya",
2337
+ "mungkin",
2338
+ "mungkinkah",
2339
+ "nah",
2340
+ "naik",
2341
+ "namun",
2342
+ "nanti",
2343
+ "nantinya",
2344
+ "nyaris",
2345
+ "oleh",
2346
+ "olehnya",
2347
+ "orang",
2348
+ "pada",
2349
+ "padahal",
2350
+ "padanya",
2351
+ "pakai",
2352
+ "paling",
2353
+ "panjang",
2354
+ "pantas",
2355
+ "para",
2356
+ "pasti",
2357
+ "pastilah",
2358
+ "pagi",
2359
+ "per",
2360
+ "pernah",
2361
+ "persoalan",
2362
+ "pertama",
2363
+ "pertama-tama",
2364
+ "perlu",
2365
+ "perlukah",
2366
+ "perlulah",
2367
+ "pernah",
2368
+ "pihak",
2369
+ "pihaknya",
2370
+ "pukul",
2371
+ "pula",
2372
+ "pun",
2373
+ "punya",
2374
+ "rasa",
2375
+ "rasanya",
2376
+ "rata",
2377
+ "rupanya",
2378
+ "saat",
2379
+ "saatnya",
2380
+ "saja",
2381
+ "sajalah",
2382
+ "salam",
2383
+ "saling",
2384
+ "sama",
2385
+ "sama-sama",
2386
+ "sambil",
2387
+ "sampai",
2388
+ "sampai-sampai",
2389
+ "sampaikan",
2390
+ "sana",
2391
+ "sangat",
2392
+ "sangatlah",
2393
+ "satu",
2394
+ "saya",
2395
+ "sayalah",
2396
+ "sayang",
2397
+ "seperti",
2398
+ "seperti-itu",
2399
+ "sepura",
2400
+ "sebab",
2401
+ "sebabnya",
2402
+ "sebagai",
2403
+ "sebagaimana",
2404
+ "sebagainya",
2405
+ "sebagian",
2406
+ "sebaik",
2407
+ "sebaik-baiknya",
2408
+ "sebaiknya",
2409
+ "sebaliknya",
2410
+ "sebanyak",
2411
+ "sebegini",
2412
+ "sebegitu",
2413
+ "sebelum",
2414
+ "sebelumnya",
2415
+ "sebenarnya",
2416
+ "seberapa",
2417
+ "sebesar",
2418
+ "sebetulnya",
2419
+ "sebisanya",
2420
+ "sebuah",
2421
+ "sebut",
2422
+ "sebutkan",
2423
+ "sebutnya",
2424
+ "secara",
2425
+ "secukupnya",
2426
+ "sedang",
2427
+ "sedangkan",
2428
+ "sedikit",
2429
+ "sedikitnya",
2430
+ "sedemikian",
2431
+ "sediakala",
2432
+ "sedikit",
2433
+ "sedikitnya",
2434
+ "segala",
2435
+ "segalanya",
2436
+ "segera",
2437
+ "seharusnya",
2438
+ "sehingga",
2439
+ "seingat",
2440
+ "sejak",
2441
+ "sejauh",
2442
+ "sejenak",
2443
+ "sejumlah",
2444
+ "sekali",
2445
+ "sekali-kali",
2446
+ "sekalian",
2447
+ "sekaligus",
2448
+ "sekalipun",
2449
+ "sekarang",
2450
+ "sekaranglah",
2451
+ "sekecil",
2452
+ "seketika",
2453
+ "sekiranya",
2454
+ "sekitar",
2455
+ "sekitarnya",
2456
+ "sekurang",
2457
+ "sekurangnya",
2458
+ "sela",
2459
+ "selalu",
2460
+ "selama",
2461
+ "selama-lamanya",
2462
+ "selamanya",
2463
+ "selanjutnya",
2464
+ "seluruh",
2465
+ "seluruhnya",
2466
+ "semacam",
2467
+ "semakin",
2468
+ "semampu",
2469
+ "semampunya",
2470
+ "semasa",
2471
+ "semata",
2472
+ "semata-mata",
2473
+ "semaunya",
2474
+ "sementara",
2475
+ "semisal",
2476
+ "semisalnya",
2477
+ "sempat",
2478
+ "semua",
2479
+ "semuanya",
2480
+ "semula",
2481
+ "sendiri",
2482
+ "sendirinya",
2483
+ "seolah",
2484
+ "seolah-olah",
2485
+ "seorang",
2486
+ "sepanjang",
2487
+ "sepantasnya",
2488
+ "sepantasnyalah",
2489
+ "seperempat",
2490
+ "seperti",
2491
+ "sepertinya",
2492
+ "sepihak",
2493
+ "sepuluh",
2494
+ "seratus",
2495
+ "seribu",
2496
+ "sering",
2497
+ "seringnya",
2498
+ "serta",
2499
+ "serupa",
2500
+ "sesaat",
2501
+ "sesama",
2502
+ "sesampai",
2503
+ "sesampainya",
2504
+ "sesegera",
2505
+ "sesekali",
2506
+ "seseorang",
2507
+ "sesuatu",
2508
+ "sesuatunya",
2509
+ "sesudah",
2510
+ "sesudahnya",
2511
+ "setelah",
2512
+ "setempat",
2513
+ "setengah",
2514
+ "seterusnya",
2515
+ "setiap",
2516
+ "setidaknya",
2517
+ "setinggi",
2518
+ "seusai",
2519
+ "sewaktu",
2520
+ "siap",
2521
+ "siapa",
2522
+ "siapakah",
2523
+ "siapapun",
2524
+ "sini",
2525
+ "sinilah",
2526
+ "situ",
2527
+ "situlah",
2528
+ "suatu",
2529
+ "sudah",
2530
+ "sudahkah",
2531
+ "sudahlah",
2532
+ "supaya",
2533
+ "tadi",
2534
+ "tadinya",
2535
+ "tahu",
2536
+ "tak",
2537
+ "tambah",
2538
+ "tambahnya",
2539
+ "tampak",
2540
+ "tampaknya",
2541
+ "tandas",
2542
+ "tandasnya",
2543
+ "tanpa",
2544
+ "tanya",
2545
+ "tanyakan",
2546
+ "tanyanya",
2547
+ "tapi",
2548
+ "tegas",
2549
+ "tegasnya",
2550
+ "telah",
2551
+ "tempat",
2552
+ "tengah",
2553
+ "tentang",
2554
+ "tentu",
2555
+ "tentulah",
2556
+ "tentunya",
2557
+ "tepat",
2558
+ "terakhir",
2559
+ "terasa",
2560
+ "terbanyak",
2561
+ "terdahulu",
2562
+ "terdapat",
2563
+ "terdiri",
2564
+ "terdiri-dari",
2565
+ "terhadap",
2566
+ "terhadapnya",
2567
+ "teringat",
2568
+ "teringat-ingat",
2569
+ "terjadi",
2570
+ "terjadilah",
2571
+ "terjadinya",
2572
+ "terkira",
2573
+ "terlalu",
2574
+ "terlebih",
2575
+ "terlihat",
2576
+ "termasuk",
2577
+ "ternyata",
2578
+ "tersampaikan",
2579
+ "tersebut",
2580
+ "tersebutlah",
2581
+ "tertentu",
2582
+ "tertuju",
2583
+ "terus",
2584
+ "terutama",
2585
+ "tetap",
2586
+ "tetapi",
2587
+ "tiap",
2588
+ "tiba",
2589
+ "tiba-tiba",
2590
+ "tidak",
2591
+ "tidakkah",
2592
+ "tidaklah",
2593
+ "tiga",
2594
+ "tadi",
2595
+ "tadinya",
2596
+ "tinggi",
2597
+ "toh",
2598
+ "tuju",
2599
+ "tunjuk",
2600
+ "turut",
2601
+ "tutur",
2602
+ "tuturnya",
2603
+ "ucap",
2604
+ "ucapnya",
2605
+ "ujar",
2606
+ "ujarnya",
2607
+ "umumnya",
2608
+ "ungkap",
2609
+ "ungkapnya",
2610
+ "untuk",
2611
+ "untaian",
2612
+ "usai",
2613
+ "usah",
2614
+ "waduh",
2615
+ "wah",
2616
+ "wahai",
2617
+ "walau",
2618
+ "walaupun",
2619
+ "wong",
2620
+ "yaitu",
2621
+ "yakin",
2622
+ "yakni",
2623
+ "yang"
2624
+ ];
1603
2625
 
1604
2626
  // src/text/capitalization.ts
1605
2627
  function capitalize2(text) {
@@ -1937,6 +2959,78 @@ function contractAbbreviation(text, options) {
1937
2959
  return result;
1938
2960
  }
1939
2961
 
2962
+ // src/text/filter.ts
2963
+ function profanityFilter(text, mask = "*") {
2964
+ let filtered = text;
2965
+ PROFANITY.forEach((word) => {
2966
+ const regex = new RegExp(`\\b${word}\\b`, "gi");
2967
+ filtered = filtered.replace(regex, mask.repeat(word.length));
2968
+ });
2969
+ return filtered;
2970
+ }
2971
+ function removeStopwords(text) {
2972
+ const words = text.split(/\s+/);
2973
+ const filtered = words.filter(
2974
+ (word) => !STOPWORDS.includes(word.toLowerCase())
2975
+ );
2976
+ return filtered.join(" ");
2977
+ }
2978
+
2979
+ // src/text/normalization.ts
2980
+ var INFORMAL_MAP = {
2981
+ gw: "saya",
2982
+ gua: "saya",
2983
+ lu: "kamu",
2984
+ lo: "kamu",
2985
+ elo: "kamu",
2986
+ lagi: "sedang",
2987
+ gue: "saya",
2988
+ gwe: "saya",
2989
+ gak: "tidak",
2990
+ ga: "tidak",
2991
+ nggak: "tidak",
2992
+ kalo: "kalau",
2993
+ karna: "karena",
2994
+ tapi: "tetapi",
2995
+ udah: "sudah",
2996
+ dah: "sudah",
2997
+ aja: "saja",
2998
+ banget: "sekali",
2999
+ emang: "memang",
3000
+ pake: "pakai",
3001
+ bikin: "membuat",
3002
+ kasih: "memberi",
3003
+ dapet: "dapat",
3004
+ liat: "lihat",
3005
+ ngasih: "memberi",
3006
+ nyari: "mencari",
3007
+ nanya: "bertanya",
3008
+ bilang: "berkata"
3009
+ };
3010
+ function toFormal(text) {
3011
+ const words = text.split(/\s+/);
3012
+ const formalized = words.map((word) => {
3013
+ const lower = word.toLowerCase().replace(/[^\w]/g, "");
3014
+ const formal = INFORMAL_MAP[lower];
3015
+ if (formal) {
3016
+ if (word[0] === word[0].toUpperCase()) {
3017
+ return formal.charAt(0).toUpperCase() + formal.slice(1);
3018
+ }
3019
+ return formal;
3020
+ }
3021
+ return word;
3022
+ });
3023
+ return formalized.join(" ");
3024
+ }
3025
+ function isAlay(text) {
3026
+ if (!text) return false;
3027
+ const alternatingCaps = /([a-z][A-Z][a-z]|[A-Z][a-z][A-Z])/.test(text);
3028
+ const numberSub = /\b\w*[0431572]\w*\b/.test(text);
3029
+ const qSub = /q/i.test(text) && !/u/i.test(text);
3030
+ const excessiveChars = /(.)\1{2,}/.test(text);
3031
+ return alternatingCaps || numberSub || qSub || excessiveChars;
3032
+ }
3033
+
1940
3034
  // src/text/extract.ts
1941
3035
  function truncate(text, maxLength, options) {
1942
3036
  if (!text || maxLength <= 0) {
@@ -2045,30 +3139,51 @@ function similarity(str1, str2) {
2045
3139
  return 1 - distance / maxLength;
2046
3140
  }
2047
3141
 
3142
+ exports.addRupiahSymbol = addRupiahSymbol;
3143
+ exports.calculateTax = calculateTax;
2048
3144
  exports.capitalize = capitalize2;
2049
3145
  exports.cleanPhoneNumber = cleanPhoneNumber;
2050
3146
  exports.compareStrings = compareStrings;
2051
3147
  exports.contractAbbreviation = contractAbbreviation;
2052
3148
  exports.expandAbbreviation = expandAbbreviation;
2053
3149
  exports.extractWords = extractWords;
3150
+ exports.formatAccounting = formatAccounting;
3151
+ exports.formatBirthDate = formatBirthDate;
2054
3152
  exports.formatCompact = formatCompact;
2055
3153
  exports.formatNIK = formatNIK;
3154
+ exports.formatNPWP = formatNPWP;
2056
3155
  exports.formatPhoneNumber = formatPhoneNumber;
3156
+ exports.formatPlate = formatPlate;
2057
3157
  exports.formatRupiah = formatRupiah;
3158
+ exports.generateSmsLink = generateSmsLink;
3159
+ exports.generateTelLink = generateTelLink;
3160
+ exports.generateWALink = generateWALink;
3161
+ exports.getAge = getAge;
2058
3162
  exports.getOperator = getOperator;
3163
+ exports.getRegionFromPlate = getRegionFromPlate;
3164
+ exports.isAlay = isAlay;
2059
3165
  exports.isLandlineNumber = isLandlineNumber;
2060
3166
  exports.isMobileNumber = isMobileNumber;
3167
+ exports.isProvider = isProvider;
3168
+ exports.isValidForBirthDate = isValidForBirthDate;
3169
+ exports.isValidForGender = isValidForGender;
2061
3170
  exports.maskNIK = maskNIK;
3171
+ exports.maskNPWP = maskNPWP;
2062
3172
  exports.maskPhoneNumber = maskPhoneNumber;
2063
3173
  exports.normalizeWhitespace = normalizeWhitespace;
2064
3174
  exports.parseNIK = parseNIK;
3175
+ exports.parseNPWP = parseNPWP;
2065
3176
  exports.parsePhoneNumber = parsePhoneNumber;
2066
3177
  exports.parseRupiah = parseRupiah;
3178
+ exports.profanityFilter = profanityFilter;
2067
3179
  exports.removeAccents = removeAccents;
3180
+ exports.removeStopwords = removeStopwords;
3181
+ exports.roundToClean = roundToClean;
2068
3182
  exports.sanitize = sanitize;
2069
3183
  exports.similarity = similarity;
2070
3184
  exports.slugify = slugify;
2071
3185
  exports.toE164 = toE164;
3186
+ exports.toFormal = toFormal;
2072
3187
  exports.toInternational = toInternational;
2073
3188
  exports.toNational = toNational;
2074
3189
  exports.toSentenceCase = toSentenceCase;
@@ -2076,6 +3191,8 @@ exports.toTitleCase = toTitleCase;
2076
3191
  exports.toWords = toWords;
2077
3192
  exports.truncate = truncate;
2078
3193
  exports.validateNIK = validateNIK;
3194
+ exports.validateNPWP = validateNPWP;
2079
3195
  exports.validatePhoneNumber = validatePhoneNumber;
3196
+ exports.validatePlate = validatePlate;
2080
3197
  //# sourceMappingURL=index.cjs.map
2081
3198
  //# sourceMappingURL=index.cjs.map