foreslash 0.3.1 → 0.3.3
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 +30 -0
- package/lib/index.cmn.cjs +504 -4
- package/lib/index.d.ts +442 -20
- package/lib/index.mjs +487 -5
- package/lib/index.umd.js +504 -4
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 0.3.3 - 2025-11-05
|
|
4
|
+
|
|
5
|
+
Unstable version
|
|
6
|
+
|
|
7
|
+
- Feat 🥥 Functions added: `lerp` `scientificNotation` `castArray` `romanNumerals` `randomDistribution` and so forth
|
|
8
|
+
- Fix 🥕 Document: Added version tags to `memo` and description to several methods
|
|
9
|
+
- Other fixes and improvements
|
|
10
|
+
|
|
11
|
+
不稳定版本
|
|
12
|
+
|
|
13
|
+
- 功能 🥥 添加函数: `lerp` `scientificNotation` `castArray` `randomDistribution` 等
|
|
14
|
+
- 修复 🥕 文档: 补充 `memo` 的版本标签和部分方法的说明
|
|
15
|
+
- 其他修复与优化
|
|
16
|
+
|
|
17
|
+
## Version 0.3.2 - 2025-09-23
|
|
18
|
+
|
|
19
|
+
Unstable version
|
|
20
|
+
|
|
21
|
+
- Feat 🥥 Functions added: `chunk` `decimalNotation` `round` `format` `isPlainObject` `cartesianProduct` **and** so forth
|
|
22
|
+
- Feat 🥥 Type Utils: `Not` `IsNegative` `IsZero` `IsPositive` `Stringify`
|
|
23
|
+
- Fix 🥕 Document: Added version tags to 19 methods
|
|
24
|
+
- Other fixes and improvements
|
|
25
|
+
|
|
26
|
+
不稳定版本
|
|
27
|
+
|
|
28
|
+
- 功能 🥥 添加函数: `chunk` `decimalNotation` `round` `format` `isPlainObject` `cartesianProduct` 等
|
|
29
|
+
- 功能 🥥 类型工具: `Not` `IsNegative` `IsZero` `IsPositive` `Stringify`
|
|
30
|
+
- 修复 🥕 文档: 补充 19 个方法的版本标签
|
|
31
|
+
- 其他修复与优化
|
|
32
|
+
|
|
3
33
|
## Version 0.3.1 - 2025-08-14
|
|
4
34
|
|
|
5
35
|
Unstable version
|
package/lib/index.cmn.cjs
CHANGED
|
@@ -11,6 +11,57 @@ See the Mulan PSL v2 for more details.
|
|
|
11
11
|
*/
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
+
function cartesianProduct(...arrList) {
|
|
15
|
+
const arrLen = arrList.length;
|
|
16
|
+
const pList = Array(arrLen).fill(0);
|
|
17
|
+
const lastIndex = arrLen - 1;
|
|
18
|
+
const res = [];
|
|
19
|
+
for (let i = 0; i < arrLen; i++) {
|
|
20
|
+
if (!arrList[i].length)
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
while (1) {
|
|
24
|
+
const temp = [];
|
|
25
|
+
for (let i = 0; i < arrLen; i++) {
|
|
26
|
+
temp.push(arrList[i][pList[i]]);
|
|
27
|
+
}
|
|
28
|
+
res.push(temp);
|
|
29
|
+
pList[lastIndex] += 1;
|
|
30
|
+
for (let i = lastIndex; i >= 0; i--) {
|
|
31
|
+
if (pList[i] >= arrList[i].length) {
|
|
32
|
+
if (i > 0) {
|
|
33
|
+
pList[i] = 0;
|
|
34
|
+
pList[i - 1] += 1;
|
|
35
|
+
}
|
|
36
|
+
else
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
else
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (pList[0] >= arrList[0].length)
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
return res;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function castArray(value) {
|
|
49
|
+
return Array.isArray(value) ? value.slice() : [value];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function chunk(array, size = 2) {
|
|
53
|
+
const res = [];
|
|
54
|
+
if (size < 1 || isNaN(size))
|
|
55
|
+
return res;
|
|
56
|
+
let start = 0, end = size;
|
|
57
|
+
while (start < array.length) {
|
|
58
|
+
res.push(Array.prototype.slice.call(array, start, end));
|
|
59
|
+
start = end;
|
|
60
|
+
end += size;
|
|
61
|
+
}
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
|
|
14
65
|
function range(start, end, stepOrOptions) {
|
|
15
66
|
if (!isFinite(start))
|
|
16
67
|
throw new Error('start must be finite');
|
|
@@ -202,6 +253,22 @@ function isNumber(value) {
|
|
|
202
253
|
return typeof value === 'number';
|
|
203
254
|
}
|
|
204
255
|
|
|
256
|
+
const fnToString = Function.prototype.toString;
|
|
257
|
+
const objProtoContString = fnToString.call(Object.prototype.constructor);
|
|
258
|
+
function isPlainObject(value) {
|
|
259
|
+
if (typeof value !== 'object' || value === null)
|
|
260
|
+
return false;
|
|
261
|
+
const prototype = Object.getPrototypeOf(value);
|
|
262
|
+
if (prototype === null)
|
|
263
|
+
return true;
|
|
264
|
+
if (!Object.prototype.hasOwnProperty.call(prototype, "constructor"))
|
|
265
|
+
return false;
|
|
266
|
+
const constructorFn = prototype.constructor;
|
|
267
|
+
if (!isFunction(constructorFn) || fnToString.call(constructorFn) !== objProtoContString)
|
|
268
|
+
return false;
|
|
269
|
+
return (Object.getPrototypeOf(prototype) === null);
|
|
270
|
+
}
|
|
271
|
+
|
|
205
272
|
function isPrimitive(value) {
|
|
206
273
|
return value === undefined || value === null || (typeof value !== 'object' && typeof value !== 'function');
|
|
207
274
|
}
|
|
@@ -374,6 +441,373 @@ function clamp(num, min, max, options) {
|
|
|
374
441
|
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
375
442
|
}
|
|
376
443
|
|
|
444
|
+
function decimalNotation(num) {
|
|
445
|
+
const n = isNumber(num) ? num : Number(num);
|
|
446
|
+
if (!isFinite(n))
|
|
447
|
+
return String(n);
|
|
448
|
+
let str = String(n);
|
|
449
|
+
if (!/e/i.test(str))
|
|
450
|
+
return str;
|
|
451
|
+
const match = str.match(/^(-?)(\d+)\.?(\d*)e([+-]?)(\d+)$/);
|
|
452
|
+
const [_, sign, mantissaI, mantissaF, expSign, _exponent] = match;
|
|
453
|
+
const exponent = Number(_exponent);
|
|
454
|
+
let mantissa = mantissaI + mantissaF;
|
|
455
|
+
let dotPos = mantissaI.length;
|
|
456
|
+
if (expSign === '-') {
|
|
457
|
+
const zeroCount = exponent - dotPos + 1;
|
|
458
|
+
if (zeroCount > 0)
|
|
459
|
+
mantissa = '0'.repeat(zeroCount) + mantissa;
|
|
460
|
+
return sign + mantissa[0] + '.' + mantissa.substring(1);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
const zeroCount = exponent + dotPos - mantissa.length;
|
|
464
|
+
if (zeroCount > 0)
|
|
465
|
+
mantissa = mantissa + '0'.repeat(zeroCount);
|
|
466
|
+
return sign + mantissa.substring(0, exponent + dotPos);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function isOdd(num) {
|
|
471
|
+
return !!(num & 1);
|
|
472
|
+
}
|
|
473
|
+
function isEven(num) {
|
|
474
|
+
return !(num & 1);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function round(num, precision, type) {
|
|
478
|
+
const str = decimalNotation(num);
|
|
479
|
+
if (/NaN|Inf/.test(str))
|
|
480
|
+
return str;
|
|
481
|
+
let [_integer, _fractional] = str.split('.');
|
|
482
|
+
let sign = '';
|
|
483
|
+
if (/^-/.test(_integer)) {
|
|
484
|
+
_integer = _integer.substring(1);
|
|
485
|
+
sign = '-';
|
|
486
|
+
}
|
|
487
|
+
_fractional = _fractional !== null && _fractional !== void 0 ? _fractional : '';
|
|
488
|
+
const roundMap = { round: roundBase, banker: roundBank, floor: roundFloor, ceil: roundCeil };
|
|
489
|
+
const [integer, fractional] = (roundMap[type || 'round'] || roundBase)(_integer, _fractional, precision, !!sign);
|
|
490
|
+
if (precision > 0)
|
|
491
|
+
return sign + integer + '.' + fractional;
|
|
492
|
+
else
|
|
493
|
+
return sign + integer;
|
|
494
|
+
}
|
|
495
|
+
function roundBase(integer, fractional, precision) {
|
|
496
|
+
if (fractional.length > precision) {
|
|
497
|
+
const splitF = fractional.substring(0, precision);
|
|
498
|
+
if (Number(fractional[precision]) > 4)
|
|
499
|
+
return increase(integer, splitF);
|
|
500
|
+
return [integer, splitF];
|
|
501
|
+
}
|
|
502
|
+
if (fractional.length < precision) {
|
|
503
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
504
|
+
}
|
|
505
|
+
return [integer, fractional];
|
|
506
|
+
}
|
|
507
|
+
function roundBank(integer, fractional, precision) {
|
|
508
|
+
if (fractional.length > precision) {
|
|
509
|
+
const splitF = fractional.substring(0, precision);
|
|
510
|
+
const rightNumber = Number(fractional[precision]);
|
|
511
|
+
if (rightNumber < 5)
|
|
512
|
+
return [integer, splitF];
|
|
513
|
+
if (rightNumber > 5)
|
|
514
|
+
return increase(integer, splitF);
|
|
515
|
+
const rightNumbers = fractional.substring(precision);
|
|
516
|
+
if (!/^50*$/.test(rightNumbers))
|
|
517
|
+
return increase(integer, splitF);
|
|
518
|
+
const leftNumber = Number(precision ? fractional[precision - 1] : integer[integer.length - 1]);
|
|
519
|
+
if (isEven(leftNumber))
|
|
520
|
+
return [integer, splitF];
|
|
521
|
+
else
|
|
522
|
+
return increase(integer, splitF);
|
|
523
|
+
}
|
|
524
|
+
if (fractional.length < precision) {
|
|
525
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
526
|
+
}
|
|
527
|
+
return [integer, fractional];
|
|
528
|
+
}
|
|
529
|
+
function roundFloor(integer, fractional, precision, isNegative) {
|
|
530
|
+
if (fractional.length > precision) {
|
|
531
|
+
const splitF = fractional.substring(0, precision);
|
|
532
|
+
if (isNegative)
|
|
533
|
+
return increase(integer, splitF);
|
|
534
|
+
return [integer, splitF];
|
|
535
|
+
}
|
|
536
|
+
if (fractional.length < precision) {
|
|
537
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
538
|
+
}
|
|
539
|
+
return [integer, fractional];
|
|
540
|
+
}
|
|
541
|
+
function roundCeil(integer, fractional, precision, isNegative) {
|
|
542
|
+
if (fractional.length > precision) {
|
|
543
|
+
const splitF = fractional.substring(0, precision);
|
|
544
|
+
if (!isNegative)
|
|
545
|
+
return increase(integer, splitF);
|
|
546
|
+
return [integer, splitF];
|
|
547
|
+
}
|
|
548
|
+
if (fractional.length < precision) {
|
|
549
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
550
|
+
}
|
|
551
|
+
return [integer, fractional];
|
|
552
|
+
}
|
|
553
|
+
function increase(integer, fractional) {
|
|
554
|
+
if (fractional) {
|
|
555
|
+
const _fractional = _increase(fractional);
|
|
556
|
+
if (_fractional.length > fractional.length) {
|
|
557
|
+
return [_increase(integer), _fractional.substring(1)];
|
|
558
|
+
}
|
|
559
|
+
return [integer, _fractional];
|
|
560
|
+
}
|
|
561
|
+
return [_increase(integer), ''];
|
|
562
|
+
}
|
|
563
|
+
function _increase(num) {
|
|
564
|
+
const numList = num.split('').map(Number).reverse();
|
|
565
|
+
numList[0] += 1;
|
|
566
|
+
numList.push(0);
|
|
567
|
+
for (let i = 0; i < numList.length; i++) {
|
|
568
|
+
if (numList[i] > 9) {
|
|
569
|
+
numList[i] -= 10;
|
|
570
|
+
numList[i + 1] += 1;
|
|
571
|
+
}
|
|
572
|
+
else
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
if (numList[numList.length - 1] === 0)
|
|
576
|
+
numList.pop();
|
|
577
|
+
return numList.reverse().map(String).join('');
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function format(num, options) {
|
|
581
|
+
var _a;
|
|
582
|
+
const str = decimalNotation(num);
|
|
583
|
+
if (/NaN|Inf/.test(str))
|
|
584
|
+
return str;
|
|
585
|
+
const separator = (options || {}).separator || ',';
|
|
586
|
+
const separate = clamp((options || {}).separate || 3, 1, Infinity);
|
|
587
|
+
const decimal = (options || {}).decimal || '.';
|
|
588
|
+
const precision = clamp((_a = (options || {}).precision) !== null && _a !== void 0 ? _a : 2, 0, Infinity);
|
|
589
|
+
const round = (options || {}).round || 'round';
|
|
590
|
+
let [integer, fractional] = str.split('.');
|
|
591
|
+
let sign = '';
|
|
592
|
+
if (/^-/.test(integer)) {
|
|
593
|
+
integer = integer.substring(1);
|
|
594
|
+
sign = '-';
|
|
595
|
+
}
|
|
596
|
+
fractional = fractional !== null && fractional !== void 0 ? fractional : '';
|
|
597
|
+
if (fractional.length > precision) {
|
|
598
|
+
const roundMap = { round: roundBase, banker: roundBank, floor: roundFloor, ceil: roundCeil };
|
|
599
|
+
[integer, fractional] = (roundMap[round] || roundBase)(integer, fractional, precision, !!sign);
|
|
600
|
+
}
|
|
601
|
+
else if (fractional.length < precision) {
|
|
602
|
+
fractional += '0'.repeat(precision - fractional.length);
|
|
603
|
+
}
|
|
604
|
+
if (integer.length > separate) {
|
|
605
|
+
integer = chunk(Array.from(integer).reverse(), separate)
|
|
606
|
+
.map((part) => part.join(''))
|
|
607
|
+
.join(separator);
|
|
608
|
+
integer = Array.from(integer).reverse().join('');
|
|
609
|
+
}
|
|
610
|
+
if (precision > 0)
|
|
611
|
+
return sign + integer + decimal + fractional;
|
|
612
|
+
else
|
|
613
|
+
return sign + integer;
|
|
614
|
+
}
|
|
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 !== null && _precision !== void 0 ? _precision : 2, 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
|
+
|
|
377
811
|
function parallel(args, fn, options) {
|
|
378
812
|
return __awaiter(this, void 0, void 0, function* () {
|
|
379
813
|
if (!args.length)
|
|
@@ -1005,6 +1439,54 @@ function randomChoice(arr, weights) {
|
|
|
1005
1439
|
return arr[index];
|
|
1006
1440
|
}
|
|
1007
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
|
+
|
|
1008
1490
|
const radix32 = '0123456789abcdefghijklmnopqrstuv';
|
|
1009
1491
|
const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
1010
1492
|
const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
|
|
@@ -1631,22 +2113,22 @@ function _deepClone(obj, map, options) {
|
|
|
1631
2113
|
if (isFormData(obj))
|
|
1632
2114
|
return _cloneFormData(obj, map, _deepClone, options);
|
|
1633
2115
|
let res;
|
|
1634
|
-
if (obj
|
|
2116
|
+
if (isDate(obj)) {
|
|
1635
2117
|
res = new Date(obj.valueOf());
|
|
1636
2118
|
map.set(obj, res);
|
|
1637
2119
|
}
|
|
1638
|
-
else if (obj
|
|
2120
|
+
else if (isRegExp(obj)) {
|
|
1639
2121
|
res = new RegExp(obj.source, obj.flags);
|
|
1640
2122
|
map.set(obj, res);
|
|
1641
2123
|
}
|
|
1642
|
-
else if (obj
|
|
2124
|
+
else if (isArrayBuffer(obj)) {
|
|
1643
2125
|
res = _cloneArrayBuffer(obj, map);
|
|
1644
2126
|
}
|
|
1645
2127
|
else if (isTypedArray(obj)) {
|
|
1646
2128
|
res = new obj.constructor(_cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.length);
|
|
1647
2129
|
map.set(obj, res);
|
|
1648
2130
|
}
|
|
1649
|
-
else if (obj
|
|
2131
|
+
else if (isDataView(obj)) {
|
|
1650
2132
|
res = new DataView(map.has(obj.buffer) ? map.get(obj.buffer) : _cloneArrayBuffer(obj.buffer, map), obj.byteOffset, obj.byteLength);
|
|
1651
2133
|
map.set(obj, res);
|
|
1652
2134
|
}
|
|
@@ -2048,23 +2530,29 @@ exports.acceptableFileName = acceptableFileName;
|
|
|
2048
2530
|
exports.acceptableFileType = acceptableFileType;
|
|
2049
2531
|
exports.camelCase = camelCase;
|
|
2050
2532
|
exports.capitalize = capitalize;
|
|
2533
|
+
exports.cartesianProduct = cartesianProduct;
|
|
2051
2534
|
exports.caseCamel = caseCamel;
|
|
2052
2535
|
exports.caseConvert = caseConvert;
|
|
2053
2536
|
exports.caseKebab = caseKebab;
|
|
2054
2537
|
exports.casePascal = casePascal;
|
|
2055
2538
|
exports.caseSnake = caseSnake;
|
|
2539
|
+
exports.castArray = castArray;
|
|
2540
|
+
exports.chunk = chunk;
|
|
2056
2541
|
exports.clamp = clamp;
|
|
2057
2542
|
exports.compose = compose;
|
|
2058
2543
|
exports.curry = _curryMore;
|
|
2059
2544
|
exports.debounce = debounce;
|
|
2545
|
+
exports.decimalNotation = decimalNotation;
|
|
2060
2546
|
exports.dedent = dedent;
|
|
2061
2547
|
exports.deepClone = deepClone;
|
|
2062
2548
|
exports.deepMerge = deepMerge;
|
|
2063
2549
|
exports.defer = defer;
|
|
2064
2550
|
exports.fastClone = fastClone;
|
|
2551
|
+
exports.format = format;
|
|
2065
2552
|
exports.getAcceptableExtByMIME = getAcceptableExtByMIME;
|
|
2066
2553
|
exports.getAcceptableMIMEByExt = getAcceptableMIMEByExt;
|
|
2067
2554
|
exports.getGlobalThis = getGlobalThis;
|
|
2555
|
+
exports.getInitP = getInitP;
|
|
2068
2556
|
exports.getTag = getTag;
|
|
2069
2557
|
exports.indent = indent;
|
|
2070
2558
|
exports.isArray = isArray;
|
|
@@ -2079,6 +2567,7 @@ exports.isBuffer = isBuffer;
|
|
|
2079
2567
|
exports.isDataView = isDataView;
|
|
2080
2568
|
exports.isDate = isDate;
|
|
2081
2569
|
exports.isEmpty = isEmpty;
|
|
2570
|
+
exports.isEven = isEven;
|
|
2082
2571
|
exports.isFile = isFile;
|
|
2083
2572
|
exports.isFloat32Array = isFloat32Array;
|
|
2084
2573
|
exports.isFloat64Array = isFloat64Array;
|
|
@@ -2095,7 +2584,9 @@ exports.isNil = isNil;
|
|
|
2095
2584
|
exports.isNull = isNull;
|
|
2096
2585
|
exports.isNumber = isNumber;
|
|
2097
2586
|
exports.isObject = isObject;
|
|
2587
|
+
exports.isOdd = isOdd;
|
|
2098
2588
|
exports.isPlaceholder = isPlaceholder;
|
|
2589
|
+
exports.isPlainObject = isPlainObject;
|
|
2099
2590
|
exports.isPrimitive = isPrimitive;
|
|
2100
2591
|
exports.isPromise = isPromise;
|
|
2101
2592
|
exports.isPromiseLike = isPromiseLike;
|
|
@@ -2118,6 +2609,7 @@ exports.isWrapperObject = isWrapperObject;
|
|
|
2118
2609
|
exports.isWrapperString = isWrapperString;
|
|
2119
2610
|
exports.isWrapperSymbol = isWrapperSymbol;
|
|
2120
2611
|
exports.kebabCase = kebabCase;
|
|
2612
|
+
exports.lerp = lerp;
|
|
2121
2613
|
exports.memo = memo;
|
|
2122
2614
|
exports.noop = noop;
|
|
2123
2615
|
exports.not = not;
|
|
@@ -2128,6 +2620,7 @@ exports.passWith = passWith;
|
|
|
2128
2620
|
exports.pipe = pipe;
|
|
2129
2621
|
exports.randomBase32String = randomBase32String;
|
|
2130
2622
|
exports.randomChoice = randomChoice;
|
|
2623
|
+
exports.randomDistribution = randomDistribution;
|
|
2131
2624
|
exports.randomHexString = randomHexString;
|
|
2132
2625
|
exports.randomInt = randomInt;
|
|
2133
2626
|
exports.randomIntFloor = randomIntFloor;
|
|
@@ -2135,6 +2628,13 @@ exports.randomString = randomString;
|
|
|
2135
2628
|
exports.range = range;
|
|
2136
2629
|
exports.remove = remove;
|
|
2137
2630
|
exports.retry = retry;
|
|
2631
|
+
exports.romanNumerals = romanNumerals;
|
|
2632
|
+
exports.round = round;
|
|
2633
|
+
exports.roundBank = roundBank;
|
|
2634
|
+
exports.roundBase = roundBase;
|
|
2635
|
+
exports.roundCeil = roundCeil;
|
|
2636
|
+
exports.roundFloor = roundFloor;
|
|
2637
|
+
exports.scientificNotation = scientificNotation;
|
|
2138
2638
|
exports.shuffle = shuffle;
|
|
2139
2639
|
exports.sleep = sleep;
|
|
2140
2640
|
exports.snakeCase = snakeCase;
|