toosoon-utils 2.4.1 → 2.4.2
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/lib/classes/_pool.js +22 -50
- package/lib/classes/color-scale.js +55 -76
- package/lib/classes/frame-rate.js +19 -27
- package/lib/colors.js +85 -123
- package/lib/constants.js +6 -9
- package/lib/dom.js +10 -17
- package/lib/files.js +8 -15
- package/lib/functions.js +17 -20
- package/lib/geometry.js +20 -33
- package/lib/maths.js +22 -51
- package/lib/prng.js +36 -60
- package/lib/random.js +26 -55
- package/lib/strings.js +2 -7
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.js +1 -2
- package/package.json +2 -1
- package/tsconfig.json +3 -3
package/lib/geometry.js
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.contain = exports.cover = exports.radToSphere = exports.diagonal = exports.distance = exports.closestAngle = exports.angle = exports.toRadians = exports.toDegrees = void 0;
|
|
4
|
-
var constants_1 = require("./constants");
|
|
1
|
+
import { PI } from './constants';
|
|
5
2
|
/**
|
|
6
3
|
* Convert a radians value into degrees
|
|
7
4
|
*
|
|
8
5
|
* @param {number} radians Angle in radians
|
|
9
6
|
* @returns {number} Angle in degrees
|
|
10
7
|
*/
|
|
11
|
-
function toDegrees(radians) {
|
|
12
|
-
return (radians * 180) /
|
|
8
|
+
export function toDegrees(radians) {
|
|
9
|
+
return (radians * 180) / PI;
|
|
13
10
|
}
|
|
14
|
-
exports.toDegrees = toDegrees;
|
|
15
11
|
/**
|
|
16
12
|
* Convert a degrees value into radians
|
|
17
13
|
*
|
|
18
14
|
* @param {number} degrees Angle in degrees
|
|
19
15
|
* @returns {number} Angle in radians
|
|
20
16
|
*/
|
|
21
|
-
function toRadians(degrees) {
|
|
22
|
-
return (degrees *
|
|
17
|
+
export function toRadians(degrees) {
|
|
18
|
+
return (degrees * PI) / 180;
|
|
23
19
|
}
|
|
24
|
-
exports.toRadians = toRadians;
|
|
25
20
|
/**
|
|
26
21
|
* Calculate the angle from a point to another
|
|
27
22
|
*
|
|
@@ -31,10 +26,9 @@ exports.toRadians = toRadians;
|
|
|
31
26
|
* @param {number} y2 Y value of the second point
|
|
32
27
|
* @returns {number} Angle
|
|
33
28
|
*/
|
|
34
|
-
function angle(x1, y1, x2, y2) {
|
|
29
|
+
export function angle(x1, y1, x2, y2) {
|
|
35
30
|
return Math.atan2(y2 - y1, x2 - x1);
|
|
36
31
|
}
|
|
37
|
-
exports.angle = angle;
|
|
38
32
|
/**
|
|
39
33
|
* Find the closest angle between to angles
|
|
40
34
|
*
|
|
@@ -42,11 +36,10 @@ exports.angle = angle;
|
|
|
42
36
|
* @param {number} target Target angle in radians
|
|
43
37
|
* @returns {number} Closest angle
|
|
44
38
|
*/
|
|
45
|
-
function closestAngle(source, target) {
|
|
46
|
-
|
|
47
|
-
return delta >
|
|
39
|
+
export function closestAngle(source, target) {
|
|
40
|
+
const delta = target - source;
|
|
41
|
+
return delta > PI ? target - 2 * PI : target < -PI ? delta + 2 * PI : target;
|
|
48
42
|
}
|
|
49
|
-
exports.closestAngle = closestAngle;
|
|
50
43
|
/**
|
|
51
44
|
* Calculate the distance between two points
|
|
52
45
|
*
|
|
@@ -56,12 +49,11 @@ exports.closestAngle = closestAngle;
|
|
|
56
49
|
* @param {number} y2 Y coord of the second point
|
|
57
50
|
* @returns {number} Computed distance
|
|
58
51
|
*/
|
|
59
|
-
function distance(x1, y1, x2, y2) {
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
export function distance(x1, y1, x2, y2) {
|
|
53
|
+
const dx = x1 - x2;
|
|
54
|
+
const dy = y1 - y2;
|
|
62
55
|
return Math.sqrt(dx * dx + dy * dy);
|
|
63
56
|
}
|
|
64
|
-
exports.distance = distance;
|
|
65
57
|
/**
|
|
66
58
|
* Calculate the length of the diagonal of a rectangle
|
|
67
59
|
*
|
|
@@ -69,10 +61,9 @@ exports.distance = distance;
|
|
|
69
61
|
* @param {number} height Height of the rectangle
|
|
70
62
|
* @returns {number} Diagonal length
|
|
71
63
|
*/
|
|
72
|
-
function diagonal(width, height) {
|
|
64
|
+
export function diagonal(width, height) {
|
|
73
65
|
return Math.sqrt(width * width + height * height);
|
|
74
66
|
}
|
|
75
|
-
exports.diagonal = diagonal;
|
|
76
67
|
/**
|
|
77
68
|
* Convert radians to a 3D point on the surface of a unit sphere
|
|
78
69
|
*
|
|
@@ -82,14 +73,12 @@ exports.diagonal = diagonal;
|
|
|
82
73
|
* @param {Vector3} target Target vector
|
|
83
74
|
* @returns {Vector3}
|
|
84
75
|
*/
|
|
85
|
-
function radToSphere(radius, phi, theta, target) {
|
|
86
|
-
if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
|
|
76
|
+
export function radToSphere(radius, phi, theta, target = { x: 0, y: 0, z: 0 }) {
|
|
87
77
|
target.x = radius * Math.sin(phi) * Math.sin(theta);
|
|
88
78
|
target.y = radius * Math.cos(phi);
|
|
89
79
|
target.z = radius * Math.sin(phi) * Math.cos(theta);
|
|
90
80
|
return target;
|
|
91
81
|
}
|
|
92
|
-
exports.radToSphere = radToSphere;
|
|
93
82
|
/**
|
|
94
83
|
* Make a target fit a container
|
|
95
84
|
*
|
|
@@ -99,9 +88,9 @@ exports.radToSphere = radToSphere;
|
|
|
99
88
|
* @returns {FitOutput}
|
|
100
89
|
*/
|
|
101
90
|
function fit(target, container, mode) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
const ratioWidth = container.width / target.width;
|
|
92
|
+
const ratioHeight = container.height / target.height;
|
|
93
|
+
let scale;
|
|
105
94
|
if (mode === 'contain') {
|
|
106
95
|
scale = ratioWidth < ratioHeight ? ratioWidth : ratioHeight;
|
|
107
96
|
}
|
|
@@ -113,7 +102,7 @@ function fit(target, container, mode) {
|
|
|
113
102
|
top: (container.height - target.height * scale) >> 1,
|
|
114
103
|
width: target.width * scale,
|
|
115
104
|
height: target.height * scale,
|
|
116
|
-
scale
|
|
105
|
+
scale
|
|
117
106
|
};
|
|
118
107
|
}
|
|
119
108
|
/**
|
|
@@ -123,10 +112,9 @@ function fit(target, container, mode) {
|
|
|
123
112
|
* @param {FitInput} container Dimension of the container
|
|
124
113
|
* @returns {FitOutput}
|
|
125
114
|
*/
|
|
126
|
-
function cover(target, container) {
|
|
115
|
+
export function cover(target, container) {
|
|
127
116
|
return fit(target, container, 'cover');
|
|
128
117
|
}
|
|
129
|
-
exports.cover = cover;
|
|
130
118
|
/**
|
|
131
119
|
* Make a target fit a container (contain mode)
|
|
132
120
|
*
|
|
@@ -134,7 +122,6 @@ exports.cover = cover;
|
|
|
134
122
|
* @param {FitInput} container Dimension of the container
|
|
135
123
|
* @returns {FitOutput}
|
|
136
124
|
*/
|
|
137
|
-
function contain(target, container) {
|
|
125
|
+
export function contain(target, container) {
|
|
138
126
|
return fit(target, container, 'contain');
|
|
139
127
|
}
|
|
140
|
-
exports.contain = contain;
|
package/lib/maths.js
CHANGED
|
@@ -1,36 +1,30 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.damp = exports.average = exports.sum = exports.parabola = exports.smoothstep = exports.pingPong = exports.modAbs = exports.roundTo = exports.map = exports.normalize = exports.expLerp = exports.triLerp = exports.lerp = exports.clamp = exports.sign = exports.toPowerOf2 = exports.isPowerOf2 = exports.isOdd = exports.isEven = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Check if a number is even
|
|
6
3
|
*
|
|
7
4
|
* @param {number} value Value to check
|
|
8
5
|
* @returns {boolean} True if the given number is even, false otherwise
|
|
9
6
|
*/
|
|
10
|
-
function isEven(value) {
|
|
7
|
+
export function isEven(value) {
|
|
11
8
|
return !(value & 1);
|
|
12
9
|
}
|
|
13
|
-
exports.isEven = isEven;
|
|
14
10
|
/**
|
|
15
11
|
* Check if a number is odd
|
|
16
12
|
*
|
|
17
13
|
* @param {number} value Value to check
|
|
18
14
|
* @returns {boolean} True if the given number is odd, false otherwise
|
|
19
15
|
*/
|
|
20
|
-
function isOdd(value) {
|
|
16
|
+
export function isOdd(value) {
|
|
21
17
|
return !!(value & 1);
|
|
22
18
|
}
|
|
23
|
-
exports.isOdd = isOdd;
|
|
24
19
|
/**
|
|
25
20
|
* Check if a number is a power of 2
|
|
26
21
|
*
|
|
27
22
|
* @param {number} value Value to check
|
|
28
23
|
* @returns {boolean} True if the given number is a power of 2, false otherwise
|
|
29
24
|
*/
|
|
30
|
-
function isPowerOf2(value) {
|
|
25
|
+
export function isPowerOf2(value) {
|
|
31
26
|
return (value & (value - 1)) === 0;
|
|
32
27
|
}
|
|
33
|
-
exports.isPowerOf2 = isPowerOf2;
|
|
34
28
|
/**
|
|
35
29
|
* Find closest power of 2 that fits a number
|
|
36
30
|
*
|
|
@@ -38,25 +32,22 @@ exports.isPowerOf2 = isPowerOf2;
|
|
|
38
32
|
* @param {string} [mode='ceil'] Can be 'floor' | 'ceil' | 'round'
|
|
39
33
|
* @returns {number} Power of 2
|
|
40
34
|
*/
|
|
41
|
-
function toPowerOf2(value, mode) {
|
|
42
|
-
if (mode === void 0) { mode = 'ceil'; }
|
|
35
|
+
export function toPowerOf2(value, mode = 'ceil') {
|
|
43
36
|
return Math.pow(2, Math[mode](Math.log(value) / Math.log(2)));
|
|
44
37
|
}
|
|
45
|
-
exports.toPowerOf2 = toPowerOf2;
|
|
46
38
|
/**
|
|
47
39
|
* Return the sign (positive or negative) of a number
|
|
48
40
|
*
|
|
49
41
|
* @param {number} value Value to check
|
|
50
42
|
* @returns {number} 1 if the given number is positive, -1 if it is negative, otherwise 0
|
|
51
43
|
*/
|
|
52
|
-
function sign(value) {
|
|
44
|
+
export function sign(value) {
|
|
53
45
|
if (value > 0)
|
|
54
46
|
return 1;
|
|
55
47
|
else if (value < 0)
|
|
56
48
|
return -1;
|
|
57
49
|
return 0;
|
|
58
50
|
}
|
|
59
|
-
exports.sign = sign;
|
|
60
51
|
/**
|
|
61
52
|
* Clamp a value between two bounds
|
|
62
53
|
*
|
|
@@ -65,12 +56,9 @@ exports.sign = sign;
|
|
|
65
56
|
* @param {number} [max=1] Maximum boundary
|
|
66
57
|
* @returns {number} Clamped value
|
|
67
58
|
*/
|
|
68
|
-
function clamp(value, min, max) {
|
|
69
|
-
if (min === void 0) { min = 0; }
|
|
70
|
-
if (max === void 0) { max = 1; }
|
|
59
|
+
export function clamp(value, min = 0, max = 1) {
|
|
71
60
|
return Math.min(max, Math.max(min, value));
|
|
72
61
|
}
|
|
73
|
-
exports.clamp = clamp;
|
|
74
62
|
/**
|
|
75
63
|
* Linear interpolation between two values (lerping)
|
|
76
64
|
*
|
|
@@ -79,10 +67,9 @@ exports.clamp = clamp;
|
|
|
79
67
|
* @param {number} max Maximum value
|
|
80
68
|
* @returns {number} Lerped value
|
|
81
69
|
*/
|
|
82
|
-
function lerp(value, min, max) {
|
|
70
|
+
export function lerp(value, min, max) {
|
|
83
71
|
return min + (max - min) * value;
|
|
84
72
|
}
|
|
85
|
-
exports.lerp = lerp;
|
|
86
73
|
/**
|
|
87
74
|
* Triangular interpolation between two values
|
|
88
75
|
*
|
|
@@ -92,11 +79,10 @@ exports.lerp = lerp;
|
|
|
92
79
|
* @param {number} target Triangle target value
|
|
93
80
|
* @returns {number} Interpolated value
|
|
94
81
|
*/
|
|
95
|
-
function triLerp(value, min, max, target) {
|
|
96
|
-
|
|
82
|
+
export function triLerp(value, min, max, target) {
|
|
83
|
+
const x = Math.pow(1 + Math.abs(target - max) / Math.abs(target - min), -1);
|
|
97
84
|
return value <= x ? min - (min - target) * (value / x) : target - (target - max) * ((value - x) / (1 - x));
|
|
98
85
|
}
|
|
99
|
-
exports.triLerp = triLerp;
|
|
100
86
|
/**
|
|
101
87
|
* Exponential interpolation between two values
|
|
102
88
|
*
|
|
@@ -107,11 +93,10 @@ exports.triLerp = triLerp;
|
|
|
107
93
|
* @param {number} targetMax Upper bound of the value's target range
|
|
108
94
|
* @returns {number} Interpolated value
|
|
109
95
|
*/
|
|
110
|
-
function expLerp(value, currentMin, currentMax, targetMin, targetMax) {
|
|
96
|
+
export function expLerp(value, currentMin, currentMax, targetMin, targetMax) {
|
|
111
97
|
return (targetMin *
|
|
112
98
|
Math.pow(targetMax / targetMin, (clamp(value, currentMin, currentMax) - currentMin) / (currentMax - currentMin)));
|
|
113
99
|
}
|
|
114
|
-
exports.expLerp = expLerp;
|
|
115
100
|
/**
|
|
116
101
|
* Normalize a value between two bounds
|
|
117
102
|
*
|
|
@@ -120,10 +105,9 @@ exports.expLerp = expLerp;
|
|
|
120
105
|
* @param {number} max Maximum boundary
|
|
121
106
|
* @returns {number} Normalized value
|
|
122
107
|
*/
|
|
123
|
-
function normalize(value, min, max) {
|
|
108
|
+
export function normalize(value, min, max) {
|
|
124
109
|
return (value - min) / (max - min);
|
|
125
110
|
}
|
|
126
|
-
exports.normalize = normalize;
|
|
127
111
|
/**
|
|
128
112
|
* Re-map a number from one range to another
|
|
129
113
|
*
|
|
@@ -134,10 +118,9 @@ exports.normalize = normalize;
|
|
|
134
118
|
* @param {number} targetMax Upper bound of the value's target range
|
|
135
119
|
* @returns {number} Re-mapped value
|
|
136
120
|
*/
|
|
137
|
-
function map(value, currentMin, currentMax, targetMin, targetMax) {
|
|
121
|
+
export function map(value, currentMin, currentMax, targetMin, targetMax) {
|
|
138
122
|
return ((value - currentMin) / (currentMax - currentMin)) * (targetMax - targetMin) + targetMin;
|
|
139
123
|
}
|
|
140
|
-
exports.map = map;
|
|
141
124
|
/**
|
|
142
125
|
* Round a number up to a nearest multiple
|
|
143
126
|
*
|
|
@@ -145,13 +128,11 @@ exports.map = map;
|
|
|
145
128
|
* @param {number} [multiple=1] Multiple to round to
|
|
146
129
|
* @returns {number} Closest multiple
|
|
147
130
|
*/
|
|
148
|
-
function roundTo(value, multiple) {
|
|
149
|
-
if (multiple === void 0) { multiple = 1; }
|
|
131
|
+
export function roundTo(value, multiple = 1) {
|
|
150
132
|
if (multiple === 0)
|
|
151
133
|
return value;
|
|
152
134
|
return Math.round(value / multiple) * multiple;
|
|
153
135
|
}
|
|
154
|
-
exports.roundTo = roundTo;
|
|
155
136
|
/**
|
|
156
137
|
* Modulo absolute a value based on a length
|
|
157
138
|
*
|
|
@@ -159,13 +140,12 @@ exports.roundTo = roundTo;
|
|
|
159
140
|
* @param {number} length Total length
|
|
160
141
|
* @returns {number} Modulated value
|
|
161
142
|
*/
|
|
162
|
-
function modAbs(value, length) {
|
|
143
|
+
export function modAbs(value, length) {
|
|
163
144
|
if (value < 0) {
|
|
164
145
|
return length + (value % length);
|
|
165
146
|
}
|
|
166
147
|
return value % length;
|
|
167
148
|
}
|
|
168
|
-
exports.modAbs = modAbs;
|
|
169
149
|
/**
|
|
170
150
|
* Move back and forth a value between 0 and length, so that it is never larger than length and never smaller than 0
|
|
171
151
|
*
|
|
@@ -173,11 +153,10 @@ exports.modAbs = modAbs;
|
|
|
173
153
|
* @param {number} length Total length
|
|
174
154
|
* @returns {number} PingPonged value
|
|
175
155
|
*/
|
|
176
|
-
function pingPong(value, length) {
|
|
156
|
+
export function pingPong(value, length) {
|
|
177
157
|
value = modAbs(value, length * 2);
|
|
178
158
|
return length - Math.abs(value - length);
|
|
179
159
|
}
|
|
180
|
-
exports.pingPong = pingPong;
|
|
181
160
|
/**
|
|
182
161
|
* Smooth a value using cubic Hermite interpolation
|
|
183
162
|
*
|
|
@@ -186,13 +165,10 @@ exports.pingPong = pingPong;
|
|
|
186
165
|
* @param {number} [max=1] Maximum boundary
|
|
187
166
|
* @returns {number} Normalized smoothed value
|
|
188
167
|
*/
|
|
189
|
-
function smoothstep(value, min, max) {
|
|
190
|
-
|
|
191
|
-
if (max === void 0) { max = 1; }
|
|
192
|
-
var x = clamp(normalize(value, min, max));
|
|
168
|
+
export function smoothstep(value, min = 0, max = 1) {
|
|
169
|
+
const x = clamp(normalize(value, min, max));
|
|
193
170
|
return x * x * (3 - 2 * x);
|
|
194
171
|
}
|
|
195
|
-
exports.smoothstep = smoothstep;
|
|
196
172
|
/**
|
|
197
173
|
* Re-map the [0, 1] interval into [0, 1] parabola, such that corners are remaped to 0 and the center to 1
|
|
198
174
|
* -> parabola(0) = parabola(1) = 0, and parabola(0.5) = 1
|
|
@@ -201,31 +177,27 @@ exports.smoothstep = smoothstep;
|
|
|
201
177
|
* @param {number} [power=1] Parabola power
|
|
202
178
|
* @returns {number} Normalized re-mapped value
|
|
203
179
|
*/
|
|
204
|
-
function parabola(x, power) {
|
|
205
|
-
if (power === void 0) { power = 1; }
|
|
180
|
+
export function parabola(x, power = 1) {
|
|
206
181
|
return Math.pow(4 * x * (1 - x), power);
|
|
207
182
|
}
|
|
208
|
-
exports.parabola = parabola;
|
|
209
183
|
/**
|
|
210
184
|
* Return the sum of numbers
|
|
211
185
|
*
|
|
212
186
|
* @param {number[]} array Array of numbers
|
|
213
187
|
* @returns {number} Total sum
|
|
214
188
|
*/
|
|
215
|
-
function sum(array) {
|
|
216
|
-
return array.reduce(
|
|
189
|
+
export function sum(array) {
|
|
190
|
+
return array.reduce((previous, current) => previous + current);
|
|
217
191
|
}
|
|
218
|
-
exports.sum = sum;
|
|
219
192
|
/**
|
|
220
193
|
* Return the average of numbers
|
|
221
194
|
*
|
|
222
195
|
* @param {number[]} array Array of numbers
|
|
223
196
|
* @returns {number} Total average
|
|
224
197
|
*/
|
|
225
|
-
function average(array) {
|
|
198
|
+
export function average(array) {
|
|
226
199
|
return sum(array) / array.length;
|
|
227
200
|
}
|
|
228
|
-
exports.average = average;
|
|
229
201
|
/**
|
|
230
202
|
* Smoothly interpolate a number toward another
|
|
231
203
|
*
|
|
@@ -235,7 +207,6 @@ exports.average = average;
|
|
|
235
207
|
* @param {number} delta Delta time (in seconds)
|
|
236
208
|
* @returns {number} Interpolated number
|
|
237
209
|
*/
|
|
238
|
-
function damp(value, target, damping, delta) {
|
|
210
|
+
export function damp(value, target, damping, delta) {
|
|
239
211
|
return lerp(1 - Math.exp(-damping * delta), value, target);
|
|
240
212
|
}
|
|
241
|
-
exports.damp = damp;
|
package/lib/prng.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.randomIndex = exports.randomObjectProperty = exports.randomItem = exports.randomHexColor = exports.randomInt = exports.randomFloat = exports.randomSign = exports.randomBoolean = exports.random = exports.xoshiro128ss = exports.jsf32 = exports.mulberry32 = exports.splitmix32 = exports.sfc32 = exports.cyrb128 = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Produce a 128-bit hash value from a seed
|
|
6
3
|
*
|
|
7
4
|
* @param {string} seed Initial seed state
|
|
8
5
|
* @returns {[number, number, number, number]} Hash numbers
|
|
9
6
|
*/
|
|
10
|
-
function cyrb128(seed) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
for (
|
|
7
|
+
export function cyrb128(seed) {
|
|
8
|
+
let h1 = 1779033703;
|
|
9
|
+
let h2 = 3144134277;
|
|
10
|
+
let h3 = 1013904242;
|
|
11
|
+
let h4 = 2773480762;
|
|
12
|
+
for (let i = 0, k; i < seed.length; i++) {
|
|
16
13
|
k = seed.charCodeAt(i);
|
|
17
14
|
h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
|
|
18
15
|
h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
|
|
@@ -25,7 +22,6 @@ function cyrb128(seed) {
|
|
|
25
22
|
h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);
|
|
26
23
|
return [(h1 ^ h2 ^ h3 ^ h4) >>> 0, (h2 ^ h1) >>> 0, (h3 ^ h1) >>> 0, (h4 ^ h1) >>> 0];
|
|
27
24
|
}
|
|
28
|
-
exports.cyrb128 = cyrb128;
|
|
29
25
|
// *********************
|
|
30
26
|
// PRNG Algorithms
|
|
31
27
|
// *********************
|
|
@@ -38,12 +34,12 @@ exports.cyrb128 = cyrb128;
|
|
|
38
34
|
* @param {number} d
|
|
39
35
|
* @returns {number} Pseudo-random number
|
|
40
36
|
*/
|
|
41
|
-
function sfc32(a, b, c, d) {
|
|
37
|
+
export function sfc32(a, b, c, d) {
|
|
42
38
|
a >>>= 0;
|
|
43
39
|
b >>>= 0;
|
|
44
40
|
c >>>= 0;
|
|
45
41
|
d >>>= 0;
|
|
46
|
-
|
|
42
|
+
let t = (a + b) | 0;
|
|
47
43
|
a = b ^ (b >>> 9);
|
|
48
44
|
b = (c + (c << 3)) | 0;
|
|
49
45
|
c = (c << 21) | (c >>> 11);
|
|
@@ -52,14 +48,13 @@ function sfc32(a, b, c, d) {
|
|
|
52
48
|
c = (c + t) | 0;
|
|
53
49
|
return (t >>> 0) / 4294967296;
|
|
54
50
|
}
|
|
55
|
-
exports.sfc32 = sfc32;
|
|
56
51
|
/**
|
|
57
52
|
* SplitMix32, Generator with a 32-bit state
|
|
58
53
|
*
|
|
59
54
|
* @param {number} a
|
|
60
55
|
* @returns {number} Pseudo-random number
|
|
61
56
|
*/
|
|
62
|
-
function splitmix32(a) {
|
|
57
|
+
export function splitmix32(a) {
|
|
63
58
|
a |= 0;
|
|
64
59
|
a = (a + 0x9e3779b9) | 0;
|
|
65
60
|
var t = a ^ (a >>> 16);
|
|
@@ -68,48 +63,45 @@ function splitmix32(a) {
|
|
|
68
63
|
t = Math.imul(t, 0x735a2d97);
|
|
69
64
|
return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296;
|
|
70
65
|
}
|
|
71
|
-
exports.splitmix32 = splitmix32;
|
|
72
66
|
/**
|
|
73
67
|
* Mulberry32, Generator with a 32-bit state
|
|
74
68
|
*
|
|
75
69
|
* @param {number} a
|
|
76
70
|
* @returns {number} Pseudo-random number
|
|
77
71
|
*/
|
|
78
|
-
function mulberry32(a) {
|
|
79
|
-
|
|
72
|
+
export function mulberry32(a) {
|
|
73
|
+
let t = (a += 0x6d2b79f5);
|
|
80
74
|
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
81
75
|
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
82
76
|
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
83
77
|
}
|
|
84
|
-
exports.mulberry32 = mulberry32;
|
|
85
78
|
/**
|
|
86
79
|
* Jenkins' Small Fast, Generator with a 32-bit state
|
|
87
80
|
*
|
|
88
81
|
* @param {number} a
|
|
89
82
|
* @returns {number} Pseudo-random number
|
|
90
83
|
*/
|
|
91
|
-
function jsf32(a, b, c, d) {
|
|
84
|
+
export function jsf32(a, b, c, d) {
|
|
92
85
|
a |= 0;
|
|
93
86
|
b |= 0;
|
|
94
87
|
c |= 0;
|
|
95
88
|
d |= 0;
|
|
96
|
-
|
|
89
|
+
let t = (a - ((b << 27) | (b >>> 5))) | 0;
|
|
97
90
|
a = b ^ ((c << 17) | (c >>> 15));
|
|
98
91
|
b = (c + d) | 0;
|
|
99
92
|
c = (d + t) | 0;
|
|
100
93
|
d = (a + t) | 0;
|
|
101
94
|
return (d >>> 0) / 4294967296;
|
|
102
95
|
}
|
|
103
|
-
exports.jsf32 = jsf32;
|
|
104
96
|
/**
|
|
105
97
|
* xoshiro128**, Generator with a 128-bit state
|
|
106
98
|
*
|
|
107
99
|
* @param {number} a
|
|
108
100
|
* @returns {number} Pseudo-random number
|
|
109
101
|
*/
|
|
110
|
-
function xoshiro128ss(a, b, c, d) {
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
export function xoshiro128ss(a, b, c, d) {
|
|
103
|
+
let t = b << 9;
|
|
104
|
+
let r = a * 5;
|
|
113
105
|
r = ((r << 7) | (r >>> 25)) * 9;
|
|
114
106
|
c ^= a;
|
|
115
107
|
d ^= b;
|
|
@@ -119,7 +111,6 @@ function xoshiro128ss(a, b, c, d) {
|
|
|
119
111
|
d = (d << 11) | (d >>> 21);
|
|
120
112
|
return (r >>> 0) / 4294967296;
|
|
121
113
|
}
|
|
122
|
-
exports.xoshiro128ss = xoshiro128ss;
|
|
123
114
|
/**
|
|
124
115
|
* Generate a pseudo-random number in the interval [0, 1]
|
|
125
116
|
* PRNG equivalent of `Math.random()`
|
|
@@ -127,13 +118,12 @@ exports.xoshiro128ss = xoshiro128ss;
|
|
|
127
118
|
* @param {PRNGParameters} prng PRNG parameters
|
|
128
119
|
* @returns {number} Pseudo-random number
|
|
129
120
|
*/
|
|
130
|
-
function random(prng) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return algorithm
|
|
121
|
+
export function random(prng) {
|
|
122
|
+
const seed = typeof prng === 'string' ? prng : prng.seed;
|
|
123
|
+
const algorithm = typeof prng === 'string' ? splitmix32 : prng.algorithm;
|
|
124
|
+
const hashes = cyrb128(seed);
|
|
125
|
+
return algorithm(...hashes);
|
|
135
126
|
}
|
|
136
|
-
exports.random = random;
|
|
137
127
|
/**
|
|
138
128
|
* Generate a pseudo-random boolean (true or false)
|
|
139
129
|
*
|
|
@@ -141,11 +131,9 @@ exports.random = random;
|
|
|
141
131
|
* @param {number} [probability=0.5] Probability to get true
|
|
142
132
|
* @returns {boolean} Either `true` or `false`
|
|
143
133
|
*/
|
|
144
|
-
function randomBoolean(prng, probability) {
|
|
145
|
-
if (probability === void 0) { probability = 0.5; }
|
|
134
|
+
export function randomBoolean(prng, probability = 0.5) {
|
|
146
135
|
return random(prng) < probability;
|
|
147
136
|
}
|
|
148
|
-
exports.randomBoolean = randomBoolean;
|
|
149
137
|
/**
|
|
150
138
|
* Generate a pseudo-random sign (1 or -1)
|
|
151
139
|
*
|
|
@@ -153,11 +141,9 @@ exports.randomBoolean = randomBoolean;
|
|
|
153
141
|
* @param {number} [probability=0.5] Probability to get 1
|
|
154
142
|
* @returns {number} Either 1 or -1
|
|
155
143
|
*/
|
|
156
|
-
function randomSign(prng, probability) {
|
|
157
|
-
if (probability === void 0) { probability = 0.5; }
|
|
144
|
+
export function randomSign(prng, probability = 0.5) {
|
|
158
145
|
return randomBoolean(prng, probability) ? 1 : -1;
|
|
159
146
|
}
|
|
160
|
-
exports.randomSign = randomSign;
|
|
161
147
|
/**
|
|
162
148
|
* Generate a pseudo-random floating-point number within a specified range
|
|
163
149
|
*
|
|
@@ -167,13 +153,9 @@ exports.randomSign = randomSign;
|
|
|
167
153
|
* @param {number} [precision=2] Number of digits after the decimal point
|
|
168
154
|
* @returns {number} Generated float
|
|
169
155
|
*/
|
|
170
|
-
function randomFloat(prng, min, max, precision) {
|
|
171
|
-
if (min === void 0) { min = 0; }
|
|
172
|
-
if (max === void 0) { max = 1; }
|
|
173
|
-
if (precision === void 0) { precision = 2; }
|
|
156
|
+
export function randomFloat(prng, min = 0, max = 1, precision = 2) {
|
|
174
157
|
return parseFloat(Math.min(min + random(prng) * (max - min), max).toFixed(precision));
|
|
175
158
|
}
|
|
176
|
-
exports.randomFloat = randomFloat;
|
|
177
159
|
/**
|
|
178
160
|
* Generate a pseudo-random integer number within a specified range
|
|
179
161
|
*
|
|
@@ -182,20 +164,18 @@ exports.randomFloat = randomFloat;
|
|
|
182
164
|
* @param {number} max Maximum boundary
|
|
183
165
|
* @returns {number} Generated integer
|
|
184
166
|
*/
|
|
185
|
-
function randomInt(prng, min, max) {
|
|
167
|
+
export function randomInt(prng, min, max) {
|
|
186
168
|
return Math.floor(random(prng) * (max - min + 1) + min);
|
|
187
169
|
}
|
|
188
|
-
exports.randomInt = randomInt;
|
|
189
170
|
/**
|
|
190
171
|
* Generate a pseudo-random hexadecimal color
|
|
191
172
|
*
|
|
192
173
|
* @param {PRNGParameters} prng PRNG parameters
|
|
193
174
|
* @returns {string} Generated hexadecimal color
|
|
194
175
|
*/
|
|
195
|
-
function randomHexColor(prng) {
|
|
176
|
+
export function randomHexColor(prng) {
|
|
196
177
|
return '#' + ('00000' + ((random(prng) * (1 << 24)) | 0).toString(16)).slice(-6);
|
|
197
178
|
}
|
|
198
|
-
exports.randomHexColor = randomHexColor;
|
|
199
179
|
/**
|
|
200
180
|
* Pick a pseudo-random item from a given array
|
|
201
181
|
*
|
|
@@ -203,12 +183,11 @@ exports.randomHexColor = randomHexColor;
|
|
|
203
183
|
* @param {T[]} array Array to pick the item from
|
|
204
184
|
* @returns {T|undefined} Random item picked
|
|
205
185
|
*/
|
|
206
|
-
function randomItem(prng, array) {
|
|
186
|
+
export function randomItem(prng, array) {
|
|
207
187
|
if (array.length === 0)
|
|
208
188
|
return undefined;
|
|
209
189
|
return array[randomInt(prng, 0, array.length - 1)];
|
|
210
190
|
}
|
|
211
|
-
exports.randomItem = randomItem;
|
|
212
191
|
/**
|
|
213
192
|
* Pick a pseudo-random property value from a given object
|
|
214
193
|
*
|
|
@@ -216,14 +195,13 @@ exports.randomItem = randomItem;
|
|
|
216
195
|
* @param {object} object Object to pick the property from
|
|
217
196
|
* @returns {T|undefined} Random item picked
|
|
218
197
|
*/
|
|
219
|
-
function randomObjectProperty(prng, object) {
|
|
220
|
-
|
|
221
|
-
|
|
198
|
+
export function randomObjectProperty(prng, object) {
|
|
199
|
+
const keys = Object.keys(object);
|
|
200
|
+
const key = randomItem(prng, keys);
|
|
222
201
|
if (key && object.hasOwnProperty(key)) {
|
|
223
202
|
return object[key];
|
|
224
203
|
}
|
|
225
204
|
}
|
|
226
|
-
exports.randomObjectProperty = randomObjectProperty;
|
|
227
205
|
/**
|
|
228
206
|
* Select a pseudo-random index from an array of weighted items
|
|
229
207
|
*
|
|
@@ -231,22 +209,20 @@ exports.randomObjectProperty = randomObjectProperty;
|
|
|
231
209
|
* @param {number[]} weights Array of weights
|
|
232
210
|
* @returns {number} Random index based on weights
|
|
233
211
|
*/
|
|
234
|
-
function randomIndex(prng, weights) {
|
|
212
|
+
export function randomIndex(prng, weights) {
|
|
235
213
|
if (weights.length === 0)
|
|
236
214
|
return -1;
|
|
237
|
-
|
|
238
|
-
for (
|
|
239
|
-
|
|
240
|
-
totalWeight += weight_1;
|
|
215
|
+
let totalWeight = 0;
|
|
216
|
+
for (let weight of weights) {
|
|
217
|
+
totalWeight += weight;
|
|
241
218
|
}
|
|
242
219
|
if (totalWeight <= 0)
|
|
243
220
|
console.warn('PRNG randomIndex()', 'Weights must sum to > 0', totalWeight);
|
|
244
|
-
|
|
245
|
-
for (
|
|
221
|
+
let weight = random(prng) * totalWeight;
|
|
222
|
+
for (let i = 0; i < weights.length; i++) {
|
|
246
223
|
if (weight < weights[i])
|
|
247
224
|
return i;
|
|
248
225
|
weight -= weights[i];
|
|
249
226
|
}
|
|
250
227
|
return 0;
|
|
251
228
|
}
|
|
252
|
-
exports.randomIndex = randomIndex;
|