superjs-core 0.6.0 → 0.7.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.js CHANGED
@@ -78,6 +78,7 @@ function deepMerge(...objects) {
78
78
  const keys = Object.keys(obj);
79
79
  for (let j = 0; j < keys.length; j++) {
80
80
  const key = keys[j];
81
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
81
82
  const val = obj[key];
82
83
  const existing = result[key];
83
84
  if (val !== void 0 && isPlainObject(val) && isPlainObject(existing)) {
@@ -265,6 +266,54 @@ function once(fn) {
265
266
  return result;
266
267
  };
267
268
  }
269
+ function deepEqual(a, b) {
270
+ if (Object.is(a, b)) return true;
271
+ if (a === null || b === null || typeof a !== typeof b) return false;
272
+ if (typeof a !== "object") return false;
273
+ const aObj = a;
274
+ const bObj = b;
275
+ if (Array.isArray(a) && Array.isArray(b)) {
276
+ if (a.length !== b.length) return false;
277
+ for (let i = 0; i < a.length; i++) {
278
+ if (!deepEqual(a[i], b[i])) return false;
279
+ }
280
+ return true;
281
+ }
282
+ if (a instanceof Date && b instanceof Date) {
283
+ return a.getTime() === b.getTime();
284
+ }
285
+ if (a instanceof RegExp && b instanceof RegExp) {
286
+ return a.source === b.source && a.flags === b.flags;
287
+ }
288
+ if (a instanceof Map && b instanceof Map) {
289
+ if (a.size !== b.size) return false;
290
+ for (const [k, v] of a) {
291
+ if (!b.has(k) || !deepEqual(v, b.get(k))) return false;
292
+ }
293
+ return true;
294
+ }
295
+ if (a instanceof Set && b instanceof Set) {
296
+ if (a.size !== b.size) return false;
297
+ for (const v of a) {
298
+ if (!b.has(v)) return false;
299
+ }
300
+ return true;
301
+ }
302
+ const keysA = Object.keys(aObj);
303
+ const keysB = Object.keys(bObj);
304
+ if (keysA.length !== keysB.length) return false;
305
+ for (const key of keysA) {
306
+ if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;
307
+ if (!deepEqual(aObj[key], bObj[key])) return false;
308
+ }
309
+ return true;
310
+ }
311
+ function pipe(initial, ...fns) {
312
+ return fns.reduce((acc, fn) => fn(acc), initial);
313
+ }
314
+ function compose(...fns) {
315
+ return (initial) => fns.reduceRight((acc, fn) => fn(acc), initial);
316
+ }
268
317
 
269
318
  // src/math/index.ts
270
319
  var DivisionByZeroError = class extends Error {
@@ -354,6 +403,250 @@ function randomInt(min, max) {
354
403
  function inRange(value, min, max) {
355
404
  return value >= min && value <= max;
356
405
  }
406
+ function median(values) {
407
+ if (values.length === 0) throw new RangeError("Cannot compute median of an empty array");
408
+ const sorted = [...values].sort((a, b) => a - b);
409
+ const mid = Math.floor(sorted.length / 2);
410
+ return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
411
+ }
412
+ function stddev(values) {
413
+ if (values.length < 2) throw new RangeError("Need at least 2 values for stddev");
414
+ const mean = sum(values) / values.length;
415
+ const sqDiffs = values.map((v) => (v - mean) ** 2);
416
+ return Math.sqrt(sqDiffs.reduce((a, b) => a + b, 0) / values.length);
417
+ }
418
+ function sampleStddev(values) {
419
+ if (values.length < 2) throw new RangeError("Need at least 2 values for sample stddev");
420
+ const mean = sum(values) / values.length;
421
+ const sqDiffs = values.map((v) => (v - mean) ** 2);
422
+ return Math.sqrt(sqDiffs.reduce((a, b) => a + b, 0) / (values.length - 1));
423
+ }
424
+ function percentile(values, p) {
425
+ if (values.length === 0) throw new RangeError("Cannot compute percentile of empty array");
426
+ if (p < 0 || p > 100) throw new RangeError("Percentile must be between 0 and 100");
427
+ const sorted = [...values].sort((a, b) => a - b);
428
+ const rank = p / 100 * (sorted.length - 1);
429
+ const lower = Math.floor(rank);
430
+ const upper = Math.ceil(rank);
431
+ if (lower === upper) return sorted[lower];
432
+ return sorted[lower] + (sorted[upper] - sorted[lower]) * (rank - lower);
433
+ }
434
+ function correlation(x, y) {
435
+ if (x.length !== y.length) throw new RangeError("Arrays must have the same length");
436
+ if (x.length < 2) throw new RangeError("Need at least 2 pairs for correlation");
437
+ const n = x.length;
438
+ const meanX = sum(x) / n;
439
+ const meanY = sum(y) / n;
440
+ let num = 0;
441
+ let denX = 0;
442
+ let denY = 0;
443
+ for (let i = 0; i < n; i++) {
444
+ const dx = x[i] - meanX;
445
+ const dy = y[i] - meanY;
446
+ num += dx * dy;
447
+ denX += dx * dx;
448
+ denY += dy * dy;
449
+ }
450
+ if (denX === 0 || denY === 0) return 0;
451
+ return num / Math.sqrt(denX * denY);
452
+ }
453
+ function formatCurrency(value, options) {
454
+ const locale = options?.locale ?? "id-ID";
455
+ const currency = options?.currency ?? "IDR";
456
+ const notation = options?.notation ?? "standard";
457
+ try {
458
+ return new Intl.NumberFormat(locale, {
459
+ style: "currency",
460
+ currency,
461
+ notation,
462
+ minimumFractionDigits: 0,
463
+ maximumFractionDigits: 2
464
+ }).format(value);
465
+ } catch {
466
+ return `${currency} ${value.toLocaleString(locale)}`;
467
+ }
468
+ }
469
+ function isEven(n) {
470
+ return n % 2 === 0;
471
+ }
472
+ function isOdd(n) {
473
+ return n % 2 !== 0;
474
+ }
475
+ function gcd(a, b) {
476
+ if (!Number.isInteger(a) || !Number.isInteger(b)) {
477
+ throw new RangeError("Arguments must be integers");
478
+ }
479
+ a = Math.abs(a);
480
+ b = Math.abs(b);
481
+ while (b !== 0) {
482
+ const t = b;
483
+ b = a % b;
484
+ a = t;
485
+ }
486
+ return a;
487
+ }
488
+ function lcm(a, b) {
489
+ if (!Number.isInteger(a) || !Number.isInteger(b)) {
490
+ throw new RangeError("Arguments must be integers");
491
+ }
492
+ if (a === 0 || b === 0) {
493
+ throw new RangeError("Arguments must be non-zero");
494
+ }
495
+ return Math.abs(a * b) / gcd(a, b);
496
+ }
497
+ function factorial(n) {
498
+ if (!Number.isInteger(n)) {
499
+ throw new RangeError("Argument must be an integer");
500
+ }
501
+ if (n < 0) {
502
+ throw new RangeError("Factorial is not defined for negative numbers");
503
+ }
504
+ let result = 1;
505
+ for (let i = 2; i <= n; i++) {
506
+ result *= i;
507
+ }
508
+ return result;
509
+ }
510
+ function isPrime(n) {
511
+ if (!Number.isInteger(n)) {
512
+ throw new RangeError("Argument must be an integer");
513
+ }
514
+ if (n < 2) return false;
515
+ if (n === 2 || n === 3) return true;
516
+ if (n % 2 === 0 || n % 3 === 0) return false;
517
+ const limit = Math.sqrt(n);
518
+ for (let i = 5; i <= limit; i += 6) {
519
+ if (n % i === 0 || n % (i + 2) === 0) return false;
520
+ }
521
+ return true;
522
+ }
523
+ function toRadians(degrees) {
524
+ return degrees * Math.PI / 180;
525
+ }
526
+ function toDegrees(radians) {
527
+ return radians * 180 / Math.PI;
528
+ }
529
+ function lerp(a, b, t) {
530
+ return a + (b - a) * t;
531
+ }
532
+ function percentageOf(value, total) {
533
+ if (total === 0) {
534
+ throw new RangeError("Total must be non-zero");
535
+ }
536
+ return value / total * 100;
537
+ }
538
+ function mapRange(value, inMin, inMax, outMin, outMax) {
539
+ if (inMin === inMax) {
540
+ throw new RangeError("Input range must not be zero");
541
+ }
542
+ return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin;
543
+ }
544
+ function mode(values) {
545
+ if (values.length === 0) {
546
+ throw new RangeError("Cannot compute mode of an empty array");
547
+ }
548
+ const freq = /* @__PURE__ */ new Map();
549
+ let maxFreq = 0;
550
+ for (const v of values) {
551
+ const count = (freq.get(v) ?? 0) + 1;
552
+ freq.set(v, count);
553
+ if (count > maxFreq) maxFreq = count;
554
+ }
555
+ const result = [];
556
+ for (const [v, count] of freq) {
557
+ if (count === maxFreq) result.push(v);
558
+ }
559
+ return result;
560
+ }
561
+ function range(start, end, step) {
562
+ const dir = end >= start ? 1 : -1;
563
+ const s = step ?? dir;
564
+ if (s === 0) {
565
+ throw new RangeError("Step must not be zero");
566
+ }
567
+ if ((end - start) * s < 0) {
568
+ return [];
569
+ }
570
+ const result = [];
571
+ let i = start;
572
+ if (s > 0) {
573
+ while (i <= end) {
574
+ result.push(i);
575
+ i += s;
576
+ }
577
+ } else {
578
+ while (i >= end) {
579
+ result.push(i);
580
+ i += s;
581
+ }
582
+ }
583
+ return result;
584
+ }
585
+ function weightedAverage(values, weights) {
586
+ if (values.length === 0 || weights.length === 0) {
587
+ throw new RangeError("Arrays must not be empty");
588
+ }
589
+ if (values.length !== weights.length) {
590
+ throw new RangeError("Values and weights must have the same length");
591
+ }
592
+ let weightedSum = 0;
593
+ let weightSum = 0;
594
+ for (let i = 0; i < values.length; i++) {
595
+ weightedSum += values[i] * weights[i];
596
+ weightSum += weights[i];
597
+ }
598
+ if (weightSum === 0) {
599
+ throw new RangeError("Sum of weights must be non-zero");
600
+ }
601
+ return weightedSum / weightSum;
602
+ }
603
+ function geometricMean(values) {
604
+ if (values.length === 0) {
605
+ throw new RangeError("Cannot compute geometric mean of an empty array");
606
+ }
607
+ for (const v of values) {
608
+ if (v < 0) {
609
+ throw new RangeError("Values must be non-negative for geometric mean");
610
+ }
611
+ }
612
+ const logSum = values.reduce((acc, v) => v === 0 ? acc : acc + Math.log(v), 0);
613
+ if (logSum === -Infinity) return 0;
614
+ return Math.exp(logSum / values.length);
615
+ }
616
+ function combinations(n, k) {
617
+ if (!Number.isInteger(n) || !Number.isInteger(k)) {
618
+ throw new RangeError("Arguments must be integers");
619
+ }
620
+ if (n < 0 || k < 0) {
621
+ throw new RangeError("Arguments must be non-negative");
622
+ }
623
+ if (k > n) {
624
+ throw new RangeError("k must not exceed n");
625
+ }
626
+ if (k === 0 || k === n) return 1;
627
+ const r = Math.min(k, n - k);
628
+ let result = 1;
629
+ for (let i = 1; i <= r; i++) {
630
+ result = result * (n - r + i) / i;
631
+ }
632
+ return result;
633
+ }
634
+ function permutations(n, k) {
635
+ if (!Number.isInteger(n) || !Number.isInteger(k)) {
636
+ throw new RangeError("Arguments must be integers");
637
+ }
638
+ if (n < 0 || k < 0) {
639
+ throw new RangeError("Arguments must be non-negative");
640
+ }
641
+ if (k > n) {
642
+ throw new RangeError("k must not exceed n");
643
+ }
644
+ let result = 1;
645
+ for (let i = n; i > n - k; i--) {
646
+ result *= i;
647
+ }
648
+ return result;
649
+ }
357
650
 
358
651
  // src/date/index.ts
359
652
  var InvalidDateError = class extends Error {
@@ -610,6 +903,427 @@ function calculateAge(birthDate) {
610
903
  }
611
904
  return age;
612
905
  }
906
+ var LOCALE_LABELS = {
907
+ id: {
908
+ years: { single: "tahun", plural: "tahun" },
909
+ months: { single: "bulan", plural: "bulan" },
910
+ weeks: { single: "minggu", plural: "minggu" },
911
+ days: { single: "hari", plural: "hari" },
912
+ hours: { single: "jam", plural: "jam" },
913
+ minutes: { single: "menit", plural: "menit" },
914
+ seconds: { single: "detik", plural: "detik" }
915
+ },
916
+ en: {
917
+ years: { single: "year", plural: "years" },
918
+ months: { single: "month", plural: "months" },
919
+ weeks: { single: "week", plural: "weeks" },
920
+ days: { single: "day", plural: "days" },
921
+ hours: { single: "hour", plural: "hours" },
922
+ minutes: { single: "minute", plural: "minutes" },
923
+ seconds: { single: "second", plural: "seconds" }
924
+ }
925
+ };
926
+ function getSuffix(diffMs, kind, locale) {
927
+ if (diffMs < 0) {
928
+ return locale === "en" ? "ago" : "yang lalu";
929
+ }
930
+ if (kind === "remaining") {
931
+ return locale === "en" ? "remaining" : "lagi";
932
+ }
933
+ return locale === "en" ? "ago" : "yang lalu";
934
+ }
935
+ function formatRelativeTime(absDiffMs, suffix, locale) {
936
+ const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id;
937
+ const seconds = Math.floor(absDiffMs / 1e3);
938
+ const minutes = Math.floor(seconds / 60);
939
+ const hours = Math.floor(minutes / 60);
940
+ const days = Math.floor(hours / 24);
941
+ const weeks = Math.floor(days / 7);
942
+ const months = Math.floor(days / 30.4375);
943
+ const years = Math.floor(days / 365.25);
944
+ let count;
945
+ let unit;
946
+ if (years >= 1) {
947
+ count = years;
948
+ unit = "years";
949
+ } else if (months >= 1) {
950
+ count = months;
951
+ unit = "months";
952
+ } else if (weeks >= 1) {
953
+ count = weeks;
954
+ unit = "weeks";
955
+ } else if (days >= 1) {
956
+ count = days;
957
+ unit = "days";
958
+ } else if (hours >= 1) {
959
+ count = hours;
960
+ unit = "hours";
961
+ } else if (minutes >= 1) {
962
+ count = minutes;
963
+ unit = "minutes";
964
+ } else {
965
+ count = Math.max(1, seconds);
966
+ unit = "seconds";
967
+ }
968
+ const label = count === 1 ? labels[unit].single : labels[unit].plural;
969
+ return `${count} ${label} ${suffix}`;
970
+ }
971
+ function timeAgo(date, options) {
972
+ const diff = Date.now() - date.getTime();
973
+ const locale = options?.locale ?? "id";
974
+ const suffix = getSuffix(diff, "ago", locale);
975
+ return formatRelativeTime(Math.abs(diff), suffix, locale);
976
+ }
977
+ function timeRemaining(target, options) {
978
+ const diff = target.getTime() - Date.now();
979
+ const locale = options?.locale ?? "id";
980
+ const suffix = getSuffix(diff, "remaining", locale);
981
+ return formatRelativeTime(Math.abs(diff), suffix, locale);
982
+ }
983
+ function formatDuration(duration, options) {
984
+ const locale = options?.locale ?? "id";
985
+ const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id;
986
+ const parts = [];
987
+ const entries = [
988
+ ["years", duration.years],
989
+ ["months", duration.months],
990
+ ["days", duration.days],
991
+ ["hours", duration.hours],
992
+ ["minutes", duration.minutes],
993
+ ["seconds", duration.seconds]
994
+ ];
995
+ for (const [key, value] of entries) {
996
+ if (value > 0) {
997
+ const label = value === 1 ? labels[key].single : labels[key].plural;
998
+ parts.push(`${value} ${label}`);
999
+ }
1000
+ }
1001
+ if (parts.length === 0) {
1002
+ const label = labels.seconds.plural;
1003
+ return `0 ${label}`;
1004
+ }
1005
+ return parts.join(" ");
1006
+ }
1007
+ var TIMEZONE_WIB = 7;
1008
+ var TIMEZONE_WITA = 8;
1009
+ var TIMEZONE_WIT = 9;
1010
+ function toTimezone(date, offsetHours) {
1011
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1012
+ const utcMs = date.getTime() + date.getTimezoneOffset() * 6e4;
1013
+ return new Date(utcMs + offsetHours * 36e5);
1014
+ }
1015
+ function formatInTimezone(date, format2, offsetHours) {
1016
+ return formatDate(toTimezone(date, offsetHours), format2);
1017
+ }
1018
+ function isToday(date) {
1019
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1020
+ const now = /* @__PURE__ */ new Date();
1021
+ return date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate();
1022
+ }
1023
+ function isYesterday(date) {
1024
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1025
+ const yesterday = /* @__PURE__ */ new Date();
1026
+ yesterday.setDate(yesterday.getDate() - 1);
1027
+ return date.getFullYear() === yesterday.getFullYear() && date.getMonth() === yesterday.getMonth() && date.getDate() === yesterday.getDate();
1028
+ }
1029
+ function isTomorrow(date) {
1030
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1031
+ const tomorrow = /* @__PURE__ */ new Date();
1032
+ tomorrow.setDate(tomorrow.getDate() + 1);
1033
+ return date.getFullYear() === tomorrow.getFullYear() && date.getMonth() === tomorrow.getMonth() && date.getDate() === tomorrow.getDate();
1034
+ }
1035
+ function isPast(date) {
1036
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1037
+ return date.getTime() < Date.now();
1038
+ }
1039
+ function isFuture(date) {
1040
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1041
+ return date.getTime() > Date.now();
1042
+ }
1043
+ function isSameDay(date1, date2) {
1044
+ if (!isValidDate(date1) || !isValidDate(date2)) {
1045
+ throw new InvalidDateError("Invalid date provided to isSameDay");
1046
+ }
1047
+ return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate();
1048
+ }
1049
+ function daysInMonth(date) {
1050
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1051
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
1052
+ }
1053
+ function dayOfYear(date) {
1054
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1055
+ const start = new Date(date.getFullYear(), 0, 0);
1056
+ return Math.floor((date.getTime() - start.getTime()) / MS_IN_DAY);
1057
+ }
1058
+ function weekOfYear(date) {
1059
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1060
+ const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
1061
+ const dayNum = d.getUTCDay() || 7;
1062
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
1063
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
1064
+ const weekNum = Math.ceil(((d.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
1065
+ return weekNum;
1066
+ }
1067
+ function quarter(date) {
1068
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1069
+ return Math.floor(date.getMonth() / 3) + 1;
1070
+ }
1071
+ function maxDate(dates) {
1072
+ if (dates.length === 0) throw new Error("maxDate requires at least one date");
1073
+ const ms = Math.max(...dates.map((d) => {
1074
+ if (!isValidDate(d)) throw new InvalidDateError(d);
1075
+ return d.getTime();
1076
+ }));
1077
+ return new Date(ms);
1078
+ }
1079
+ function minDate(dates) {
1080
+ if (dates.length === 0) throw new Error("minDate requires at least one date");
1081
+ const ms = Math.min(...dates.map((d) => {
1082
+ if (!isValidDate(d)) throw new InvalidDateError(d);
1083
+ return d.getTime();
1084
+ }));
1085
+ return new Date(ms);
1086
+ }
1087
+ function getNextWeekday(date, targetDay) {
1088
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1089
+ const result = new Date(date);
1090
+ const currentDay = result.getDay();
1091
+ let diff = targetDay - currentDay;
1092
+ if (diff <= 0) diff += 7;
1093
+ result.setDate(result.getDate() + diff);
1094
+ return result;
1095
+ }
1096
+ function getLastWeekday(date, targetDay) {
1097
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1098
+ const result = new Date(date);
1099
+ const currentDay = result.getDay();
1100
+ let diff = currentDay - targetDay;
1101
+ if (diff <= 0) diff += 7;
1102
+ result.setDate(result.getDate() - diff);
1103
+ return result;
1104
+ }
1105
+ function nextMonday(date) {
1106
+ return getNextWeekday(date, 1);
1107
+ }
1108
+ function nextTuesday(date) {
1109
+ return getNextWeekday(date, 2);
1110
+ }
1111
+ function nextWednesday(date) {
1112
+ return getNextWeekday(date, 3);
1113
+ }
1114
+ function nextThursday(date) {
1115
+ return getNextWeekday(date, 4);
1116
+ }
1117
+ function nextFriday(date) {
1118
+ return getNextWeekday(date, 5);
1119
+ }
1120
+ function nextSaturday(date) {
1121
+ return getNextWeekday(date, 6);
1122
+ }
1123
+ function nextSunday(date) {
1124
+ return getNextWeekday(date, 0);
1125
+ }
1126
+ function lastMonday(date) {
1127
+ return getLastWeekday(date, 1);
1128
+ }
1129
+ function lastTuesday(date) {
1130
+ return getLastWeekday(date, 2);
1131
+ }
1132
+ function lastWednesday(date) {
1133
+ return getLastWeekday(date, 3);
1134
+ }
1135
+ function lastThursday(date) {
1136
+ return getLastWeekday(date, 4);
1137
+ }
1138
+ function lastFriday(date) {
1139
+ return getLastWeekday(date, 5);
1140
+ }
1141
+ function lastSaturday(date) {
1142
+ return getLastWeekday(date, 6);
1143
+ }
1144
+ function lastSunday(date) {
1145
+ return getLastWeekday(date, 0);
1146
+ }
1147
+ function parseDuration(input) {
1148
+ const regex = /(\d+)\s*([wdhms])/g;
1149
+ let ms = 0;
1150
+ let match;
1151
+ while ((match = regex.exec(input)) !== null) {
1152
+ const val = parseInt(match[1], 10);
1153
+ switch (match[2]) {
1154
+ case "w":
1155
+ ms += val * 7 * MS_IN_DAY;
1156
+ break;
1157
+ case "d":
1158
+ ms += val * MS_IN_DAY;
1159
+ break;
1160
+ case "h":
1161
+ ms += val * MS_IN_HOUR;
1162
+ break;
1163
+ case "m":
1164
+ ms += val * MS_IN_MINUTE;
1165
+ break;
1166
+ case "s":
1167
+ ms += val * MS_IN_SECOND;
1168
+ break;
1169
+ }
1170
+ }
1171
+ return ms;
1172
+ }
1173
+ var INDONESIAN_FIXED_HOLIDAYS = [
1174
+ { name: "New Year", month: 0, day: 1 },
1175
+ { name: "Labor Day", month: 4, day: 1 },
1176
+ { name: "Pancasila Day", month: 5, day: 1 },
1177
+ { name: "Independence Day", month: 7, day: 17 },
1178
+ { name: "National Awakening Day", month: 4, day: 20 },
1179
+ { name: "National Heroes Day", month: 10, day: 10 },
1180
+ { name: "Christmas", month: 11, day: 25 }
1181
+ ];
1182
+ function computeEaster(year) {
1183
+ const a = year % 19;
1184
+ const b = Math.floor(year / 100);
1185
+ const c = year % 100;
1186
+ const d = Math.floor(b / 4);
1187
+ const e = b % 4;
1188
+ const f = Math.floor((b + 8) / 25);
1189
+ const g = Math.floor((b - f + 1) / 3);
1190
+ const h = (19 * a + b - d - g + 15) % 30;
1191
+ const i = Math.floor(c / 4);
1192
+ const k = c % 4;
1193
+ const l = (32 + 2 * e + 2 * i - h - k) % 7;
1194
+ const m = Math.floor((a + 11 * h + 22 * l) / 451);
1195
+ const month = Math.floor((h + l - 7 * m + 114) / 31);
1196
+ const day = (h + l - 7 * m + 114) % 31 + 1;
1197
+ return new Date(year, month - 1, day);
1198
+ }
1199
+ var CHINESE_NEW_YEAR = {
1200
+ 2024: { month: 1, day: 10 },
1201
+ 2025: { month: 0, day: 29 },
1202
+ 2026: { month: 1, day: 17 },
1203
+ 2027: { month: 1, day: 6 },
1204
+ 2028: { month: 0, day: 26 },
1205
+ 2029: { month: 1, day: 13 },
1206
+ 2030: { month: 2, day: 3 }
1207
+ };
1208
+ var NYEPI = {
1209
+ 2024: { month: 2, day: 11 },
1210
+ 2025: { month: 2, day: 29 },
1211
+ 2026: { month: 2, day: 19 },
1212
+ 2027: { month: 2, day: 7 },
1213
+ 2028: { month: 2, day: 26 },
1214
+ 2029: { month: 2, day: 15 },
1215
+ 2030: { month: 2, day: 5 }
1216
+ };
1217
+ var VESAK = {
1218
+ 2024: { month: 4, day: 23 },
1219
+ 2025: { month: 4, day: 12 },
1220
+ 2026: { month: 4, day: 31 },
1221
+ 2027: { month: 4, day: 20 },
1222
+ 2028: { month: 4, day: 9 },
1223
+ 2029: { month: 4, day: 28 },
1224
+ 2030: { month: 4, day: 18 }
1225
+ };
1226
+ var EID_AL_FITR = {
1227
+ 2024: [{ month: 3, day: 10 }, { month: 3, day: 11 }],
1228
+ 2025: [{ month: 2, day: 31 }, { month: 3, day: 1 }],
1229
+ 2026: [{ month: 2, day: 21 }, { month: 2, day: 22 }],
1230
+ 2027: [{ month: 2, day: 10 }, { month: 2, day: 11 }],
1231
+ 2028: [{ month: 2, day: 28 }, { month: 2, day: 29 }],
1232
+ 2029: [{ month: 2, day: 17 }, { month: 2, day: 18 }],
1233
+ 2030: [{ month: 2, day: 7 }, { month: 2, day: 8 }]
1234
+ };
1235
+ var EID_AL_ADHA = {
1236
+ 2024: { month: 5, day: 17 },
1237
+ 2025: { month: 5, day: 7 },
1238
+ 2026: { month: 4, day: 27 },
1239
+ 2027: { month: 4, day: 17 },
1240
+ 2028: { month: 5, day: 5 },
1241
+ 2029: { month: 4, day: 25 },
1242
+ 2030: { month: 4, day: 15 }
1243
+ };
1244
+ var ISLAMIC_NEW_YEAR = {
1245
+ 2024: { month: 6, day: 7 },
1246
+ 2025: { month: 5, day: 27 },
1247
+ 2026: { month: 5, day: 16 },
1248
+ 2027: { month: 5, day: 6 },
1249
+ 2028: { month: 6, day: 24 },
1250
+ 2029: { month: 6, day: 13 },
1251
+ 2030: { month: 6, day: 3 }
1252
+ };
1253
+ var PROPHETS_BIRTHDAY = {
1254
+ 2024: { month: 8, day: 16 },
1255
+ 2025: { month: 8, day: 5 },
1256
+ 2026: { month: 7, day: 26 },
1257
+ 2027: { month: 7, day: 16 },
1258
+ 2028: { month: 8, day: 3 },
1259
+ 2029: { month: 7, day: 23 },
1260
+ 2030: { month: 7, day: 13 }
1261
+ };
1262
+ var ISRA_MIRAJ = {
1263
+ 2024: { month: 1, day: 8 },
1264
+ 2025: { month: 0, day: 28 },
1265
+ 2026: { month: 0, day: 17 },
1266
+ 2027: { month: 0, day: 6 },
1267
+ 2028: { month: 0, day: 26 },
1268
+ 2029: { month: 1, day: 14 },
1269
+ 2030: { month: 1, day: 3 }
1270
+ };
1271
+ function addHolidayEntry(entries, name, month, day) {
1272
+ entries.push({ name, month, day });
1273
+ }
1274
+ function getIndonesianHolidaysForYear(year) {
1275
+ const holidays = [...INDONESIAN_FIXED_HOLIDAYS];
1276
+ const easter = computeEaster(year);
1277
+ addHolidayEntry(holidays, "Good Friday", easter.getMonth(), easter.getDate() - 2);
1278
+ addHolidayEntry(holidays, "Easter", easter.getMonth(), easter.getDate());
1279
+ const ascension = new Date(easter);
1280
+ ascension.setDate(ascension.getDate() + 39);
1281
+ addHolidayEntry(holidays, "Ascension of Jesus Christ", ascension.getMonth(), ascension.getDate());
1282
+ const cny = CHINESE_NEW_YEAR[year];
1283
+ if (cny) addHolidayEntry(holidays, "Chinese New Year", cny.month, cny.day);
1284
+ const nyepi = NYEPI[year];
1285
+ if (nyepi) addHolidayEntry(holidays, "Nyepi (Day of Silence)", nyepi.month, nyepi.day);
1286
+ const vesak = VESAK[year];
1287
+ if (vesak) addHolidayEntry(holidays, "Vesak (Buddha's Birthday)", vesak.month, vesak.day);
1288
+ const eidDays = EID_AL_FITR[year];
1289
+ if (eidDays) {
1290
+ eidDays.forEach((entry, idx) => {
1291
+ addHolidayEntry(holidays, idx === 0 ? "Eid al-Fitr" : "Eid al-Fitr (Day 2)", entry.month, entry.day);
1292
+ });
1293
+ }
1294
+ const eidAdha = EID_AL_ADHA[year];
1295
+ if (eidAdha) addHolidayEntry(holidays, "Eid al-Adha", eidAdha.month, eidAdha.day);
1296
+ const islNewYear = ISLAMIC_NEW_YEAR[year];
1297
+ if (islNewYear) addHolidayEntry(holidays, "Islamic New Year", islNewYear.month, islNewYear.day);
1298
+ const prophetBday = PROPHETS_BIRTHDAY[year];
1299
+ if (prophetBday) addHolidayEntry(holidays, "Prophet Muhammad's Birthday", prophetBday.month, prophetBday.day);
1300
+ const isra = ISRA_MIRAJ[year];
1301
+ if (isra) addHolidayEntry(holidays, "Isra' Mi'raj (Ascension of Prophet Muhammad)", isra.month, isra.day);
1302
+ return holidays;
1303
+ }
1304
+ function isHolidayIndonesia(date) {
1305
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1306
+ const year = date.getFullYear();
1307
+ const holidays = getIndonesianHolidaysForYear(year);
1308
+ for (const h of holidays) {
1309
+ if (h.month === date.getMonth() && h.day === date.getDate()) {
1310
+ return true;
1311
+ }
1312
+ }
1313
+ return false;
1314
+ }
1315
+ function getIndonesianHolidayNames(date) {
1316
+ if (!isValidDate(date)) throw new InvalidDateError(date);
1317
+ const year = date.getFullYear();
1318
+ const holidays = getIndonesianHolidaysForYear(year);
1319
+ const names = [];
1320
+ for (const h of holidays) {
1321
+ if (h.month === date.getMonth() && h.day === date.getDate()) {
1322
+ names.push(h.name);
1323
+ }
1324
+ }
1325
+ return names;
1326
+ }
613
1327
 
614
1328
  // src/crypto/index.ts
615
1329
  function hash(str) {
@@ -635,15 +1349,12 @@ function simpleHash(str) {
635
1349
  return toHex(h1) + toHex(h2) + toHex(h3) + toHex(h4);
636
1350
  }
637
1351
  function getRandomBytes(size) {
638
- const bytes = new Uint8Array(size);
639
1352
  if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
1353
+ const bytes = new Uint8Array(size);
640
1354
  crypto.getRandomValues(bytes);
641
- } else {
642
- for (let i = 0; i < size; i++) {
643
- bytes[i] = Math.floor(Math.random() * 256);
644
- }
1355
+ return bytes;
645
1356
  }
646
- return bytes;
1357
+ throw new Error("Crypto API unavailable. Cannot generate secure random bytes.");
647
1358
  }
648
1359
  function randomHex(size = 16) {
649
1360
  const bytes = getRandomBytes(size);
@@ -988,6 +1699,217 @@ function isEmpty(value) {
988
1699
  if (value !== null && typeof value === "object") return Object.keys(value).length === 0;
989
1700
  return false;
990
1701
  }
1702
+ function topoSort(items) {
1703
+ const adj = /* @__PURE__ */ new Map();
1704
+ const inDegree = /* @__PURE__ */ new Map();
1705
+ const itemMap = /* @__PURE__ */ new Map();
1706
+ for (const item of items) {
1707
+ itemMap.set(item.id, item);
1708
+ if (!adj.has(item.id)) adj.set(item.id, []);
1709
+ if (!inDegree.has(item.id)) inDegree.set(item.id, 0);
1710
+ }
1711
+ for (const item of items) {
1712
+ if (item.dependencies) {
1713
+ for (const depId of item.dependencies) {
1714
+ adj.get(depId)?.push(item.id);
1715
+ inDegree.set(item.id, (inDegree.get(item.id) ?? 0) + 1);
1716
+ }
1717
+ }
1718
+ }
1719
+ const queue = [];
1720
+ for (const [id, degree] of inDegree) {
1721
+ if (degree === 0) queue.push(id);
1722
+ }
1723
+ const sorted = [];
1724
+ while (queue.length > 0) {
1725
+ const id = queue.shift();
1726
+ sorted.push(id);
1727
+ for (const neighbor of adj.get(id) ?? []) {
1728
+ const newDegree = (inDegree.get(neighbor) ?? 1) - 1;
1729
+ inDegree.set(neighbor, newDegree);
1730
+ if (newDegree === 0) queue.push(neighbor);
1731
+ }
1732
+ }
1733
+ if (sorted.length !== items.length) {
1734
+ throw new Error("Circular dependency detected");
1735
+ }
1736
+ return sorted.map((id) => itemMap.get(id));
1737
+ }
1738
+ function slidingWindows(items, size, step = 1) {
1739
+ if (size <= 0 || items.length === 0 || step <= 0) return [];
1740
+ const result = [];
1741
+ for (let i = 0; i + size <= items.length; i += step) {
1742
+ result.push(items.slice(i, i + size));
1743
+ }
1744
+ return result;
1745
+ }
1746
+ function tumblingWindows(items, size) {
1747
+ if (size <= 0 || items.length === 0) return [];
1748
+ const result = [];
1749
+ for (let i = 0; i < items.length; i += size) {
1750
+ result.push(items.slice(i, i + size));
1751
+ }
1752
+ return result;
1753
+ }
1754
+ function deepGet(obj, path, default_) {
1755
+ const keys = path.split(".");
1756
+ let current = obj;
1757
+ for (const key of keys) {
1758
+ if (current === null || current === void 0) return default_;
1759
+ if (typeof current !== "object") return default_;
1760
+ const curObj = current;
1761
+ if (!(key in curObj)) return default_;
1762
+ current = curObj[key];
1763
+ }
1764
+ return current ?? default_;
1765
+ }
1766
+ function deepSet(obj, path, value) {
1767
+ const keys = path.split(".");
1768
+ const PROTO_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
1769
+ for (const key of keys) {
1770
+ if (PROTO_KEYS.has(key)) {
1771
+ return { ...obj };
1772
+ }
1773
+ }
1774
+ const result = { ...obj };
1775
+ let current = result;
1776
+ for (let i = 0; i < keys.length - 1; i++) {
1777
+ const key = keys[i];
1778
+ const next = current[key];
1779
+ if (next === null || next === void 0 || typeof next !== "object") {
1780
+ const isArray2 = /^\d+$/.test(keys[i + 1]);
1781
+ current[key] = isArray2 ? [] : {};
1782
+ }
1783
+ current = current[key];
1784
+ }
1785
+ current[keys[keys.length - 1]] = value;
1786
+ return result;
1787
+ }
1788
+ function partition(items, predicate) {
1789
+ const pass = [];
1790
+ const fail = [];
1791
+ for (const item of items) {
1792
+ if (predicate(item)) pass.push(item);
1793
+ else fail.push(item);
1794
+ }
1795
+ return [pass, fail];
1796
+ }
1797
+ function compact(items) {
1798
+ return items.filter(Boolean);
1799
+ }
1800
+ function difference(a, b) {
1801
+ const setB = new Set(b);
1802
+ return a.filter((item) => !setB.has(item));
1803
+ }
1804
+ function intersection(a, b) {
1805
+ const setB = new Set(b);
1806
+ return a.filter((item) => setB.has(item));
1807
+ }
1808
+ function union(...arrays) {
1809
+ const set = /* @__PURE__ */ new Set();
1810
+ for (const arr of arrays) {
1811
+ for (const item of arr) {
1812
+ set.add(item);
1813
+ }
1814
+ }
1815
+ return [...set];
1816
+ }
1817
+ function zip(...arrays) {
1818
+ if (arrays.length === 0) return [];
1819
+ const minLen = Math.min(...arrays.map((a) => a.length));
1820
+ const result = [];
1821
+ for (let i = 0; i < minLen; i++) {
1822
+ const tuple = [];
1823
+ for (const arr of arrays) {
1824
+ tuple.push(arr[i]);
1825
+ }
1826
+ result.push(tuple);
1827
+ }
1828
+ return result;
1829
+ }
1830
+ function unzip(paired) {
1831
+ if (paired.length === 0) return [];
1832
+ const tupleLen = paired.reduce((max, t) => Math.max(max, t.length), 0);
1833
+ const result = Array.from({ length: tupleLen }, () => []);
1834
+ for (const tuple of paired) {
1835
+ for (let i = 0; i < tupleLen; i++) {
1836
+ result[i].push(tuple[i]);
1837
+ }
1838
+ }
1839
+ return result;
1840
+ }
1841
+ function countBy(items, keyFn) {
1842
+ const result = {};
1843
+ for (const item of items) {
1844
+ const key = keyFn(item);
1845
+ result[key] = (result[key] ?? 0) + 1;
1846
+ }
1847
+ return result;
1848
+ }
1849
+ function maxBy(items, keyFn) {
1850
+ if (items.length === 0) return void 0;
1851
+ let maxItem = items[0];
1852
+ let maxVal = keyFn(maxItem);
1853
+ for (let i = 1; i < items.length; i++) {
1854
+ const val = keyFn(items[i]);
1855
+ if (val > maxVal) {
1856
+ maxVal = val;
1857
+ maxItem = items[i];
1858
+ }
1859
+ }
1860
+ return maxItem;
1861
+ }
1862
+ function minBy(items, keyFn) {
1863
+ if (items.length === 0) return void 0;
1864
+ let minItem = items[0];
1865
+ let minVal = keyFn(minItem);
1866
+ for (let i = 1; i < items.length; i++) {
1867
+ const val = keyFn(items[i]);
1868
+ if (val < minVal) {
1869
+ minVal = val;
1870
+ minItem = items[i];
1871
+ }
1872
+ }
1873
+ return minItem;
1874
+ }
1875
+ function sumBy(items, keyFn) {
1876
+ let total = 0;
1877
+ for (const item of items) {
1878
+ total += keyFn(item);
1879
+ }
1880
+ return total;
1881
+ }
1882
+ function findIndex(items, predicate, fromIndex = 0) {
1883
+ for (let i = fromIndex; i < items.length; i++) {
1884
+ if (predicate(items[i])) return i;
1885
+ }
1886
+ return -1;
1887
+ }
1888
+ function findLast(items, predicate) {
1889
+ for (let i = items.length - 1; i >= 0; i--) {
1890
+ if (predicate(items[i])) return items[i];
1891
+ }
1892
+ return void 0;
1893
+ }
1894
+ function drop(items, n = 1) {
1895
+ return items.slice(Math.max(0, n));
1896
+ }
1897
+ function dropRight(items, n = 1) {
1898
+ return items.slice(0, Math.max(0, items.length - n));
1899
+ }
1900
+ function take(items, n = 1) {
1901
+ return items.slice(0, Math.max(0, n));
1902
+ }
1903
+ function takeRight(items, n = 1) {
1904
+ return items.slice(Math.max(0, items.length - n));
1905
+ }
1906
+ function without(items, ...values) {
1907
+ const exclude = new Set(values);
1908
+ return items.filter((item) => !exclude.has(item));
1909
+ }
1910
+ function nth(items, index) {
1911
+ return index < 0 ? items[items.length + index] : items[index];
1912
+ }
991
1913
 
992
1914
  // src/string/index.ts
993
1915
  var WORD_SPLIT_RE = /[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\d|\b)|\d+/g;
@@ -1019,6 +1941,7 @@ function truncate(str, maxLength, suffix = "...") {
1019
1941
  }
1020
1942
  function template(str, data) {
1021
1943
  return str.replace(/\{\{(\w+)\}\}/g, (_2, key) => {
1944
+ if (key === "__proto__" || key === "constructor" || key === "prototype") return `{{${key}}}`;
1022
1945
  const value = data[key];
1023
1946
  return value !== void 0 ? String(value) : `{{${key}}}`;
1024
1947
  });
@@ -1044,9 +1967,15 @@ function uuid() {
1044
1967
  }
1045
1968
  function nanoid(size = 21, alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-") {
1046
1969
  const len = alphabet.length;
1970
+ const bytes = new Uint8Array(size);
1971
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
1972
+ crypto.getRandomValues(bytes);
1973
+ } else {
1974
+ throw new Error("Crypto API unavailable. Cannot generate secure random ID.");
1975
+ }
1047
1976
  let result = "";
1048
1977
  for (let i = 0; i < size; i++) {
1049
- result += alphabet[Math.floor(Math.random() * len)];
1978
+ result += alphabet[bytes[i] % len];
1050
1979
  }
1051
1980
  return result;
1052
1981
  }
@@ -1055,7 +1984,9 @@ var HTML_ESCAPE_MAP = {
1055
1984
  "<": "&lt;",
1056
1985
  ">": "&gt;",
1057
1986
  '"': "&quot;",
1058
- "'": "&#39;"
1987
+ "'": "&#39;",
1988
+ "`": "&#96;",
1989
+ "/": "&#x2F;"
1059
1990
  };
1060
1991
  var HTML_UNESCAPE_MAP = {
1061
1992
  "&amp;": "&",
@@ -1063,13 +1994,15 @@ var HTML_UNESCAPE_MAP = {
1063
1994
  "&gt;": ">",
1064
1995
  "&quot;": '"',
1065
1996
  "&#39;": "'",
1066
- "&#x27;": "'"
1997
+ "&#x27;": "'",
1998
+ "&#96;": "`",
1999
+ "&#x2F;": "/"
1067
2000
  };
1068
2001
  function escapeHtml(str) {
1069
- return str.replace(/[&<>"']/g, (ch) => HTML_ESCAPE_MAP[ch] ?? ch);
2002
+ return str.replace(/[&<>"'`\/]/g, (ch) => HTML_ESCAPE_MAP[ch] ?? ch);
1070
2003
  }
1071
2004
  function unescapeHtml(str) {
1072
- return str.replace(/&(?:amp|lt|gt|quot|#39|#x27);/g, (entity) => HTML_UNESCAPE_MAP[entity] ?? entity);
2005
+ return str.replace(/&(?:amp|lt|gt|quot|#39|#x27|#96|#x2F);/g, (entity) => HTML_UNESCAPE_MAP[entity] ?? entity);
1073
2006
  }
1074
2007
  function trim(str) {
1075
2008
  return str.trim();
@@ -1111,6 +2044,494 @@ function countOccurrences(str, substring) {
1111
2044
  }
1112
2045
  return count;
1113
2046
  }
2047
+ function levenshtein(a, b) {
2048
+ const an = a.length;
2049
+ const bn = b.length;
2050
+ if (an === 0) return bn;
2051
+ if (bn === 0) return an;
2052
+ if (an < bn) return levenshtein(b, a);
2053
+ let prev = new Uint32Array(bn + 1);
2054
+ let curr = new Uint32Array(bn + 1);
2055
+ for (let j = 0; j <= bn; j++) prev[j] = j;
2056
+ for (let i = 1; i <= an; i++) {
2057
+ curr[0] = i;
2058
+ for (let j = 1; j <= bn; j++) {
2059
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
2060
+ curr[j] = Math.min(
2061
+ prev[j] + 1,
2062
+ curr[j - 1] + 1,
2063
+ prev[j - 1] + cost
2064
+ );
2065
+ }
2066
+ ;
2067
+ [prev, curr] = [curr, prev];
2068
+ }
2069
+ return prev[bn];
2070
+ }
2071
+ function fuzzyMatch(str, query) {
2072
+ if (query.length === 0) return true;
2073
+ if (str.length === 0) return false;
2074
+ const sl = str.toLowerCase();
2075
+ const ql = query.toLowerCase();
2076
+ let si = 0;
2077
+ for (let qi = 0; qi < ql.length; qi++) {
2078
+ si = sl.indexOf(ql[qi], si);
2079
+ if (si === -1) return false;
2080
+ si++;
2081
+ }
2082
+ return true;
2083
+ }
2084
+ function maskString(str, options) {
2085
+ if (str.length === 0) return str;
2086
+ const maskChar = options?.char ?? "*";
2087
+ const start = options?.start ?? Math.ceil(str.length * 0.25);
2088
+ const end = options?.end ?? Math.floor(str.length * 0.75);
2089
+ if (start >= end || start < 0) return str;
2090
+ const clampedStart = Math.max(0, start);
2091
+ const clampedEnd = Math.min(str.length, end);
2092
+ return str.slice(0, clampedStart) + maskChar.repeat(clampedEnd - clampedStart) + str.slice(clampedEnd);
2093
+ }
2094
+ var SATUAN = ["", "satu", "dua", "tiga", "empat", "lima", "enam", "tujuh", "delapan", "sembilan"];
2095
+ var BELASAN = ["sepuluh", "sebelas", "dua belas", "tiga belas", "empat belas", "lima belas", "enam belas", "tujuh belas", "delapan belas", "sembilan belas"];
2096
+ var PULUHAN = ["", "", "dua puluh", "tiga puluh", "empat puluh", "lima puluh", "enam puluh", "tujuh puluh", "delapan puluh", "sembilan puluh"];
2097
+ function _terbilang(n) {
2098
+ if (n < 0) return "minus " + _terbilang(-n);
2099
+ if (n === 0) return "nol";
2100
+ if (n < 10) return SATUAN[n];
2101
+ if (n < 20) return n === 10 ? "sepuluh" : n === 11 ? "sebelas" : BELASAN[n - 10];
2102
+ if (n < 100) {
2103
+ const pul = Math.floor(n / 10);
2104
+ const sat = n % 10;
2105
+ return PULUHAN[pul] + (sat > 0 ? " " + SATUAN[sat] : "");
2106
+ }
2107
+ if (n < 1e3) {
2108
+ const ratus = Math.floor(n / 100);
2109
+ const sis2 = n % 100;
2110
+ const ratusStr = ratus === 1 ? "seratus" : SATUAN[ratus] + " ratus";
2111
+ return ratusStr + (sis2 > 0 ? " " + _terbilang(sis2) : "");
2112
+ }
2113
+ if (n < 1e6) {
2114
+ const rib = Math.floor(n / 1e3);
2115
+ const sis2 = n % 1e3;
2116
+ const ribStr = rib === 1 ? "seribu" : _terbilang(rib) + " ribu";
2117
+ return ribStr + (sis2 > 0 ? " " + _terbilang(sis2) : "");
2118
+ }
2119
+ if (n < 1e9) {
2120
+ const jut = Math.floor(n / 1e6);
2121
+ const sis2 = n % 1e6;
2122
+ return _terbilang(jut) + " juta" + (sis2 > 0 ? " " + _terbilang(sis2) : "");
2123
+ }
2124
+ if (n < 1e12) {
2125
+ const mil = Math.floor(n / 1e9);
2126
+ const sis2 = n % 1e9;
2127
+ return _terbilang(mil) + " miliar" + (sis2 > 0 ? " " + _terbilang(sis2) : "");
2128
+ }
2129
+ const tril = Math.floor(n / 1e12);
2130
+ const sis = n % 1e12;
2131
+ return _terbilang(tril) + " triliun" + (sis > 0 ? " " + _terbilang(sis) : "");
2132
+ }
2133
+ function terbilang(value) {
2134
+ if (!Number.isFinite(value)) throw new RangeError("Input must be a finite number");
2135
+ if (value > Number.MAX_SAFE_INTEGER) throw new RangeError("Input terlalu besar");
2136
+ return _terbilang(Math.floor(Math.abs(value)));
2137
+ }
2138
+ function formatRupiah(value, options) {
2139
+ return formatCurrency(value, { locale: "id-ID", currency: "IDR", notation: options?.notation });
2140
+ }
2141
+ function formatBytes(bytes, options) {
2142
+ if (bytes === 0) return "0 B";
2143
+ if (!Number.isFinite(bytes) || bytes < 0) return "0 B";
2144
+ const k = 1024;
2145
+ const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
2146
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
2147
+ const dm = options?.decimals ?? (i === 0 ? 0 : 1);
2148
+ const index = Math.min(i, sizes.length - 1);
2149
+ return parseFloat((bytes / Math.pow(k, index)).toFixed(dm)) + " " + sizes[index];
2150
+ }
2151
+ function randomString(length = 16) {
2152
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2153
+ const bytes = new Uint8Array(length);
2154
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
2155
+ crypto.getRandomValues(bytes);
2156
+ } else {
2157
+ throw new Error("Crypto API unavailable. Cannot generate secure random string.");
2158
+ }
2159
+ let result = "";
2160
+ for (let i = 0; i < length; i++) {
2161
+ result += chars[bytes[i] % chars.length];
2162
+ }
2163
+ return result;
2164
+ }
2165
+ function randomBoolean() {
2166
+ return Math.random() >= 0.5;
2167
+ }
2168
+ function pluralize(count, singular) {
2169
+ if (count === 1) return singular;
2170
+ const last2 = singular[singular.length - 1];
2171
+ const lastTwo = singular.slice(-2);
2172
+ if (last2 === "s" || last2 === "x" || last2 === "z" || lastTwo === "ch" || lastTwo === "sh") {
2173
+ return singular + "es";
2174
+ }
2175
+ if (last2 === "y" && singular.length > 2 && !"aeiou".includes(singular[singular.length - 2])) {
2176
+ return singular.slice(0, -1) + "ies";
2177
+ }
2178
+ return singular + "s";
2179
+ }
2180
+ function stripHtml(str) {
2181
+ return str.replace(/<[^>]*>/g, "");
2182
+ }
2183
+ function truncateWords(str, count, suffix = "...") {
2184
+ const words2 = str.split(/\s+/).filter(Boolean);
2185
+ if (words2.length <= count) return str;
2186
+ return words2.slice(0, count).join(" ") + suffix;
2187
+ }
2188
+ function isPalindrome(str) {
2189
+ const cleaned = str.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
2190
+ if (cleaned.length <= 1) return true;
2191
+ let left = 0;
2192
+ let right = cleaned.length - 1;
2193
+ while (left < right) {
2194
+ if (cleaned[left] !== cleaned[right]) return false;
2195
+ left++;
2196
+ right--;
2197
+ }
2198
+ return true;
2199
+ }
2200
+ function isAnagram(str1, str2) {
2201
+ const clean = (s) => s.replace(/\s/g, "").toLowerCase().split("").sort().join("");
2202
+ return clean(str1) === clean(str2);
2203
+ }
2204
+ function similarity(a, b) {
2205
+ if (a === b) return 1;
2206
+ if (a.length < 2 || b.length < 2) return 0;
2207
+ const bigrams = /* @__PURE__ */ new Map();
2208
+ for (let i = 0; i < a.length - 1; i++) {
2209
+ const bg = a.slice(i, i + 2);
2210
+ bigrams.set(bg, (bigrams.get(bg) ?? 0) + 1);
2211
+ }
2212
+ let intersection2 = 0;
2213
+ for (let i = 0; i < b.length - 1; i++) {
2214
+ const bg = b.slice(i, i + 2);
2215
+ const count = bigrams.get(bg) ?? 0;
2216
+ if (count > 0) {
2217
+ bigrams.set(bg, count - 1);
2218
+ intersection2++;
2219
+ }
2220
+ }
2221
+ return 2 * intersection2 / (a.length + b.length - 2);
2222
+ }
2223
+ function dedent(str) {
2224
+ const lines = str.split("\n");
2225
+ if (lines.length === 0) return str;
2226
+ const indent = lines.reduce((min, line) => {
2227
+ if (line.trim().length === 0) return min;
2228
+ const leading = line.match(/^[ \t]*/)?.[0]?.length ?? 0;
2229
+ return min === null ? leading : Math.min(min, leading);
2230
+ }, null);
2231
+ if (indent === null || indent === 0) return str;
2232
+ return lines.map((line) => line.slice(indent)).join("\n");
2233
+ }
2234
+ function wordCount(str) {
2235
+ const match = str.match(/[a-zA-Z0-9]+(?:['\u2019][a-zA-Z]+)?/g);
2236
+ return match ? match.length : 0;
2237
+ }
2238
+ function swapCase(str) {
2239
+ let result = "";
2240
+ for (let i = 0; i < str.length; i++) {
2241
+ const ch = str[i];
2242
+ if (ch >= "a" && ch <= "z") {
2243
+ result += ch.toUpperCase();
2244
+ } else if (ch >= "A" && ch <= "Z") {
2245
+ result += ch.toLowerCase();
2246
+ } else {
2247
+ result += ch;
2248
+ }
2249
+ }
2250
+ return result;
2251
+ }
2252
+ function toCobolCase(str) {
2253
+ const words2 = splitWords(str);
2254
+ return words2.map((w) => w.toUpperCase()).join("_");
2255
+ }
2256
+ function charCount(str) {
2257
+ const result = {};
2258
+ for (let i = 0; i < str.length; i++) {
2259
+ const ch = str[i];
2260
+ result[ch] = (result[ch] ?? 0) + 1;
2261
+ }
2262
+ return result;
2263
+ }
2264
+
2265
+ // src/async/queue.ts
2266
+ var Queue = class {
2267
+ _tasks = [];
2268
+ _running = 0;
2269
+ _paused = false;
2270
+ _idleResolve = null;
2271
+ _maxConcurrency;
2272
+ constructor(options) {
2273
+ this._maxConcurrency = options?.concurrency ?? 1;
2274
+ if (this._maxConcurrency < 1) this._maxConcurrency = 1;
2275
+ }
2276
+ get pending() {
2277
+ return this._tasks.length;
2278
+ }
2279
+ get running() {
2280
+ return this._running;
2281
+ }
2282
+ add(task, options) {
2283
+ return new Promise((resolve2, reject) => {
2284
+ this._tasks.push({
2285
+ priority: options?.priority ?? 0,
2286
+ task,
2287
+ resolve: resolve2,
2288
+ reject
2289
+ });
2290
+ this._tasks.sort((a, b) => b.priority - a.priority);
2291
+ this._process();
2292
+ });
2293
+ }
2294
+ pause() {
2295
+ this._paused = true;
2296
+ }
2297
+ resume() {
2298
+ this._paused = false;
2299
+ this._process();
2300
+ }
2301
+ clear() {
2302
+ const err = new Error("Queue cleared");
2303
+ for (const t of this._tasks) t.reject(err);
2304
+ this._tasks = [];
2305
+ }
2306
+ onIdle() {
2307
+ if (this._running === 0 && this._tasks.length === 0) return Promise.resolve();
2308
+ return new Promise((resolve2) => {
2309
+ this._idleResolve = resolve2;
2310
+ });
2311
+ }
2312
+ _process() {
2313
+ if (this._paused) return;
2314
+ while (this._running < this._maxConcurrency && this._tasks.length > 0) {
2315
+ const item = this._tasks.shift();
2316
+ this._running++;
2317
+ item.task().then((result) => item.resolve(result)).catch((err) => item.reject(err)).finally(() => {
2318
+ this._running--;
2319
+ this._process();
2320
+ if (this._running === 0 && this._tasks.length === 0 && this._idleResolve) {
2321
+ this._idleResolve();
2322
+ this._idleResolve = null;
2323
+ }
2324
+ });
2325
+ }
2326
+ }
2327
+ };
2328
+
2329
+ // src/async/semaphore.ts
2330
+ var Semaphore = class {
2331
+ _available;
2332
+ _waiting = [];
2333
+ constructor(concurrency) {
2334
+ if (concurrency < 1) throw new RangeError("Semaphore concurrency must be >= 1");
2335
+ this._available = concurrency;
2336
+ }
2337
+ get available() {
2338
+ return this._available;
2339
+ }
2340
+ acquire() {
2341
+ if (this._available > 0) {
2342
+ this._available--;
2343
+ return Promise.resolve(this._release.bind(this));
2344
+ }
2345
+ return new Promise((resolve2) => {
2346
+ this._waiting.push(() => {
2347
+ this._available--;
2348
+ resolve2(this._release.bind(this));
2349
+ });
2350
+ });
2351
+ }
2352
+ async use(fn) {
2353
+ const release = await this.acquire();
2354
+ try {
2355
+ return await fn();
2356
+ } finally {
2357
+ release();
2358
+ }
2359
+ }
2360
+ _release() {
2361
+ this._available++;
2362
+ if (this._waiting.length > 0) {
2363
+ const next = this._waiting.shift();
2364
+ if (next) next();
2365
+ }
2366
+ }
2367
+ };
2368
+
2369
+ // src/async/memoize.ts
2370
+ function memoizeAsync(fn, options) {
2371
+ const {
2372
+ ttl = 6e4,
2373
+ staleWhileRevalidate = false,
2374
+ maxSize = 100,
2375
+ resolver = (...args) => JSON.stringify(args)
2376
+ } = options ?? {};
2377
+ const cache = /* @__PURE__ */ new Map();
2378
+ const memoized = (async (...args) => {
2379
+ const key = resolver(...args);
2380
+ const now = Date.now();
2381
+ const entry = cache.get(key);
2382
+ if (entry && now - entry.timestamp < ttl) {
2383
+ return entry.value;
2384
+ }
2385
+ if (entry && staleWhileRevalidate && now - entry.timestamp >= ttl) {
2386
+ if (entry.promise) {
2387
+ return entry.value;
2388
+ }
2389
+ entry.promise = fn(...args).then((result2) => {
2390
+ entry.value = result2;
2391
+ entry.timestamp = now;
2392
+ entry.promise = void 0;
2393
+ return result2;
2394
+ }).catch((err) => {
2395
+ entry.promise = void 0;
2396
+ throw err;
2397
+ });
2398
+ return entry.value;
2399
+ }
2400
+ const result = await fn(...args);
2401
+ cache.set(key, { value: result, timestamp: now });
2402
+ if (cache.size > maxSize) {
2403
+ const firstKey = cache.keys().next().value;
2404
+ if (firstKey !== void 0) cache.delete(firstKey);
2405
+ }
2406
+ return result;
2407
+ });
2408
+ memoized.cache = cache;
2409
+ memoized.clear = () => cache.clear();
2410
+ return memoized;
2411
+ }
2412
+
2413
+ // src/async/ratelimit.ts
2414
+ var RateLimiter = class {
2415
+ _maxRequests;
2416
+ _perWindow;
2417
+ _timestamps = [];
2418
+ constructor(options) {
2419
+ if (options.maxRequests < 1) throw new RangeError("maxRequests must be >= 1");
2420
+ if (options.perWindow < 1) throw new RangeError("perWindow must be >= 1");
2421
+ this._maxRequests = options.maxRequests;
2422
+ this._perWindow = options.perWindow;
2423
+ }
2424
+ _prune() {
2425
+ const now = Date.now();
2426
+ const cutoff = now - this._perWindow;
2427
+ while (this._timestamps.length > 0) {
2428
+ const ts = this._timestamps[0];
2429
+ if (ts === void 0 || ts > cutoff) break;
2430
+ this._timestamps.shift();
2431
+ }
2432
+ }
2433
+ /**
2434
+ * Check if a request is allowed without waiting.
2435
+ */
2436
+ tryAcquire() {
2437
+ this._prune();
2438
+ if (this._timestamps.length < this._maxRequests) {
2439
+ this._timestamps.push(Date.now());
2440
+ return true;
2441
+ }
2442
+ return false;
2443
+ }
2444
+ /**
2445
+ * Wait until a request is allowed.
2446
+ */
2447
+ async acquire() {
2448
+ while (true) {
2449
+ this._prune();
2450
+ if (this._timestamps.length < this._maxRequests) {
2451
+ this._timestamps.push(Date.now());
2452
+ return;
2453
+ }
2454
+ const oldest = this._timestamps[0] ?? Date.now();
2455
+ const waitMs = oldest + this._perWindow - Date.now();
2456
+ if (waitMs > 0) {
2457
+ await new Promise((resolve2) => setTimeout(resolve2, waitMs));
2458
+ }
2459
+ }
2460
+ }
2461
+ /**
2462
+ * Current number of pending requests in the window.
2463
+ */
2464
+ get pending() {
2465
+ this._prune();
2466
+ return this._timestamps.length;
2467
+ }
2468
+ };
2469
+
2470
+ // src/async/mutex.ts
2471
+ var Mutex = class {
2472
+ _locked = false;
2473
+ _waiting = [];
2474
+ /**
2475
+ * Acquire the lock. Returns a release function to be called when done.
2476
+ */
2477
+ acquire() {
2478
+ if (!this._locked) {
2479
+ this._locked = true;
2480
+ return Promise.resolve(this._release.bind(this));
2481
+ }
2482
+ return new Promise((resolve2) => {
2483
+ this._waiting.push(() => {
2484
+ resolve2(this._release.bind(this));
2485
+ });
2486
+ });
2487
+ }
2488
+ /**
2489
+ * Run a function with the lock held and automatically release it.
2490
+ */
2491
+ async use(fn) {
2492
+ const release = await this.acquire();
2493
+ try {
2494
+ return await fn();
2495
+ } finally {
2496
+ release();
2497
+ }
2498
+ }
2499
+ /**
2500
+ * Whether the mutex is currently locked.
2501
+ */
2502
+ get locked() {
2503
+ return this._locked;
2504
+ }
2505
+ _release() {
2506
+ if (this._waiting.length > 0) {
2507
+ const next = this._waiting.shift();
2508
+ if (next) next();
2509
+ } else {
2510
+ this._locked = false;
2511
+ }
2512
+ }
2513
+ };
2514
+
2515
+ // src/async/batch.ts
2516
+ async function batch(items, batchSize, fn) {
2517
+ if (batchSize < 1) throw new RangeError("batchSize must be >= 1");
2518
+ const results = [];
2519
+ for (let i = 0; i < items.length; i += batchSize) {
2520
+ const chunk2 = items.slice(i, i + batchSize);
2521
+ const batchResults = await fn(chunk2);
2522
+ results.push(...batchResults);
2523
+ }
2524
+ return results;
2525
+ }
2526
+
2527
+ // src/async/waterfall.ts
2528
+ async function waterfall(tasks, initial) {
2529
+ let result = initial;
2530
+ for (const task of tasks) {
2531
+ result = await task(result);
2532
+ }
2533
+ return result;
2534
+ }
1114
2535
 
1115
2536
  // src/async/index.ts
1116
2537
  function sleep(ms) {
@@ -1208,6 +2629,7 @@ function parseCsv(input, options) {
1208
2629
  return body.map((row) => {
1209
2630
  const record = {};
1210
2631
  for (let i = 0; i < head.length; i++) {
2632
+ if (head[i] === "__proto__" || head[i] === "constructor" || head[i] === "prototype") continue;
1211
2633
  record[head[i]] = row[i] ?? "";
1212
2634
  }
1213
2635
  return record;
@@ -1348,9 +2770,7 @@ function assertType(value, guard, message) {
1348
2770
  function ensureArray(value) {
1349
2771
  return Array.isArray(value) ? value : [value];
1350
2772
  }
1351
- function castArray(value) {
1352
- return ensureArray(value);
1353
- }
2773
+ var castArray = ensureArray;
1354
2774
  function getType2(value) {
1355
2775
  if (value === null) return "null";
1356
2776
  if (value === void 0) return "undefined";
@@ -2182,6 +3602,29 @@ function isNoRekening(value) {
2182
3602
  return true;
2183
3603
  }
2184
3604
 
3605
+ // src/validation/isNoSIM.ts
3606
+ function isNoSIM(value) {
3607
+ const digits = value.replace(/\D/g, "");
3608
+ return digits.length === 12;
3609
+ }
3610
+
3611
+ // src/validation/isPassport.ts
3612
+ function isPassport(value) {
3613
+ return /^[A-Za-z]{2}\d{7}$/.test(value.trim());
3614
+ }
3615
+
3616
+ // src/validation/isNoBPJS.ts
3617
+ function isNoBPJS(value) {
3618
+ const digits = value.replace(/\D/g, "");
3619
+ return digits.length === 13;
3620
+ }
3621
+
3622
+ // src/validation/isNoKK.ts
3623
+ function isNoKK(value) {
3624
+ const digits = value.replace(/\D/g, "");
3625
+ return digits.length === 16;
3626
+ }
3627
+
2185
3628
  // src/error/createError.ts
2186
3629
  var defaultStatus = {
2187
3630
  "BAD_REQUEST": 400,
@@ -2545,6 +3988,98 @@ function meetsWCAG(hex1, hex2, level) {
2545
3988
  const threshold = level === "AAA" ? 7 : 4.5;
2546
3989
  return ratio >= threshold;
2547
3990
  }
3991
+ function isValidHex(value) {
3992
+ return /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
3993
+ }
3994
+ function hexToHsl(hex) {
3995
+ const rgb = hexToRgb(hex);
3996
+ if (!rgb) return null;
3997
+ const r = rgb.r / 255;
3998
+ const g = rgb.g / 255;
3999
+ const b = rgb.b / 255;
4000
+ const max = Math.max(r, g, b);
4001
+ const min = Math.min(r, g, b);
4002
+ const l = (max + min) / 2;
4003
+ if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) };
4004
+ const d = max - min;
4005
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
4006
+ let h = 0;
4007
+ switch (max) {
4008
+ case r:
4009
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
4010
+ break;
4011
+ case g:
4012
+ h = ((b - r) / d + 2) / 6;
4013
+ break;
4014
+ case b:
4015
+ h = ((r - g) / d + 4) / 6;
4016
+ break;
4017
+ }
4018
+ return {
4019
+ h: Math.round(h * 360),
4020
+ s: Math.round(s * 100),
4021
+ l: Math.round(l * 100)
4022
+ };
4023
+ }
4024
+ function hslToHex(h, s, l) {
4025
+ const hue = h / 360;
4026
+ const sat = s / 100;
4027
+ const lig = l / 100;
4028
+ if (sat === 0) {
4029
+ const val = Math.round(lig * 255);
4030
+ return rgbToHex(val, val, val);
4031
+ }
4032
+ const hue2rgb = (p2, q2, t) => {
4033
+ let tt = t;
4034
+ if (tt < 0) tt += 1;
4035
+ if (tt > 1) tt -= 1;
4036
+ if (tt < 1 / 6) return p2 + (q2 - p2) * 6 * tt;
4037
+ if (tt < 1 / 2) return q2;
4038
+ if (tt < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - tt) * 6;
4039
+ return p2;
4040
+ };
4041
+ const q = lig < 0.5 ? lig * (1 + sat) : lig + sat - lig * sat;
4042
+ const p = 2 * lig - q;
4043
+ return rgbToHex(
4044
+ Math.round(hue2rgb(p, q, hue + 1 / 3) * 255),
4045
+ Math.round(hue2rgb(p, q, hue) * 255),
4046
+ Math.round(hue2rgb(p, q, hue - 1 / 3) * 255)
4047
+ );
4048
+ }
4049
+ function mix(color1, color2, weight = 0.5) {
4050
+ const rgb1 = hexToRgb(color1);
4051
+ const rgb2 = hexToRgb(color2);
4052
+ if (!rgb1 || !rgb2) return color1;
4053
+ const w = Math.max(0, Math.min(1, weight));
4054
+ const lerp2 = (a, b) => Math.floor(a + (b - a) * w);
4055
+ return rgbToHex(lerp2(rgb1.r, rgb2.r), lerp2(rgb1.g, rgb2.g), lerp2(rgb1.b, rgb2.b));
4056
+ }
4057
+ function randomColor() {
4058
+ const r = Math.floor(Math.random() * 256);
4059
+ const g = Math.floor(Math.random() * 256);
4060
+ const b = Math.floor(Math.random() * 256);
4061
+ return rgbToHex(r, g, b);
4062
+ }
4063
+ function isLight(hex) {
4064
+ const rgb = hexToRgb(hex);
4065
+ if (!rgb) return false;
4066
+ return (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255 > 0.5;
4067
+ }
4068
+ function isDark(hex) {
4069
+ return !isLight(hex);
4070
+ }
4071
+ function complementary(hex) {
4072
+ const hsl = hexToHsl(hex);
4073
+ if (!hsl) return hex;
4074
+ return hslToHex((hsl.h + 180) % 360, hsl.s, hsl.l);
4075
+ }
4076
+ function alpha(hex, opacity) {
4077
+ const rgb = hexToRgb(hex);
4078
+ if (!rgb) return hex;
4079
+ const a = Math.max(0, Math.min(1, opacity));
4080
+ const alphaHex = Math.round(a * 255).toString(16).padStart(2, "0");
4081
+ return rgbToHex(rgb.r, rgb.g, rgb.b) + alphaHex;
4082
+ }
2548
4083
  export {
2549
4084
  DivisionByZeroError,
2550
4085
  InvalidDateError,
@@ -2552,6 +4087,13 @@ export {
2552
4087
  KNOWN_MAPPINGS,
2553
4088
  Logger,
2554
4089
  MultiError,
4090
+ Mutex,
4091
+ Queue,
4092
+ RateLimiter,
4093
+ Semaphore,
4094
+ TIMEZONE_WIB,
4095
+ TIMEZONE_WIT,
4096
+ TIMEZONE_WITA,
2555
4097
  TypedError,
2556
4098
  add,
2557
4099
  addBusinessDays,
@@ -2559,6 +4101,7 @@ export {
2559
4101
  addMonths,
2560
4102
  addYears,
2561
4103
  allSettledMap,
4104
+ alpha,
2562
4105
  analyzeUsage,
2563
4106
  approxEqual,
2564
4107
  assertDefined,
@@ -2567,18 +4110,26 @@ export {
2567
4110
  base64Decode,
2568
4111
  base64Encode,
2569
4112
  basename,
4113
+ batch,
2570
4114
  calculateAge,
2571
4115
  camelCase,
2572
4116
  capitalize,
2573
4117
  castArray,
2574
4118
  ceil,
4119
+ charCount,
2575
4120
  checksum,
2576
4121
  chunk,
2577
4122
  clamp,
2578
4123
  collectErrors,
4124
+ combinations,
4125
+ compact,
4126
+ complementary,
4127
+ compose,
2579
4128
  consoleTransport,
2580
4129
  constantTimeEqual,
2581
4130
  contrastRatio,
4131
+ correlation,
4132
+ countBy,
2582
4133
  countOccurrences,
2583
4134
  createBufferedTransport,
2584
4135
  createConsoleTransport,
@@ -2587,12 +4138,21 @@ export {
2587
4138
  createJsonTransport,
2588
4139
  darken,
2589
4140
  dateDiff,
4141
+ dayOfYear,
4142
+ daysInMonth,
2590
4143
  debounce,
4144
+ dedent,
2591
4145
  deepClone,
4146
+ deepEqual,
4147
+ deepGet,
2592
4148
  deepMerge,
4149
+ deepSet,
2593
4150
  deferred,
4151
+ difference,
2594
4152
  dirname,
2595
4153
  div,
4154
+ drop,
4155
+ dropRight,
2596
4156
  endOfDay,
2597
4157
  endOfMonth,
2598
4158
  endOfYear,
@@ -2602,63 +4162,125 @@ export {
2602
4162
  envInt,
2603
4163
  escapeHtml,
2604
4164
  extname,
4165
+ factorial,
4166
+ findIndex,
4167
+ findLast,
2605
4168
  first,
2606
4169
  flatten,
2607
4170
  floor,
2608
4171
  format,
4172
+ formatBytes,
4173
+ formatCurrency,
2609
4174
  formatDate,
4175
+ formatDuration,
4176
+ formatInTimezone,
4177
+ formatRupiah,
4178
+ fuzzyMatch,
4179
+ gcd,
2610
4180
  generateOTP,
2611
4181
  generateReport,
2612
4182
  generateToken,
4183
+ geometricMean,
4184
+ getIndonesianHolidayNames,
2613
4185
  getType2 as getType,
2614
4186
  groupBy,
2615
4187
  hash,
4188
+ hexToHsl,
2616
4189
  hexToRgb,
4190
+ hslToHex,
2617
4191
  identity,
2618
4192
  inRange,
4193
+ intersection,
2619
4194
  isAbsolute,
2620
4195
  isAfter,
4196
+ isAnagram,
2621
4197
  isArray,
2622
4198
  isBefore,
2623
4199
  isBetween,
2624
4200
  isBoolean,
2625
4201
  isBusinessDay,
4202
+ isDark,
2626
4203
  isDate,
2627
4204
  isEmail,
2628
4205
  isEmpty,
4206
+ isEven,
2629
4207
  isFunction,
4208
+ isFuture,
4209
+ isHolidayIndonesia,
2630
4210
  isKodepos,
2631
4211
  isLeapYear,
4212
+ isLight,
2632
4213
  isMap,
2633
4214
  isNIK,
2634
4215
  isNPWP,
2635
4216
  isNil,
4217
+ isNoBPJS,
4218
+ isNoKK,
2636
4219
  isNoRekening,
4220
+ isNoSIM,
2637
4221
  isNull,
2638
4222
  isNumber,
2639
4223
  isObject,
4224
+ isOdd,
4225
+ isPalindrome,
4226
+ isPassport,
4227
+ isPast,
2640
4228
  isPhone,
2641
4229
  isPlatNomor,
4230
+ isPrime,
2642
4231
  isPromise,
2643
4232
  isRegExp,
4233
+ isSameDay,
2644
4234
  isSet,
2645
4235
  isString,
4236
+ isToday,
4237
+ isTomorrow,
2646
4238
  isTypedError,
2647
4239
  isURL,
2648
4240
  isUndefined,
4241
+ isValidHex,
2649
4242
  isWeekend,
4243
+ isYesterday,
2650
4244
  join,
2651
4245
  kebabCase,
2652
4246
  keyBy,
2653
4247
  last,
4248
+ lastFriday,
4249
+ lastMonday,
4250
+ lastSaturday,
4251
+ lastSunday,
4252
+ lastThursday,
4253
+ lastTuesday,
4254
+ lastWednesday,
4255
+ lcm,
4256
+ lerp,
4257
+ levenshtein,
2654
4258
  lighten,
2655
4259
  logger,
4260
+ mapRange,
4261
+ maskString,
4262
+ maxBy,
4263
+ maxDate,
4264
+ median,
2656
4265
  meetsWCAG,
2657
4266
  memoize,
4267
+ memoizeAsync,
4268
+ minBy,
4269
+ minDate,
4270
+ mix,
4271
+ mode,
2658
4272
  mul,
2659
4273
  nanoid,
4274
+ nextFriday,
4275
+ nextMonday,
4276
+ nextSaturday,
4277
+ nextSunday,
4278
+ nextThursday,
4279
+ nextTuesday,
4280
+ nextWednesday,
2660
4281
  noop,
2661
4282
  normalize,
4283
+ nth,
2662
4284
  omit,
2663
4285
  once,
2664
4286
  orderBy,
@@ -2669,14 +4291,26 @@ export {
2669
4291
  parse,
2670
4292
  parseCsv,
2671
4293
  parseDate,
4294
+ parseDuration,
2672
4295
  parseNIK,
4296
+ partition,
2673
4297
  pascalCase,
4298
+ percentageOf,
4299
+ percentile,
4300
+ permutations,
2674
4301
  pick,
4302
+ pipe,
2675
4303
  pipeline,
2676
4304
  pluck,
4305
+ pluralize,
4306
+ quarter,
2677
4307
  raceWithTimeout,
4308
+ randomBoolean,
4309
+ randomColor,
2678
4310
  randomHex,
2679
4311
  randomInt,
4312
+ randomString,
4313
+ range,
2680
4314
  relative,
2681
4315
  resolve,
2682
4316
  retry,
@@ -2687,31 +4321,58 @@ export {
2687
4321
  safeJsonParse,
2688
4322
  sample,
2689
4323
  sampleSize,
4324
+ sampleStddev,
2690
4325
  scanProject,
2691
4326
  shuffle,
4327
+ similarity,
2692
4328
  simpleHash,
2693
4329
  sleep,
4330
+ slidingWindows,
2694
4331
  slugify,
2695
4332
  snakeCase,
2696
4333
  sortBy,
2697
4334
  startOfDay,
2698
4335
  startOfMonth,
2699
4336
  startOfYear,
4337
+ stddev,
2700
4338
  stringifyCsv,
4339
+ stripHtml,
2701
4340
  sub,
2702
4341
  sum,
4342
+ sumBy,
4343
+ swapCase,
4344
+ take,
4345
+ takeRight,
2703
4346
  template,
4347
+ terbilang,
2704
4348
  throttle,
4349
+ timeAgo,
4350
+ timeRemaining,
2705
4351
  timeout,
4352
+ toCobolCase,
4353
+ toDegrees,
4354
+ toRadians,
4355
+ toTimezone,
4356
+ topoSort,
2706
4357
  trim,
2707
4358
  trimEnd,
2708
4359
  trimStart,
2709
4360
  truncate,
4361
+ truncateWords,
4362
+ tumblingWindows,
2710
4363
  unescapeHtml,
4364
+ union,
2711
4365
  uniq,
2712
4366
  uniqueBy,
4367
+ unzip,
2713
4368
  uuid,
4369
+ waterfall,
4370
+ weekOfYear,
4371
+ weightedAverage,
4372
+ without,
4373
+ wordCount,
2714
4374
  words,
2715
- xorCipher
4375
+ xorCipher,
4376
+ zip
2716
4377
  };
2717
4378
  //# sourceMappingURL=index.js.map