foreslash 0.3.2 → 0.3.4
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/CHANGELOG.md +26 -0
- package/lib/index.cmn.cjs +305 -4
- package/lib/index.d.ts +269 -26
- package/lib/index.mjs +298 -5
- package/lib/index.umd.js +305 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 0.3.4 - 2025-11-
|
|
4
|
+
|
|
5
|
+
Unstable version
|
|
6
|
+
|
|
7
|
+
- Feat 🥥 Functions added: `omit` `pick`
|
|
8
|
+
- Other fixes and improvements
|
|
9
|
+
|
|
10
|
+
不稳定版本
|
|
11
|
+
|
|
12
|
+
- 功能 🥥 添加函数: `omit` `pick`
|
|
13
|
+
- 其他修复与优化
|
|
14
|
+
|
|
15
|
+
## Version 0.3.3 - 2025-11-05
|
|
16
|
+
|
|
17
|
+
Unstable version
|
|
18
|
+
|
|
19
|
+
- Feat 🥥 Functions added: `lerp` `scientificNotation` `castArray` `romanNumerals` `randomDistribution` and so forth
|
|
20
|
+
- Fix 🥕 Document: Added version tags to `memo` and description to several methods
|
|
21
|
+
- Other fixes and improvements
|
|
22
|
+
|
|
23
|
+
不稳定版本
|
|
24
|
+
|
|
25
|
+
- 功能 🥥 添加函数: `lerp` `scientificNotation` `castArray` `randomDistribution` 等
|
|
26
|
+
- 修复 🥕 文档: 补充 `memo` 的版本标签和部分方法的说明
|
|
27
|
+
- 其他修复与优化
|
|
28
|
+
|
|
3
29
|
## Version 0.3.2 - 2025-09-23
|
|
4
30
|
|
|
5
31
|
Unstable version
|
package/lib/index.cmn.cjs
CHANGED
|
@@ -45,6 +45,10 @@ function cartesianProduct(...arrList) {
|
|
|
45
45
|
return res;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function castArray(value) {
|
|
49
|
+
return Array.isArray(value) ? value.slice() : [value];
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
function chunk(array, size = 2) {
|
|
49
53
|
const res = [];
|
|
50
54
|
if (size < 1 || isNaN(size))
|
|
@@ -609,6 +613,201 @@ function format(num, options) {
|
|
|
609
613
|
return sign + integer;
|
|
610
614
|
}
|
|
611
615
|
|
|
616
|
+
function lerp(val1, val2, t) {
|
|
617
|
+
if (isNumber(val1)) {
|
|
618
|
+
if (!isNumber(val2))
|
|
619
|
+
throw new Error('Invalid val2 parameter: val2 should be a number');
|
|
620
|
+
return _lerp(val1, val2, t);
|
|
621
|
+
}
|
|
622
|
+
else if (isArray(val1)) {
|
|
623
|
+
if (!isArray(val2))
|
|
624
|
+
throw new Error('Invalid val2 parameter: val2 should be an Array');
|
|
625
|
+
if (val1.length !== val2.length) {
|
|
626
|
+
throw new Error(`Invalid val2 parameter: the length of val2 (${val2.length}) should be consistent with val1 (${val1.length})`);
|
|
627
|
+
}
|
|
628
|
+
if (val1.length === 0)
|
|
629
|
+
return [];
|
|
630
|
+
if (isNumber(val1[0])) {
|
|
631
|
+
if (!isNumber(val2[0]))
|
|
632
|
+
throw new Error('Invalid val2 parameter: val2 should be an Array<number>');
|
|
633
|
+
return val1.map((v1, index) => _lerp(v1, val2[index], t));
|
|
634
|
+
}
|
|
635
|
+
else if (isArray(val1[0])) {
|
|
636
|
+
const res = [];
|
|
637
|
+
for (let i = 0; i < val1.length; i++) {
|
|
638
|
+
const arr1 = val1[i];
|
|
639
|
+
const arr2 = val2[i];
|
|
640
|
+
if (arr1.length !== arr2.length) {
|
|
641
|
+
throw new Error(`Invalid val2 parameter: The length of array at index ${i} in val2 (${arr2.length}) must match the length of the corresponding array in val1 (${arr1.length})`);
|
|
642
|
+
}
|
|
643
|
+
res.push(arr1.map((v1, index) => _lerp(v1, arr2[index], t)));
|
|
644
|
+
}
|
|
645
|
+
return res;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
throw new Error('Invalid val1 parameter: val1 should be a number or Array');
|
|
649
|
+
}
|
|
650
|
+
function _lerp(val1, val2, t) {
|
|
651
|
+
return val1 + (val2 - val1) * t;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
function romanNumerals(num, options) {
|
|
655
|
+
const str = decimalNotation(num);
|
|
656
|
+
if (/NaN|Inf/.test(str))
|
|
657
|
+
return str;
|
|
658
|
+
const type = (options || {}).type || 'unicode';
|
|
659
|
+
const thousand = (options || {}).thousand || 'normal';
|
|
660
|
+
const forceSplitThousand = thousand === 'strict';
|
|
661
|
+
const integer = str.split('.')[0].replace('-', '');
|
|
662
|
+
if (integer === '0') {
|
|
663
|
+
const zero = (options || {}).zero || '0';
|
|
664
|
+
if (type === 'json')
|
|
665
|
+
return `["${zero}"]`;
|
|
666
|
+
else
|
|
667
|
+
return zero;
|
|
668
|
+
}
|
|
669
|
+
if (integer === '1') {
|
|
670
|
+
const one = (options || {}).one || 'I';
|
|
671
|
+
if (type === 'json')
|
|
672
|
+
return `["${one}"]`;
|
|
673
|
+
else
|
|
674
|
+
return one;
|
|
675
|
+
}
|
|
676
|
+
const chunks = chunk(Array.from(integer).reverse(), 3);
|
|
677
|
+
const romanChunks = [];
|
|
678
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
679
|
+
const val = Number(chunks[i].reverse().join(''));
|
|
680
|
+
if (i === chunks.length - 2 && !forceSplitThousand && Number(chunks[i + 1]) < 4) {
|
|
681
|
+
romanChunks.push(number2roman(val + Number(chunks[i + 1]) * 1000));
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
romanChunks.push(number2roman(val));
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
switch (type) {
|
|
689
|
+
case 'js':
|
|
690
|
+
return romanChunks
|
|
691
|
+
.map((str, index) => str
|
|
692
|
+
.split('')
|
|
693
|
+
.map((s) => s + '\\\\u0305'.repeat(index))
|
|
694
|
+
.join(''))
|
|
695
|
+
.reverse()
|
|
696
|
+
.join('');
|
|
697
|
+
case 'html':
|
|
698
|
+
return romanChunks
|
|
699
|
+
.map((str, index) => str
|
|
700
|
+
.split('')
|
|
701
|
+
.map((s) => s + '̅'.repeat(index))
|
|
702
|
+
.join(''))
|
|
703
|
+
.reverse()
|
|
704
|
+
.join('');
|
|
705
|
+
case 'json':
|
|
706
|
+
return `[${romanChunks.map((str) => `"${str}"`).join(', ')}]`;
|
|
707
|
+
case 'unicode':
|
|
708
|
+
default:
|
|
709
|
+
return romanChunks
|
|
710
|
+
.map((str, index) => str
|
|
711
|
+
.split('')
|
|
712
|
+
.map((s) => s + '\u0305'.repeat(index))
|
|
713
|
+
.join(''))
|
|
714
|
+
.reverse()
|
|
715
|
+
.join('');
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
function number2roman(num) {
|
|
719
|
+
const symbols = [
|
|
720
|
+
[1000, 'M'],
|
|
721
|
+
[900, 'CM'],
|
|
722
|
+
[500, 'D'],
|
|
723
|
+
[400, 'CD'],
|
|
724
|
+
[100, 'C'],
|
|
725
|
+
[90, 'XC'],
|
|
726
|
+
[50, 'L'],
|
|
727
|
+
[40, 'XL'],
|
|
728
|
+
[10, 'X'],
|
|
729
|
+
[9, 'IX'],
|
|
730
|
+
[5, 'V'],
|
|
731
|
+
[4, 'IV'],
|
|
732
|
+
[1, 'I'],
|
|
733
|
+
];
|
|
734
|
+
let roman = '';
|
|
735
|
+
for (const [val, str] of symbols) {
|
|
736
|
+
while (num >= val) {
|
|
737
|
+
num -= val;
|
|
738
|
+
roman += str;
|
|
739
|
+
}
|
|
740
|
+
if (num == 0)
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
return roman;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
function scientificNotation(num, options) {
|
|
747
|
+
const str = decimalNotation(num);
|
|
748
|
+
if (/NaN|Inf/.test(str))
|
|
749
|
+
return str;
|
|
750
|
+
const type = (options || {}).type || 'unicode';
|
|
751
|
+
const _precision = (options || {}).precision;
|
|
752
|
+
const precision = isNumber(_precision) ? clamp(_precision, 0, Infinity) : null;
|
|
753
|
+
const round = (options || {}).round || 'round';
|
|
754
|
+
let [integer, fractional] = str.split('.');
|
|
755
|
+
let sign = '';
|
|
756
|
+
if (/^-/.test(integer)) {
|
|
757
|
+
integer = integer.substring(1);
|
|
758
|
+
sign = '-';
|
|
759
|
+
}
|
|
760
|
+
fractional = fractional !== null && fractional !== void 0 ? fractional : '';
|
|
761
|
+
let exp = 0;
|
|
762
|
+
let n = '';
|
|
763
|
+
if (integer === '0') {
|
|
764
|
+
exp = /^(0+)/.test(fractional) ? -(fractional.match(/^(0+)/)[0].length + 1) : -1;
|
|
765
|
+
[integer, fractional] = [fractional.slice(-exp - 1, -exp), fractional.slice(-exp)];
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
exp = integer.length - 1;
|
|
769
|
+
[integer, fractional] = [integer.slice(0, 1), integer.slice(1) + fractional];
|
|
770
|
+
}
|
|
771
|
+
if (isNumber(precision)) {
|
|
772
|
+
if (fractional.length > precision) {
|
|
773
|
+
const roundMap = { round: roundBase, banker: roundBank, floor: roundFloor, ceil: roundCeil };
|
|
774
|
+
[integer, fractional] = (roundMap[round] || roundBase)(integer, fractional, precision, !!sign);
|
|
775
|
+
}
|
|
776
|
+
else if (fractional.length < precision) {
|
|
777
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
fractional = fractional.replace(/0+$/, '');
|
|
782
|
+
}
|
|
783
|
+
if ((precision === null && fractional) || (isNumber(precision) && precision > 0)) {
|
|
784
|
+
n = sign + integer + '.' + fractional;
|
|
785
|
+
}
|
|
786
|
+
else
|
|
787
|
+
n = sign + integer;
|
|
788
|
+
switch (type) {
|
|
789
|
+
case 'exp':
|
|
790
|
+
return `${n}e${exp < 0 ? '' : '+'}${exp}`;
|
|
791
|
+
case 'js':
|
|
792
|
+
return `${n}*10**${exp}`;
|
|
793
|
+
case 'code':
|
|
794
|
+
return `${n}*10^${exp}`;
|
|
795
|
+
case 'html':
|
|
796
|
+
return `${n}×10<sup>${exp}</sup>`;
|
|
797
|
+
case 'json':
|
|
798
|
+
return `{"number":"${n}","exp":${exp}}`;
|
|
799
|
+
case 'unicode':
|
|
800
|
+
default:
|
|
801
|
+
return `${n}×10${transferNumberToUniCode(String(exp))}`;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
function transferNumberToUniCode(n) {
|
|
805
|
+
const strMap = Object.assign(Object.assign({}, Array.from('⁰¹²³⁴⁵⁶⁷⁸⁹')), { '-': '⁻', '+': '⁺' });
|
|
806
|
+
return Array.from(n)
|
|
807
|
+
.map((s) => (strMap[s] ? strMap[s] : s))
|
|
808
|
+
.join('');
|
|
809
|
+
}
|
|
810
|
+
|
|
612
811
|
function parallel(args, fn, options) {
|
|
613
812
|
return __awaiter(this, void 0, void 0, function* () {
|
|
614
813
|
if (!args.length)
|
|
@@ -1240,6 +1439,54 @@ function randomChoice(arr, weights) {
|
|
|
1240
1439
|
return arr[index];
|
|
1241
1440
|
}
|
|
1242
1441
|
|
|
1442
|
+
function randomDistribution(p, options) {
|
|
1443
|
+
const threshold = (options === null || options === void 0 ? void 0 : options.threshold) ? Math.max(options.threshold, Number.MIN_VALUE * 2) : 5e-6;
|
|
1444
|
+
const C = getInitP(p, threshold);
|
|
1445
|
+
let current = C;
|
|
1446
|
+
return function getRandomDistribution() {
|
|
1447
|
+
const res = Math.random() < current;
|
|
1448
|
+
if (res)
|
|
1449
|
+
current = C;
|
|
1450
|
+
else
|
|
1451
|
+
current += C;
|
|
1452
|
+
return res;
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
function getInitP(targetP, threshold = 5e-6) {
|
|
1456
|
+
if (targetP <= 0)
|
|
1457
|
+
return 0;
|
|
1458
|
+
if (targetP >= 1)
|
|
1459
|
+
return 1;
|
|
1460
|
+
let [down, up] = [0, 1];
|
|
1461
|
+
let mid = 1;
|
|
1462
|
+
let tempP = 1;
|
|
1463
|
+
let tempPLast = 1;
|
|
1464
|
+
let step = 64;
|
|
1465
|
+
while (step-- > 0) {
|
|
1466
|
+
mid = (down + up) / 2;
|
|
1467
|
+
tempP = getRealPFromInitP(mid);
|
|
1468
|
+
if (Math.abs(tempPLast - tempP) < threshold)
|
|
1469
|
+
break;
|
|
1470
|
+
if (tempP > targetP)
|
|
1471
|
+
up = mid;
|
|
1472
|
+
else
|
|
1473
|
+
down = mid;
|
|
1474
|
+
}
|
|
1475
|
+
return mid;
|
|
1476
|
+
}
|
|
1477
|
+
function getRealPFromInitP(initP) {
|
|
1478
|
+
let sum = 0;
|
|
1479
|
+
let prod = 0;
|
|
1480
|
+
let cur = 0;
|
|
1481
|
+
let max = Math.ceil(1 / initP);
|
|
1482
|
+
for (let n = 1; n <= max; n++) {
|
|
1483
|
+
cur = Math.min(1, n * initP) * (1 - prod);
|
|
1484
|
+
prod += cur;
|
|
1485
|
+
sum += n * cur;
|
|
1486
|
+
}
|
|
1487
|
+
return 1 / sum;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1243
1490
|
const radix32 = '0123456789abcdefghijklmnopqrstuv';
|
|
1244
1491
|
const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
1245
1492
|
const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
|
|
@@ -1866,22 +2113,22 @@ function _deepClone(obj, map, options) {
|
|
|
1866
2113
|
if (isFormData(obj))
|
|
1867
2114
|
return _cloneFormData(obj, map, _deepClone, options);
|
|
1868
2115
|
let res;
|
|
1869
|
-
if (obj
|
|
2116
|
+
if (isDate(obj)) {
|
|
1870
2117
|
res = new Date(obj.valueOf());
|
|
1871
2118
|
map.set(obj, res);
|
|
1872
2119
|
}
|
|
1873
|
-
else if (obj
|
|
2120
|
+
else if (isRegExp(obj)) {
|
|
1874
2121
|
res = new RegExp(obj.source, obj.flags);
|
|
1875
2122
|
map.set(obj, res);
|
|
1876
2123
|
}
|
|
1877
|
-
else if (obj
|
|
2124
|
+
else if (isArrayBuffer(obj)) {
|
|
1878
2125
|
res = _cloneArrayBuffer(obj, map);
|
|
1879
2126
|
}
|
|
1880
2127
|
else if (isTypedArray(obj)) {
|
|
1881
2128
|
res = new obj.constructor(_cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.length);
|
|
1882
2129
|
map.set(obj, res);
|
|
1883
2130
|
}
|
|
1884
|
-
else if (obj
|
|
2131
|
+
else if (isDataView(obj)) {
|
|
1885
2132
|
res = new DataView(map.has(obj.buffer) ? map.get(obj.buffer) : _cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.byteLength);
|
|
1886
2133
|
map.set(obj, res);
|
|
1887
2134
|
}
|
|
@@ -2242,6 +2489,27 @@ function not(value) {
|
|
|
2242
2489
|
return !Boolean(value);
|
|
2243
2490
|
}
|
|
2244
2491
|
|
|
2492
|
+
function omit(obj, keys) {
|
|
2493
|
+
const res = (Object.getPrototypeOf(obj) ? {} : Object.create(null));
|
|
2494
|
+
const ownKeys = Reflect.ownKeys(obj);
|
|
2495
|
+
if (isFunction(keys)) {
|
|
2496
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2497
|
+
const key = ownKeys[i];
|
|
2498
|
+
if (!keys(obj[key], key, obj))
|
|
2499
|
+
res[key] = obj[key];
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
else {
|
|
2503
|
+
const keysSet = new Set((isArray(keys) ? keys : [keys]).map((k) => (isNumber(k) ? String(k) : k)));
|
|
2504
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2505
|
+
const key = ownKeys[i];
|
|
2506
|
+
if (!keysSet.has(key))
|
|
2507
|
+
res[key] = obj[key];
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
return res;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2245
2513
|
function pass(value) {
|
|
2246
2514
|
return value;
|
|
2247
2515
|
}
|
|
@@ -2252,6 +2520,31 @@ function passWith(fn) {
|
|
|
2252
2520
|
});
|
|
2253
2521
|
}
|
|
2254
2522
|
|
|
2523
|
+
function pick(obj, keys) {
|
|
2524
|
+
const res = (Object.getPrototypeOf(obj) ? {} : Object.create(null));
|
|
2525
|
+
const ownKeys = Reflect.ownKeys(obj);
|
|
2526
|
+
if (isFunction(keys)) {
|
|
2527
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
2528
|
+
const key = ownKeys[i];
|
|
2529
|
+
if (keys(obj[key], key, obj))
|
|
2530
|
+
res[key] = obj[key];
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
else if (isArray(keys)) {
|
|
2534
|
+
const keysSet = new Set(ownKeys);
|
|
2535
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2536
|
+
const key = keys[i];
|
|
2537
|
+
if (keysSet.has(isNumber(key) ? String(key) : key))
|
|
2538
|
+
res[key] = obj[key];
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
else if (isString(keys) || isNumber(keys) || isSymbol(keys)) {
|
|
2542
|
+
if (ownKeys.includes(isNumber(keys) ? String(keys) : keys))
|
|
2543
|
+
res[keys] = obj[keys];
|
|
2544
|
+
}
|
|
2545
|
+
return res;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2255
2548
|
function pipe(...pipeFunc) {
|
|
2256
2549
|
if (pipeFunc.length === 0) {
|
|
2257
2550
|
throw new Error('Invalid pipeFunc parameter: pipeFunc is empty');
|
|
@@ -2289,6 +2582,7 @@ exports.caseConvert = caseConvert;
|
|
|
2289
2582
|
exports.caseKebab = caseKebab;
|
|
2290
2583
|
exports.casePascal = casePascal;
|
|
2291
2584
|
exports.caseSnake = caseSnake;
|
|
2585
|
+
exports.castArray = castArray;
|
|
2292
2586
|
exports.chunk = chunk;
|
|
2293
2587
|
exports.clamp = clamp;
|
|
2294
2588
|
exports.compose = compose;
|
|
@@ -2304,6 +2598,7 @@ exports.format = format;
|
|
|
2304
2598
|
exports.getAcceptableExtByMIME = getAcceptableExtByMIME;
|
|
2305
2599
|
exports.getAcceptableMIMEByExt = getAcceptableMIMEByExt;
|
|
2306
2600
|
exports.getGlobalThis = getGlobalThis;
|
|
2601
|
+
exports.getInitP = getInitP;
|
|
2307
2602
|
exports.getTag = getTag;
|
|
2308
2603
|
exports.indent = indent;
|
|
2309
2604
|
exports.isArray = isArray;
|
|
@@ -2360,16 +2655,20 @@ exports.isWrapperObject = isWrapperObject;
|
|
|
2360
2655
|
exports.isWrapperString = isWrapperString;
|
|
2361
2656
|
exports.isWrapperSymbol = isWrapperSymbol;
|
|
2362
2657
|
exports.kebabCase = kebabCase;
|
|
2658
|
+
exports.lerp = lerp;
|
|
2363
2659
|
exports.memo = memo;
|
|
2364
2660
|
exports.noop = noop;
|
|
2365
2661
|
exports.not = not;
|
|
2662
|
+
exports.omit = omit;
|
|
2366
2663
|
exports.parallel = parallel;
|
|
2367
2664
|
exports.pascalCase = pascalCase;
|
|
2368
2665
|
exports.pass = pass;
|
|
2369
2666
|
exports.passWith = passWith;
|
|
2667
|
+
exports.pick = pick;
|
|
2370
2668
|
exports.pipe = pipe;
|
|
2371
2669
|
exports.randomBase32String = randomBase32String;
|
|
2372
2670
|
exports.randomChoice = randomChoice;
|
|
2671
|
+
exports.randomDistribution = randomDistribution;
|
|
2373
2672
|
exports.randomHexString = randomHexString;
|
|
2374
2673
|
exports.randomInt = randomInt;
|
|
2375
2674
|
exports.randomIntFloor = randomIntFloor;
|
|
@@ -2377,11 +2676,13 @@ exports.randomString = randomString;
|
|
|
2377
2676
|
exports.range = range;
|
|
2378
2677
|
exports.remove = remove;
|
|
2379
2678
|
exports.retry = retry;
|
|
2679
|
+
exports.romanNumerals = romanNumerals;
|
|
2380
2680
|
exports.round = round;
|
|
2381
2681
|
exports.roundBank = roundBank;
|
|
2382
2682
|
exports.roundBase = roundBase;
|
|
2383
2683
|
exports.roundCeil = roundCeil;
|
|
2384
2684
|
exports.roundFloor = roundFloor;
|
|
2685
|
+
exports.scientificNotation = scientificNotation;
|
|
2385
2686
|
exports.shuffle = shuffle;
|
|
2386
2687
|
exports.sleep = sleep;
|
|
2387
2688
|
exports.snakeCase = snakeCase;
|