oakscriptjs 0.9.5 → 0.10.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/README.md +1 -1
- package/dist/cjs/array/index.d.ts +93 -50
- package/dist/cjs/array/index.d.ts.map +1 -1
- package/dist/cjs/array/index.js +239 -78
- package/dist/cjs/array/index.js.map +3 -3
- package/dist/cjs/callsite/index.d.ts +81 -2
- package/dist/cjs/callsite/index.d.ts.map +1 -1
- package/dist/cjs/callsite/index.js +62 -1
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/color/index.d.ts +7 -3
- package/dist/cjs/color/index.d.ts.map +1 -1
- package/dist/cjs/color/index.js +6 -1
- package/dist/cjs/color/index.js.map +2 -2
- package/dist/cjs/drawing/bar-time.d.ts +24 -0
- package/dist/cjs/drawing/bar-time.d.ts.map +1 -0
- package/dist/cjs/drawing/bar-time.js +47 -0
- package/dist/cjs/drawing/bar-time.js.map +7 -0
- package/dist/cjs/drawing/output.d.ts +32 -0
- package/dist/cjs/drawing/output.d.ts.map +1 -0
- package/dist/cjs/drawing/output.js +184 -0
- package/dist/cjs/drawing/output.js.map +7 -0
- package/dist/cjs/drawing/registry.d.ts +5 -4
- package/dist/cjs/drawing/registry.d.ts.map +1 -1
- package/dist/cjs/drawing/registry.js +11 -2
- package/dist/cjs/drawing/registry.js.map +2 -2
- package/dist/cjs/index.d.ts +6 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +9 -2
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/label/index.d.ts.map +1 -1
- package/dist/cjs/label/index.js +2 -1
- package/dist/cjs/label/index.js.map +2 -2
- package/dist/cjs/linefill/index.d.ts.map +1 -1
- package/dist/cjs/linefill/index.js +1 -0
- package/dist/cjs/linefill/index.js.map +2 -2
- package/dist/cjs/math/index.d.ts +76 -21
- package/dist/cjs/math/index.d.ts.map +1 -1
- package/dist/cjs/math/index.js +155 -41
- package/dist/cjs/math/index.js.map +3 -3
- package/dist/cjs/matrix/index.d.ts.map +1 -1
- package/dist/cjs/matrix/index.js +42 -36
- package/dist/cjs/matrix/index.js.map +2 -2
- package/dist/cjs/polyline/index.d.ts +3 -5
- package/dist/cjs/polyline/index.d.ts.map +1 -1
- package/dist/cjs/polyline/index.js +0 -5
- package/dist/cjs/polyline/index.js.map +2 -2
- package/dist/cjs/runtime/series.d.ts +9 -0
- package/dist/cjs/runtime/series.d.ts.map +1 -1
- package/dist/cjs/runtime/series.js +16 -2
- package/dist/cjs/runtime/series.js.map +2 -2
- package/dist/cjs/runtime/types.d.ts +22 -0
- package/dist/cjs/runtime/types.d.ts.map +1 -1
- package/dist/cjs/runtime/types.js.map +1 -1
- package/dist/cjs/script/index.d.ts +97 -36
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +173 -26
- package/dist/cjs/script/index.js.map +3 -3
- package/dist/cjs/session/calendar.d.ts.map +1 -1
- package/dist/cjs/session/calendar.js +15 -2
- package/dist/cjs/session/calendar.js.map +2 -2
- package/dist/cjs/str/index.d.ts +50 -38
- package/dist/cjs/str/index.d.ts.map +1 -1
- package/dist/cjs/str/index.js +43 -15
- package/dist/cjs/str/index.js.map +2 -2
- package/dist/cjs/str/messageformat.d.ts +2 -1
- package/dist/cjs/str/messageformat.d.ts.map +1 -1
- package/dist/cjs/str/messageformat.js +4 -1
- package/dist/cjs/str/messageformat.js.map +2 -2
- package/dist/cjs/str/numberformat.d.ts +4 -0
- package/dist/cjs/str/numberformat.d.ts.map +1 -1
- package/dist/cjs/str/numberformat.js +26 -4
- package/dist/cjs/str/numberformat.js.map +3 -3
- package/dist/cjs/ta/index.d.ts +86 -43
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +173 -267
- package/dist/cjs/ta/index.js.map +3 -3
- package/dist/cjs/ta/running-sum.d.ts +54 -2
- package/dist/cjs/ta/running-sum.d.ts.map +1 -1
- package/dist/cjs/ta/running-sum.js +132 -52
- package/dist/cjs/ta/running-sum.js.map +2 -2
- package/dist/cjs/ta-series.d.ts +4 -4
- package/dist/cjs/ta-series.d.ts.map +1 -1
- package/dist/cjs/ta-series.js +4 -3
- package/dist/cjs/ta-series.js.map +2 -2
- package/dist/cjs/table/index.d.ts +87 -0
- package/dist/cjs/table/index.d.ts.map +1 -0
- package/dist/cjs/table/index.js +150 -0
- package/dist/cjs/table/index.js.map +7 -0
- package/dist/cjs/text/index.d.ts +17 -2
- package/dist/cjs/text/index.d.ts.map +1 -1
- package/dist/cjs/text/index.js +15 -1
- package/dist/cjs/text/index.js.map +2 -2
- package/dist/cjs/time/datestring.d.ts +1 -0
- package/dist/cjs/time/datestring.d.ts.map +1 -1
- package/dist/cjs/time/datestring.js +7 -0
- package/dist/cjs/time/datestring.js.map +2 -2
- package/dist/cjs/time/index.d.ts.map +1 -1
- package/dist/cjs/time/index.js +2 -1
- package/dist/cjs/time/index.js.map +2 -2
- package/dist/cjs/time/session.d.ts +28 -9
- package/dist/cjs/time/session.d.ts.map +1 -1
- package/dist/cjs/time/session.js +74 -28
- package/dist/cjs/time/session.js.map +2 -2
- package/dist/cjs/time/timezone.d.ts +5 -0
- package/dist/cjs/time/timezone.d.ts.map +1 -1
- package/dist/cjs/time/timezone.js +15 -1
- package/dist/cjs/time/timezone.js.map +2 -2
- package/dist/cjs/types/index.d.ts +30 -1
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +12 -0
- package/dist/cjs/types/index.js.map +2 -2
- package/dist/cjs/types/metadata.d.ts +258 -26
- package/dist/cjs/types/metadata.d.ts.map +1 -1
- package/dist/cjs/types/metadata.js.map +1 -1
- package/dist/esm/array/index.d.ts +93 -50
- package/dist/esm/array/index.d.ts.map +1 -1
- package/dist/esm/array/index.js +383 -133
- package/dist/esm/array/index.js.map +1 -1
- package/dist/esm/callsite/index.d.ts +81 -2
- package/dist/esm/callsite/index.d.ts.map +1 -1
- package/dist/esm/callsite/index.js +145 -3
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/color/index.d.ts +7 -3
- package/dist/esm/color/index.d.ts.map +1 -1
- package/dist/esm/color/index.js +15 -3
- package/dist/esm/color/index.js.map +1 -1
- package/dist/esm/drawing/bar-time.d.ts +24 -0
- package/dist/esm/drawing/bar-time.d.ts.map +1 -0
- package/dist/esm/drawing/bar-time.js +44 -0
- package/dist/esm/drawing/bar-time.js.map +1 -0
- package/dist/esm/drawing/output.d.ts +32 -0
- package/dist/esm/drawing/output.d.ts.map +1 -0
- package/dist/esm/drawing/output.js +190 -0
- package/dist/esm/drawing/output.js.map +1 -0
- package/dist/esm/drawing/registry.d.ts +5 -4
- package/dist/esm/drawing/registry.d.ts.map +1 -1
- package/dist/esm/drawing/registry.js +12 -2
- package/dist/esm/drawing/registry.js.map +1 -1
- package/dist/esm/index.d.ts +6 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +7 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/label/index.d.ts.map +1 -1
- package/dist/esm/label/index.js +2 -1
- package/dist/esm/label/index.js.map +1 -1
- package/dist/esm/linefill/index.d.ts.map +1 -1
- package/dist/esm/linefill/index.js +3 -0
- package/dist/esm/linefill/index.js.map +1 -1
- package/dist/esm/math/index.d.ts +76 -21
- package/dist/esm/math/index.d.ts.map +1 -1
- package/dist/esm/math/index.js +227 -61
- package/dist/esm/math/index.js.map +1 -1
- package/dist/esm/matrix/index.d.ts.map +1 -1
- package/dist/esm/matrix/index.js +57 -43
- package/dist/esm/matrix/index.js.map +1 -1
- package/dist/esm/polyline/index.d.ts +3 -5
- package/dist/esm/polyline/index.d.ts.map +1 -1
- package/dist/esm/polyline/index.js +3 -9
- package/dist/esm/polyline/index.js.map +1 -1
- package/dist/esm/runtime/series.d.ts +9 -0
- package/dist/esm/runtime/series.d.ts.map +1 -1
- package/dist/esm/runtime/series.js +18 -1
- package/dist/esm/runtime/series.js.map +1 -1
- package/dist/esm/runtime/types.d.ts +22 -0
- package/dist/esm/runtime/types.d.ts.map +1 -1
- package/dist/esm/script/index.d.ts +97 -36
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +211 -22
- package/dist/esm/script/index.js.map +1 -1
- package/dist/esm/session/calendar.d.ts.map +1 -1
- package/dist/esm/session/calendar.js +22 -2
- package/dist/esm/session/calendar.js.map +1 -1
- package/dist/esm/str/index.d.ts +50 -38
- package/dist/esm/str/index.d.ts.map +1 -1
- package/dist/esm/str/index.js +103 -52
- package/dist/esm/str/index.js.map +1 -1
- package/dist/esm/str/messageformat.d.ts +2 -1
- package/dist/esm/str/messageformat.d.ts.map +1 -1
- package/dist/esm/str/messageformat.js +7 -2
- package/dist/esm/str/messageformat.js.map +1 -1
- package/dist/esm/str/numberformat.d.ts +4 -0
- package/dist/esm/str/numberformat.d.ts.map +1 -1
- package/dist/esm/str/numberformat.js +38 -4
- package/dist/esm/str/numberformat.js.map +1 -1
- package/dist/esm/ta/index.d.ts +86 -43
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +296 -348
- package/dist/esm/ta/index.js.map +1 -1
- package/dist/esm/ta/running-sum.d.ts +54 -2
- package/dist/esm/ta/running-sum.d.ts.map +1 -1
- package/dist/esm/ta/running-sum.js +166 -71
- package/dist/esm/ta/running-sum.js.map +1 -1
- package/dist/esm/ta-series.d.ts +4 -4
- package/dist/esm/ta-series.d.ts.map +1 -1
- package/dist/esm/ta-series.js +5 -4
- package/dist/esm/ta-series.js.map +1 -1
- package/dist/esm/table/index.d.ts +87 -0
- package/dist/esm/table/index.d.ts.map +1 -0
- package/dist/esm/table/index.js +169 -0
- package/dist/esm/table/index.js.map +1 -0
- package/dist/esm/text/index.d.ts +17 -2
- package/dist/esm/text/index.d.ts.map +1 -1
- package/dist/esm/text/index.js +17 -2
- package/dist/esm/text/index.js.map +1 -1
- package/dist/esm/time/datestring.d.ts +1 -0
- package/dist/esm/time/datestring.d.ts.map +1 -1
- package/dist/esm/time/datestring.js +12 -0
- package/dist/esm/time/datestring.js.map +1 -1
- package/dist/esm/time/index.d.ts.map +1 -1
- package/dist/esm/time/index.js +3 -1
- package/dist/esm/time/index.js.map +1 -1
- package/dist/esm/time/session.d.ts +28 -9
- package/dist/esm/time/session.d.ts.map +1 -1
- package/dist/esm/time/session.js +113 -42
- package/dist/esm/time/session.js.map +1 -1
- package/dist/esm/time/timezone.d.ts +5 -0
- package/dist/esm/time/timezone.d.ts.map +1 -1
- package/dist/esm/time/timezone.js +21 -1
- package/dist/esm/time/timezone.js.map +1 -1
- package/dist/esm/types/index.d.ts +30 -1
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/index.js +14 -0
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/metadata.d.ts +258 -26
- package/dist/esm/types/metadata.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/array/index.ts +364 -150
- package/src/callsite/index.ts +147 -3
- package/src/color/index.ts +15 -5
- package/src/drawing/bar-time.ts +42 -0
- package/src/drawing/output.ts +214 -0
- package/src/drawing/registry.ts +16 -6
- package/src/index.ts +9 -3
- package/src/label/index.ts +2 -1
- package/src/linefill/index.ts +2 -0
- package/src/math/index.ts +256 -74
- package/src/matrix/index.ts +52 -52
- package/src/polyline/index.ts +3 -12
- package/src/runtime/series.ts +22 -1
- package/src/runtime/types.ts +23 -0
- package/src/script/index.ts +307 -25
- package/src/session/calendar.ts +22 -2
- package/src/str/index.ts +95 -51
- package/src/str/messageformat.ts +7 -2
- package/src/str/numberformat.ts +39 -4
- package/src/ta/index.ts +306 -386
- package/src/ta/running-sum.ts +187 -74
- package/src/ta-series.ts +8 -7
- package/src/table/index.ts +221 -0
- package/src/text/index.ts +18 -2
- package/src/time/datestring.ts +10 -0
- package/src/time/index.ts +3 -1
- package/src/time/session.ts +97 -47
- package/src/time/timezone.ts +21 -1
- package/src/types/index.ts +32 -1
- package/src/types/metadata.ts +325 -26
package/dist/cjs/array/index.js
CHANGED
|
@@ -52,6 +52,7 @@ __export(array_exports, {
|
|
|
52
52
|
new_line: () => new_line,
|
|
53
53
|
new_linefill: () => new_linefill,
|
|
54
54
|
new_string: () => new_string,
|
|
55
|
+
new_table: () => new_table,
|
|
55
56
|
newtype: () => newtype,
|
|
56
57
|
percentile_linear_interpolation: () => percentile_linear_interpolation,
|
|
57
58
|
percentile_nearest_rank: () => percentile_nearest_rank,
|
|
@@ -85,11 +86,27 @@ function new_array(size2 = 0, initial_value) {
|
|
|
85
86
|
function size(id) {
|
|
86
87
|
return id.length;
|
|
87
88
|
}
|
|
89
|
+
function isNa(v) {
|
|
90
|
+
return v === void 0 || v === null || typeof v === "number" && Number.isNaN(v);
|
|
91
|
+
}
|
|
92
|
+
function naOf(id) {
|
|
93
|
+
return id.length === 0 || typeof id[0] === "number" ? NaN : void 0;
|
|
94
|
+
}
|
|
95
|
+
function position(name, id, index, extra = 0) {
|
|
96
|
+
const i = Math.trunc(index);
|
|
97
|
+
const n = id.length;
|
|
98
|
+
if (i < -n || i >= n + extra) {
|
|
99
|
+
throw new Error(`array.${name}: index ${i} is out of bounds, array size is ${n}`);
|
|
100
|
+
}
|
|
101
|
+
return i < 0 ? i + n : i;
|
|
102
|
+
}
|
|
88
103
|
function get(id, index) {
|
|
89
|
-
return id
|
|
104
|
+
if (Number.isNaN(index)) return naOf(id);
|
|
105
|
+
return id[position("get", id, index)];
|
|
90
106
|
}
|
|
91
107
|
function set(id, index, value) {
|
|
92
|
-
|
|
108
|
+
if (Number.isNaN(index)) return;
|
|
109
|
+
id[position("set", id, index)] = value;
|
|
93
110
|
}
|
|
94
111
|
function push(id, value) {
|
|
95
112
|
id.push(value);
|
|
@@ -107,25 +124,46 @@ function clear(id) {
|
|
|
107
124
|
id.length = 0;
|
|
108
125
|
}
|
|
109
126
|
function insert(id, index, value) {
|
|
110
|
-
|
|
127
|
+
if (Number.isNaN(index)) {
|
|
128
|
+
id.push(value);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
id.splice(position("insert", id, index, 1), 0, value);
|
|
111
132
|
}
|
|
112
133
|
function remove(id, index) {
|
|
113
|
-
|
|
134
|
+
if (Number.isNaN(index)) return naOf(id);
|
|
135
|
+
return id.splice(position("remove", id, index), 1)[0];
|
|
136
|
+
}
|
|
137
|
+
function pineEqual(a, b) {
|
|
138
|
+
if (isNa(a) || isNa(b)) return false;
|
|
139
|
+
if (a === b) return true;
|
|
140
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
141
|
+
const d = a - b;
|
|
142
|
+
return -1e-10 <= d && d <= 1e-10;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
114
145
|
}
|
|
115
146
|
function includes(id, value) {
|
|
116
|
-
return id
|
|
147
|
+
return indexof(id, value) >= 0;
|
|
117
148
|
}
|
|
118
149
|
function indexof(id, value) {
|
|
119
|
-
|
|
150
|
+
for (let i = 0; i < id.length; i++) {
|
|
151
|
+
if (pineEqual(id[i], value)) return i;
|
|
152
|
+
}
|
|
153
|
+
return -1;
|
|
120
154
|
}
|
|
121
155
|
function lastindexof(id, value) {
|
|
122
|
-
|
|
156
|
+
for (let i = id.length - 1; i >= 0; i--) {
|
|
157
|
+
if (pineEqual(id[i], value)) return i;
|
|
158
|
+
}
|
|
159
|
+
return -1;
|
|
123
160
|
}
|
|
124
161
|
function copy(id) {
|
|
125
162
|
return [...id];
|
|
126
163
|
}
|
|
127
164
|
function concat(id1, id2) {
|
|
128
|
-
|
|
165
|
+
for (const v of Array.from(id2)) id1.push(v);
|
|
166
|
+
return id1;
|
|
129
167
|
}
|
|
130
168
|
function join(id, separator = ",") {
|
|
131
169
|
return id.join(separator);
|
|
@@ -134,64 +172,162 @@ function reverse(id) {
|
|
|
134
172
|
id.reverse();
|
|
135
173
|
}
|
|
136
174
|
function slice(id, index_from, index_to) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
175
|
+
const n = id.length;
|
|
176
|
+
const start = Number.isNaN(index_from) ? 0 : Math.trunc(index_from);
|
|
177
|
+
const stop = index_to === void 0 || Number.isNaN(index_to) ? n : Math.trunc(index_to);
|
|
178
|
+
if (start < 0 || start >= n) throw new Error(`array.slice: index ${start} is out of bounds, array size is ${n}`);
|
|
179
|
+
if (stop < 0 || stop > n) throw new Error(`array.slice: index ${stop} is out of bounds, array size is ${n}`);
|
|
180
|
+
if (start > stop) throw new Error(`array.slice: index_from ${start} is greater than index_to ${stop}`);
|
|
181
|
+
return sliceView(id, start, stop - start);
|
|
182
|
+
}
|
|
183
|
+
function indexKey(p) {
|
|
184
|
+
if (typeof p !== "string") return -1;
|
|
185
|
+
const i = Number(p);
|
|
186
|
+
return Number.isInteger(i) && i >= 0 && String(i) === p ? i : -1;
|
|
187
|
+
}
|
|
188
|
+
function sliceView(parent, start, size2) {
|
|
189
|
+
const resize = (target) => {
|
|
190
|
+
if (target > size2) parent.splice(start + size2, 0, ...Array(target - size2).fill(void 0));
|
|
191
|
+
else if (target < size2) parent.splice(start + target, size2 - target);
|
|
192
|
+
size2 = target;
|
|
193
|
+
};
|
|
194
|
+
return new Proxy([], {
|
|
195
|
+
get(target, p, receiver) {
|
|
196
|
+
const i = indexKey(p);
|
|
197
|
+
if (i >= 0) return i < size2 ? parent[start + i] : void 0;
|
|
198
|
+
if (p === "length") return size2;
|
|
199
|
+
return Reflect.get(target, p, receiver);
|
|
200
|
+
},
|
|
201
|
+
set(target, p, value, receiver) {
|
|
202
|
+
const i = indexKey(p);
|
|
203
|
+
if (i >= 0) {
|
|
204
|
+
if (i >= size2) resize(i + 1);
|
|
205
|
+
parent[start + i] = value;
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (p === "length") {
|
|
209
|
+
resize(Number(value));
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
return Reflect.set(target, p, value, receiver);
|
|
213
|
+
},
|
|
214
|
+
has(target, p) {
|
|
215
|
+
const i = indexKey(p);
|
|
216
|
+
return i >= 0 ? i < size2 : Reflect.has(target, p);
|
|
217
|
+
},
|
|
218
|
+
// Array methods delete the slots past the new end before they set the length, which does the removal.
|
|
219
|
+
deleteProperty(target, p) {
|
|
220
|
+
return indexKey(p) >= 0 ? true : Reflect.deleteProperty(target, p);
|
|
221
|
+
},
|
|
222
|
+
ownKeys(target) {
|
|
223
|
+
return [...Array.from({ length: size2 }, (_, i) => String(i)), ...Reflect.ownKeys(target)];
|
|
224
|
+
},
|
|
225
|
+
getOwnPropertyDescriptor(target, p) {
|
|
226
|
+
const i = indexKey(p);
|
|
227
|
+
if (i >= 0) {
|
|
228
|
+
return i < size2 ? { value: parent[start + i], writable: true, enumerable: true, configurable: true } : void 0;
|
|
229
|
+
}
|
|
230
|
+
if (p === "length") return { value: size2, writable: true, enumerable: false, configurable: false };
|
|
231
|
+
return Reflect.getOwnPropertyDescriptor(target, p);
|
|
145
232
|
}
|
|
146
233
|
});
|
|
147
234
|
}
|
|
235
|
+
function sortedPositions(id, order) {
|
|
236
|
+
const values = [];
|
|
237
|
+
const nas = [];
|
|
238
|
+
for (let i = 0; i < id.length; i++) (isNa(id[i]) ? nas : values).push(i);
|
|
239
|
+
values.sort((a, b) => {
|
|
240
|
+
const x = id[a];
|
|
241
|
+
const y = id[b];
|
|
242
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
243
|
+
});
|
|
244
|
+
const naFirst = values.length > 0 && typeof id[values[0]] === "string";
|
|
245
|
+
const positions = naFirst ? [...nas, ...values] : [...values, ...nas];
|
|
246
|
+
if (order === "desc" || order === "descending") positions.reverse();
|
|
247
|
+
return positions;
|
|
248
|
+
}
|
|
249
|
+
function sort(id, order = "asc") {
|
|
250
|
+
const sorted = sortedPositions(id, order).map((p) => id[p]);
|
|
251
|
+
for (let i = 0; i < sorted.length; i++) id[i] = sorted[i];
|
|
252
|
+
}
|
|
148
253
|
function sum(id) {
|
|
149
|
-
|
|
254
|
+
let total = 0;
|
|
255
|
+
let count = 0;
|
|
256
|
+
for (const v of id) {
|
|
257
|
+
if (Number.isNaN(v)) continue;
|
|
258
|
+
count++;
|
|
259
|
+
total += v;
|
|
260
|
+
if (Math.abs(total) <= 1e-10) total = 0;
|
|
261
|
+
}
|
|
262
|
+
return count ? total : NaN;
|
|
150
263
|
}
|
|
151
264
|
function avg(id) {
|
|
152
265
|
const values = id.filter((v) => !Number.isNaN(v));
|
|
153
266
|
return values.length ? values.reduce((a, b) => a + b, 0) / values.length : NaN;
|
|
154
267
|
}
|
|
268
|
+
function nthValue(name, id, nth, compare) {
|
|
269
|
+
const rank = Number.isNaN(nth) ? 0 : Math.trunc(nth);
|
|
270
|
+
const values = id.filter((v) => !Number.isNaN(v));
|
|
271
|
+
if (!values.length) return NaN;
|
|
272
|
+
if (rank < 0 || rank >= id.length) {
|
|
273
|
+
throw new Error(`array.${name}: nth ${rank} is out of bounds, array size is ${id.length}`);
|
|
274
|
+
}
|
|
275
|
+
values.sort(compare);
|
|
276
|
+
return values[Math.min(rank, values.length - 1)];
|
|
277
|
+
}
|
|
155
278
|
function min(id, nth = 0) {
|
|
156
|
-
|
|
157
|
-
return values.length ? values[Math.min(nth, values.length - 1)] : NaN;
|
|
279
|
+
return nthValue("min", id, nth, (a, b) => a - b);
|
|
158
280
|
}
|
|
159
281
|
function max(id, nth = 0) {
|
|
160
|
-
|
|
161
|
-
return values.length ? values[Math.min(nth, values.length - 1)] : NaN;
|
|
282
|
+
return nthValue("max", id, nth, (a, b) => b - a);
|
|
162
283
|
}
|
|
163
284
|
function median(id) {
|
|
164
|
-
const sorted =
|
|
285
|
+
const sorted = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);
|
|
286
|
+
if (!sorted.length) return NaN;
|
|
165
287
|
const mid = Math.floor(sorted.length / 2);
|
|
166
288
|
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
167
289
|
}
|
|
168
290
|
function mode(id) {
|
|
169
291
|
const frequency = /* @__PURE__ */ new Map();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
292
|
+
for (const v of id) {
|
|
293
|
+
if (!Number.isNaN(v)) frequency.set(v, (frequency.get(v) ?? 0) + 1);
|
|
294
|
+
}
|
|
295
|
+
let best = NaN;
|
|
296
|
+
let bestCount = 0;
|
|
297
|
+
for (const [v, count] of frequency) {
|
|
298
|
+
if (count > bestCount || count === bestCount && v < best) {
|
|
299
|
+
best = v;
|
|
300
|
+
bestCount = count;
|
|
178
301
|
}
|
|
179
302
|
}
|
|
180
|
-
return
|
|
303
|
+
return best;
|
|
181
304
|
}
|
|
182
305
|
function stdev(id, biased = true) {
|
|
183
306
|
return Math.sqrt(variance(id, biased));
|
|
184
307
|
}
|
|
308
|
+
function moments(values) {
|
|
309
|
+
let p = 0;
|
|
310
|
+
let q = 0;
|
|
311
|
+
for (const v of values) p += v;
|
|
312
|
+
for (const v of values) q += v * v;
|
|
313
|
+
return [p, q];
|
|
314
|
+
}
|
|
185
315
|
function variance(id, biased = true) {
|
|
186
316
|
const values = id.filter((v) => !Number.isNaN(v));
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
317
|
+
const n = values.length;
|
|
318
|
+
if (!n) return NaN;
|
|
319
|
+
if (n < 2) return biased ? 0 : NaN;
|
|
320
|
+
const [p, q] = moments(values);
|
|
321
|
+
const mean = p / n;
|
|
322
|
+
return biased ? Math.max(0, q / n - mean * mean) : Math.max(0, q / (n - 1) - p / (n - 1) * mean);
|
|
191
323
|
}
|
|
192
324
|
function fill(id, value, index_from = 0, index_to) {
|
|
193
|
-
const
|
|
194
|
-
|
|
325
|
+
const start = index_from === void 0 || index_from === null || Number.isNaN(index_from) ? 0 : index_from;
|
|
326
|
+
const end = index_to === void 0 || index_to === null || Number.isNaN(index_to) ? id.length : index_to;
|
|
327
|
+
for (const i of [start, end]) {
|
|
328
|
+
if (i < 0 || i > id.length) throw new Error(`array.fill: index ${i} is out of bounds, array size is ${id.length}`);
|
|
329
|
+
}
|
|
330
|
+
for (let i = start; i < end; i++) {
|
|
195
331
|
id[i] = value;
|
|
196
332
|
}
|
|
197
333
|
}
|
|
@@ -199,9 +335,11 @@ function from(...values) {
|
|
|
199
335
|
return [...values];
|
|
200
336
|
}
|
|
201
337
|
function first(id) {
|
|
338
|
+
if (id.length === 0) throw new Error("Cannot call array.first() if array is empty");
|
|
202
339
|
return id[0];
|
|
203
340
|
}
|
|
204
341
|
function last(id) {
|
|
342
|
+
if (id.length === 0) throw new Error("Cannot call array.last() if array is empty");
|
|
205
343
|
return id[id.length - 1];
|
|
206
344
|
}
|
|
207
345
|
function some(id) {
|
|
@@ -237,6 +375,9 @@ function new_label(size2 = 0, initial_value) {
|
|
|
237
375
|
function new_linefill(size2 = 0, initial_value) {
|
|
238
376
|
return new_array(size2, initial_value);
|
|
239
377
|
}
|
|
378
|
+
function new_table(size2 = 0, initial_value) {
|
|
379
|
+
return new_array(size2, initial_value);
|
|
380
|
+
}
|
|
240
381
|
function abs(id) {
|
|
241
382
|
return id.map((x) => Math.abs(x));
|
|
242
383
|
}
|
|
@@ -290,85 +431,105 @@ function binary_search_rightmost(id, val) {
|
|
|
290
431
|
return at > 0 && compareSorted(id[at - 1], val) === 0 ? at - 1 : at;
|
|
291
432
|
}
|
|
292
433
|
function covariance(id1, id2, biased = true) {
|
|
293
|
-
if (id1.length === 0 || id2.length === 0) {
|
|
294
|
-
return NaN;
|
|
295
|
-
}
|
|
296
434
|
if (id1.length !== id2.length) {
|
|
297
435
|
return NaN;
|
|
298
436
|
}
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
|
|
437
|
+
const xs = [];
|
|
438
|
+
const ys = [];
|
|
439
|
+
for (let i = 0; i < id1.length; i++) {
|
|
440
|
+
if (Number.isNaN(id1[i]) || Number.isNaN(id2[i])) continue;
|
|
441
|
+
xs.push(id1[i]);
|
|
442
|
+
ys.push(id2[i]);
|
|
443
|
+
}
|
|
444
|
+
const n = xs.length;
|
|
445
|
+
if (!n || !biased && n < 2) return NaN;
|
|
446
|
+
let mean1 = 0;
|
|
447
|
+
let mean2 = 0;
|
|
448
|
+
for (let i = 0; i < n; i++) {
|
|
449
|
+
mean1 += xs[i];
|
|
450
|
+
mean2 += ys[i];
|
|
451
|
+
}
|
|
452
|
+
mean1 /= n;
|
|
453
|
+
mean2 /= n;
|
|
302
454
|
let sum2 = 0;
|
|
303
455
|
for (let i = 0; i < n; i++) {
|
|
304
|
-
sum2 += (
|
|
456
|
+
sum2 += (xs[i] - mean1) * (ys[i] - mean2);
|
|
305
457
|
}
|
|
306
|
-
|
|
307
|
-
return sum2 / divisor;
|
|
458
|
+
return sum2 / (biased ? n : n - 1);
|
|
308
459
|
}
|
|
309
460
|
function percentile_linear_interpolation(id, percentage) {
|
|
310
|
-
if (id.length === 0) {
|
|
461
|
+
if (id.length === 0 || Number.isNaN(percentage)) {
|
|
311
462
|
return NaN;
|
|
312
463
|
}
|
|
464
|
+
checkPercentage("percentile_linear_interpolation", percentage);
|
|
313
465
|
const s = sortedNaLast(id);
|
|
314
466
|
const n = s.length;
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (pos
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
467
|
+
let pos = n * percentage / 100 + 0.5;
|
|
468
|
+
const nearest = Math.round(pos);
|
|
469
|
+
if (Math.abs(pos - nearest) < 1e-9) pos = nearest;
|
|
470
|
+
if (pos <= 1) return s[0];
|
|
471
|
+
if (pos >= n) return s[n - 1];
|
|
472
|
+
const lower = Math.floor(pos);
|
|
473
|
+
const frac = pos - lower;
|
|
474
|
+
if (frac === 0) return s[lower - 1];
|
|
475
|
+
if (Number.isNaN(s[n - 1])) return NaN;
|
|
476
|
+
return s[lower - 1] * (1 - frac) + s[lower] * frac;
|
|
322
477
|
}
|
|
323
478
|
function sortedNaLast(id) {
|
|
324
479
|
const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);
|
|
325
480
|
return [...numbers, ...Array(id.length - numbers.length).fill(NaN)];
|
|
326
481
|
}
|
|
482
|
+
function checkPercentage(name, percentage) {
|
|
483
|
+
if (!(percentage >= 0 && percentage <= 100)) {
|
|
484
|
+
throw new Error(`array.${name}: percentage ${percentage} must be between 0 and 100`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
327
487
|
function percentile_nearest_rank(id, percentage) {
|
|
328
488
|
if (id.length === 0) {
|
|
329
489
|
return NaN;
|
|
330
490
|
}
|
|
491
|
+
const pct = Number.isNaN(percentage) ? 0 : percentage;
|
|
492
|
+
checkPercentage("percentile_nearest_rank", pct);
|
|
331
493
|
const s = sortedNaLast(id);
|
|
332
|
-
const rank = Math.min(s.length, Math.max(1, Math.ceil(
|
|
494
|
+
const rank = Math.min(s.length, Math.max(1, Math.ceil(pct * s.length / 100)));
|
|
333
495
|
return s[rank - 1];
|
|
334
496
|
}
|
|
335
497
|
function percentrank(id, index) {
|
|
336
|
-
|
|
498
|
+
const i = Number.isNaN(index) ? 0 : Math.trunc(index);
|
|
499
|
+
if (id.length === 0) {
|
|
337
500
|
return NaN;
|
|
338
501
|
}
|
|
339
|
-
|
|
340
|
-
|
|
502
|
+
if (i < 0 || i >= id.length) {
|
|
503
|
+
throw new Error(`array.percentrank: index ${i} is out of bounds, array size is ${id.length}`);
|
|
504
|
+
}
|
|
505
|
+
if (id.length === 1) {
|
|
506
|
+
return NaN;
|
|
507
|
+
}
|
|
508
|
+
const value = id[i];
|
|
509
|
+
if (Number.isNaN(value)) {
|
|
341
510
|
return NaN;
|
|
342
511
|
}
|
|
343
512
|
let count = 0;
|
|
344
|
-
for (
|
|
345
|
-
if (
|
|
346
|
-
count++;
|
|
347
|
-
}
|
|
513
|
+
for (const v of id) {
|
|
514
|
+
if (v <= value) count++;
|
|
348
515
|
}
|
|
349
|
-
return count / id.length
|
|
516
|
+
return (count - 1) * 100 / (id.length - 1);
|
|
350
517
|
}
|
|
351
518
|
function sort_indices(id, order = "asc") {
|
|
352
|
-
|
|
353
|
-
indices.sort((a, b) => {
|
|
354
|
-
if (order === "asc") {
|
|
355
|
-
return id[a] - id[b];
|
|
356
|
-
} else {
|
|
357
|
-
return id[b] - id[a];
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
return indices;
|
|
519
|
+
return sortedPositions(id, order);
|
|
361
520
|
}
|
|
362
521
|
function standardize(id) {
|
|
363
|
-
|
|
364
|
-
|
|
522
|
+
const values = id.filter((v) => !Number.isNaN(v));
|
|
523
|
+
if (!values.length) {
|
|
524
|
+
return id.map(() => NaN);
|
|
365
525
|
}
|
|
366
|
-
const
|
|
367
|
-
const
|
|
526
|
+
const [p, q] = moments(values);
|
|
527
|
+
const mean = p / values.length;
|
|
528
|
+
const stdDev = Math.sqrt(Math.max(0, q / values.length - mean * mean));
|
|
368
529
|
if (stdDev === 0) {
|
|
369
|
-
return id.map(() => NaN);
|
|
530
|
+
return id.map((v) => Number.isNaN(v) ? NaN : 1);
|
|
370
531
|
}
|
|
371
|
-
return id.map((
|
|
532
|
+
return id.map((v) => Number.isNaN(v) ? NaN : (v - mean) / stdDev);
|
|
372
533
|
}
|
|
373
534
|
function newtype(size2 = 0, initial_value) {
|
|
374
535
|
return new_array(size2, initial_value);
|