@uwrl/qc-utils 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +252 -242
- package/dist/index.umd.cjs +3 -3
- package/dist/types.d.ts +51 -0
- package/dist/utils/__tests__/ellapsedTime.spec.d.ts +1 -0
- package/dist/utils/__tests__/format.spec.d.ts +1 -0
- package/dist/utils/__tests__/notifications.spec.d.ts +1 -0
- package/dist/utils/__tests__/observationsUtils.spec.d.ts +1 -0
- package/dist/utils/ellapsedTime.d.ts +0 -0
- package/dist/utils/format.d.ts +0 -0
- package/dist/utils/notifications.d.ts +46 -0
- package/dist/utils/observationsUtils.d.ts +0 -0
- package/dist/utils/plotting/__tests__/delete-data.worker.spec.d.ts +1 -0
- package/dist/utils/plotting/__tests__/mock.d.ts +4 -0
- package/dist/utils/plotting/__tests__/observationRecord.spec.d.ts +1 -0
- package/dist/utils/plotting/add-data.worker.d.ts +0 -0
- package/dist/utils/plotting/delete-data.worker.d.ts +0 -0
- package/dist/utils/plotting/drift-correction.worker.d.ts +0 -0
- package/dist/utils/plotting/fill-gaps.worker.d.ts +0 -0
- package/dist/utils/plotting/interpolate.worker.d.ts +0 -0
- package/dist/utils/plotting/observationRecord.d.ts +170 -0
- package/dist/utils/plotting/shift-datetimes.worker.d.ts +0 -0
- package/package.json +7 -4
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -1,119 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var f = /* @__PURE__ */ ((s) => (s.ADD_POINTS = "ADD_POINTS", s.CHANGE_VALUES = "CHANGE_VALUES", s.DELETE_POINTS = "DELETE_POINTS", s.DRIFT_CORRECTION = "DRIFT_CORRECTION", s.INTERPOLATE = "INTERPOLATE", s.SHIFT_DATETIMES = "SHIFT_DATETIMES", s.FILL_GAPS = "FILL_GAPS", s))(f || {}), T = /* @__PURE__ */ ((s) => (s.FIND_GAPS = "FIND_GAPS", s.PERSISTENCE = "PERSISTENCE", s.RATE_OF_CHANGE = "RATE_OF_CHANGE", s.VALUE_THRESHOLD = "VALUE_THRESHOLD", s))(T || {}), X = /* @__PURE__ */ ((s) => (s.LT = "Less than", s.LTE = "Less than or equal to", s.GT = "Greater than", s.GTE = "Greater than or equal to", s.E = "Equal", s.START = "Start datetime", s.END = "End datetime", s))(X || {});
|
|
2
|
+
const x = {
|
|
3
|
+
"Less than": (s, t) => s < t,
|
|
4
|
+
"Less than or equal to": (s, t) => s <= t,
|
|
5
|
+
"Greater than": (s, t) => s > t,
|
|
6
|
+
"Greater than or equal to": (s, t) => s >= t,
|
|
7
|
+
Equal: (s, t) => s == t,
|
|
8
|
+
"Start datetime": (s, t) => s == t,
|
|
9
|
+
"End datetime": (s, t) => s == t
|
|
10
|
+
};
|
|
11
|
+
var y = /* @__PURE__ */ ((s) => (s.ADD = "ADD", s.SUB = "SUB", s.MULT = "MULT", s.DIV = "DIV", s.ASSIGN = "ASSIGN", s))(y || {}), G = /* @__PURE__ */ ((s) => (s.LT = "Less than", s.LTE = "Less than or equal to", s.GT = "Greater than", s.GTE = "Greater than or equal to", s.E = "Equal", s))(G || {});
|
|
12
|
+
const U = {
|
|
13
|
+
"Less than": (s, t) => s < t,
|
|
14
|
+
"Less than or equal to": (s, t) => s <= t,
|
|
15
|
+
"Greater than": (s, t) => s > t,
|
|
16
|
+
"Greater than or equal to": (s, t) => s >= t,
|
|
17
|
+
Equal: (s, t) => s == t
|
|
18
|
+
}, I = `(function(){"use strict";self.onmessage=o=>{const{bufferX:s,bufferY:n,outputBufferX:u,outputBufferY:f,start:l,end:y,deleteSegment:a,startTarget:c}=o.data,A=new Float64Array(s),d=new Float32Array(n),g=new Float64Array(u),p=new Float32Array(f);let e=0,r=c;for(let t=l;t<=y;t++)e<a.length&&t===a[e]?e++:(g[r]=A[t],p[r]=d[t],r++);self.postMessage("Done")}})();
|
|
19
|
+
`, b = typeof self < "u" && self.Blob && new Blob([I], { type: "text/javascript;charset=utf-8" });
|
|
20
|
+
function M(s) {
|
|
4
21
|
let t;
|
|
5
22
|
try {
|
|
6
23
|
if (t = b && (self.URL || self.webkitURL).createObjectURL(b), !t) throw "";
|
|
7
|
-
const
|
|
8
|
-
name:
|
|
24
|
+
const a = new Worker(t, {
|
|
25
|
+
name: s?.name
|
|
9
26
|
});
|
|
10
|
-
return
|
|
27
|
+
return a.addEventListener("error", () => {
|
|
11
28
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
12
|
-
}),
|
|
29
|
+
}), a;
|
|
13
30
|
} catch {
|
|
14
31
|
return new Worker(
|
|
15
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
32
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(I),
|
|
16
33
|
{
|
|
17
|
-
name:
|
|
34
|
+
name: s?.name
|
|
18
35
|
}
|
|
19
36
|
);
|
|
20
37
|
} finally {
|
|
21
38
|
t && (self.URL || self.webkitURL).revokeObjectURL(t);
|
|
22
39
|
}
|
|
23
40
|
}
|
|
24
|
-
const
|
|
25
|
-
`,
|
|
26
|
-
function
|
|
41
|
+
const N = `(function(){"use strict";self.onmessage=function(e){const{bufferX:f,bufferY:t,outputBufferX:u,outputBufferY:s}=e.data;self.postMessage("Done")}})();
|
|
42
|
+
`, R = typeof self < "u" && self.Blob && new Blob([N], { type: "text/javascript;charset=utf-8" });
|
|
43
|
+
function C(s) {
|
|
27
44
|
let t;
|
|
28
45
|
try {
|
|
29
|
-
if (t =
|
|
30
|
-
const
|
|
31
|
-
name:
|
|
46
|
+
if (t = R && (self.URL || self.webkitURL).createObjectURL(R), !t) throw "";
|
|
47
|
+
const a = new Worker(t, {
|
|
48
|
+
name: s?.name
|
|
32
49
|
});
|
|
33
|
-
return
|
|
50
|
+
return a.addEventListener("error", () => {
|
|
34
51
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
35
|
-
}),
|
|
52
|
+
}), a;
|
|
36
53
|
} catch {
|
|
37
54
|
return new Worker(
|
|
38
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
55
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(N),
|
|
39
56
|
{
|
|
40
|
-
name:
|
|
57
|
+
name: s?.name
|
|
41
58
|
}
|
|
42
59
|
);
|
|
43
60
|
} finally {
|
|
44
61
|
t && (self.URL || self.webkitURL).revokeObjectURL(t);
|
|
45
62
|
}
|
|
46
63
|
}
|
|
47
|
-
const
|
|
48
|
-
let
|
|
49
|
-
for (;
|
|
50
|
-
const
|
|
51
|
-
|
|
64
|
+
const k = (s, t) => {
|
|
65
|
+
let a = 0, e = s.length;
|
|
66
|
+
for (; a < e; ) {
|
|
67
|
+
const n = a + e >> 1;
|
|
68
|
+
s[n] < t ? a = n + 1 : e = n;
|
|
52
69
|
}
|
|
53
|
-
return
|
|
54
|
-
}, B = (
|
|
55
|
-
let
|
|
56
|
-
for (;
|
|
57
|
-
const
|
|
58
|
-
|
|
70
|
+
return a;
|
|
71
|
+
}, B = (s, t) => {
|
|
72
|
+
let a = 0, e = s.length;
|
|
73
|
+
for (; a < e; ) {
|
|
74
|
+
const n = a + e >> 1;
|
|
75
|
+
s[n] > t ? e = n : a = n + 1;
|
|
59
76
|
}
|
|
60
|
-
return
|
|
61
|
-
},
|
|
62
|
-
const
|
|
63
|
-
console.log(` Done in ${(
|
|
64
|
-
const
|
|
65
|
-
return { response: e, duration:
|
|
66
|
-
},
|
|
67
|
-
s:
|
|
68
|
-
m:
|
|
69
|
-
h:
|
|
70
|
-
D
|
|
71
|
-
W:
|
|
72
|
-
M:
|
|
73
|
-
Y:
|
|
74
|
-
},
|
|
75
|
-
if (
|
|
76
|
-
const e = new Date(
|
|
77
|
+
return a - 1;
|
|
78
|
+
}, p = async (s, t) => {
|
|
79
|
+
const a = performance.now(), e = await s(), n = performance.now();
|
|
80
|
+
console.log(` Done in ${(n - a).toFixed(2)} ms`);
|
|
81
|
+
const r = +(n - a);
|
|
82
|
+
return { response: e, duration: r };
|
|
83
|
+
}, Y = 1, F = Y * 60, S = F * 60, D = S * 24, v = D * 7, H = S * 30, O = D * 365, A = {
|
|
84
|
+
s: Y,
|
|
85
|
+
m: F,
|
|
86
|
+
h: S,
|
|
87
|
+
D,
|
|
88
|
+
W: v,
|
|
89
|
+
M: H,
|
|
90
|
+
Y: O
|
|
91
|
+
}, V = (s, t, a) => {
|
|
92
|
+
if (a === "M") {
|
|
93
|
+
const e = new Date(s);
|
|
77
94
|
return e.setMonth(e.getMonth() + t), e.getTime();
|
|
78
|
-
} else if (
|
|
79
|
-
const e = new Date(
|
|
95
|
+
} else if (a === "Y") {
|
|
96
|
+
const e = new Date(s);
|
|
80
97
|
return e.setFullYear(e.getFullYear() + t), e.getTime();
|
|
81
98
|
} else
|
|
82
|
-
return
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
"Less than or equal to": (o, t) => o <= t,
|
|
86
|
-
"Greater than": (o, t) => o > t,
|
|
87
|
-
"Greater than or equal to": (o, t) => o >= t,
|
|
88
|
-
Equal: (o, t) => o == t,
|
|
89
|
-
"Start datetime": (o, t) => o == t,
|
|
90
|
-
"End datetime": (o, t) => o == t
|
|
91
|
-
}, k = {
|
|
92
|
-
"Less than": (o, t) => o < t,
|
|
93
|
-
"Less than or equal to": (o, t) => o <= t,
|
|
94
|
-
"Greater than": (o, t) => o > t,
|
|
95
|
-
"Greater than or equal to": (o, t) => o >= t,
|
|
96
|
-
Equal: (o, t) => o == t
|
|
97
|
-
}, g = 20 * 1e3, C = ["date", "value", "qualifier"];
|
|
98
|
-
class G {
|
|
99
|
+
return s + t * A[a] * 1e3;
|
|
100
|
+
}, L = 20 * 1e3, j = ["date", "value", "qualifier"];
|
|
101
|
+
class q {
|
|
99
102
|
/** The generated dataset to be used for plotting */
|
|
100
103
|
dataset = {
|
|
101
|
-
dimensions:
|
|
104
|
+
dimensions: j,
|
|
102
105
|
source: {
|
|
103
106
|
x: new Float64Array(
|
|
104
107
|
new SharedArrayBuffer(
|
|
105
|
-
|
|
108
|
+
L * Float64Array.BYTES_PER_ELEMENT,
|
|
106
109
|
{
|
|
107
|
-
maxByteLength:
|
|
110
|
+
maxByteLength: L * Float64Array.BYTES_PER_ELEMENT
|
|
108
111
|
// Max size the array can reach
|
|
109
112
|
}
|
|
110
113
|
)
|
|
111
114
|
),
|
|
112
115
|
y: new Float32Array(
|
|
113
116
|
new SharedArrayBuffer(
|
|
114
|
-
|
|
117
|
+
L * Float32Array.BYTES_PER_ELEMENT,
|
|
115
118
|
{
|
|
116
|
-
maxByteLength:
|
|
119
|
+
maxByteLength: L * Float32Array.BYTES_PER_ELEMENT
|
|
117
120
|
// Max size the array can reach
|
|
118
121
|
}
|
|
119
122
|
)
|
|
@@ -131,10 +134,10 @@ class G {
|
|
|
131
134
|
if (!t)
|
|
132
135
|
return;
|
|
133
136
|
this.isLoading = !0;
|
|
134
|
-
const
|
|
137
|
+
const a = await p(() => {
|
|
135
138
|
this._growBuffer(t.datetimes.length), this._resizeTo(t.datetimes.length), this.dataX.set(t.datetimes), this.dataY.set(t.dataValues);
|
|
136
139
|
});
|
|
137
|
-
this.loadingTime =
|
|
140
|
+
this.loadingTime = a.duration, this.history.length = 0, this.isLoading = !1;
|
|
138
141
|
}
|
|
139
142
|
get dataX() {
|
|
140
143
|
return this.dataset.source.x;
|
|
@@ -159,23 +162,23 @@ class G {
|
|
|
159
162
|
* @param newLength The total number of elements that the view will contain
|
|
160
163
|
*/
|
|
161
164
|
_growBuffer(t) {
|
|
162
|
-
const
|
|
165
|
+
const a = t * Float64Array.BYTES_PER_ELEMENT;
|
|
163
166
|
let e = this.dataX.buffer.byteLength;
|
|
164
|
-
for (;
|
|
165
|
-
e +=
|
|
167
|
+
for (; a > e; )
|
|
168
|
+
e += L * Float64Array.BYTES_PER_ELEMENT;
|
|
166
169
|
if (e * Float64Array.BYTES_PER_ELEMENT > this.dataX.buffer.maxByteLength) {
|
|
167
|
-
const
|
|
170
|
+
const n = new SharedArrayBuffer(
|
|
168
171
|
this.dataX.buffer.byteLength,
|
|
169
172
|
{
|
|
170
173
|
maxByteLength: e * Float64Array.BYTES_PER_ELEMENT
|
|
171
174
|
}
|
|
172
|
-
),
|
|
175
|
+
), r = new SharedArrayBuffer(
|
|
173
176
|
this.dataY.buffer.byteLength,
|
|
174
177
|
{
|
|
175
178
|
maxByteLength: e * Float32Array.BYTES_PER_ELEMENT
|
|
176
179
|
}
|
|
177
|
-
),
|
|
178
|
-
|
|
180
|
+
), o = new Float64Array(n), i = new Float32Array(r);
|
|
181
|
+
o.set(this.dataX), i.set(this.dataY), this.dataset.source.x = o, this.dataset.source.y = i;
|
|
179
182
|
}
|
|
180
183
|
this.dataX.buffer.byteLength < t * Float64Array.BYTES_PER_ELEMENT && (this.dataX.buffer.grow(t * Float64Array.BYTES_PER_ELEMENT), this.dataY.buffer.grow(t * Float32Array.BYTES_PER_ELEMENT));
|
|
181
184
|
}
|
|
@@ -190,16 +193,16 @@ class G {
|
|
|
190
193
|
* @returns
|
|
191
194
|
*/
|
|
192
195
|
async reloadHistory(t) {
|
|
193
|
-
const
|
|
194
|
-
await this.reload(), await this.dispatch(
|
|
196
|
+
const a = this.history.slice(0, t + 1);
|
|
197
|
+
await this.reload(), await this.dispatch(a.map((e) => [e.method, ...e.args || []]));
|
|
195
198
|
}
|
|
196
199
|
/**
|
|
197
200
|
* Remove a history item
|
|
198
201
|
* @param index
|
|
199
202
|
*/
|
|
200
203
|
async removeHistoryItem(t) {
|
|
201
|
-
const
|
|
202
|
-
|
|
204
|
+
const a = [...this.history];
|
|
205
|
+
a.splice(t, 1), await this.reload(), await this.dispatch(a.map((e) => [e.method, ...e.args || []]));
|
|
203
206
|
}
|
|
204
207
|
get beginTime() {
|
|
205
208
|
return this.dataset.source.x.length ? new Date(this.dataset.source.x[0]) : null;
|
|
@@ -208,88 +211,88 @@ class G {
|
|
|
208
211
|
return this.dataset.source.x.length ? new Date(this.dataset.source.x[this.dataset.source.x.length - 1]) : null;
|
|
209
212
|
}
|
|
210
213
|
/** Dispatch an operation and log its signature in hisotry */
|
|
211
|
-
async dispatch(t, ...
|
|
214
|
+
async dispatch(t, ...a) {
|
|
212
215
|
const e = {
|
|
213
|
-
ADD_POINTS: this._addDataPoints,
|
|
214
|
-
CHANGE_VALUES: this._changeValues,
|
|
215
|
-
DELETE_POINTS: this._deleteDataPoints,
|
|
216
|
-
DRIFT_CORRECTION: this._driftCorrection,
|
|
217
|
-
INTERPOLATE: this._interpolate,
|
|
218
|
-
SHIFT_DATETIMES: this._shift,
|
|
219
|
-
FILL_GAPS: this._fillGaps
|
|
220
|
-
},
|
|
221
|
-
ADD_POINTS: "mdi-plus",
|
|
222
|
-
CHANGE_VALUES: "mdi-pencil",
|
|
223
|
-
DELETE_POINTS: "mdi-trash-can",
|
|
224
|
-
DRIFT_CORRECTION: "mdi-chart-sankey",
|
|
225
|
-
INTERPOLATE: "mdi-transit-connection-horizontal",
|
|
226
|
-
SHIFT_DATETIMES: "mdi-calendar",
|
|
227
|
-
FILL_GAPS: "mdi-keyboard-space"
|
|
216
|
+
[f.ADD_POINTS]: this._addDataPoints,
|
|
217
|
+
[f.CHANGE_VALUES]: this._changeValues,
|
|
218
|
+
[f.DELETE_POINTS]: this._deleteDataPoints,
|
|
219
|
+
[f.DRIFT_CORRECTION]: this._driftCorrection,
|
|
220
|
+
[f.INTERPOLATE]: this._interpolate,
|
|
221
|
+
[f.SHIFT_DATETIMES]: this._shift,
|
|
222
|
+
[f.FILL_GAPS]: this._fillGaps
|
|
223
|
+
}, n = {
|
|
224
|
+
[f.ADD_POINTS]: "mdi-plus",
|
|
225
|
+
[f.CHANGE_VALUES]: "mdi-pencil",
|
|
226
|
+
[f.DELETE_POINTS]: "mdi-trash-can",
|
|
227
|
+
[f.DRIFT_CORRECTION]: "mdi-chart-sankey",
|
|
228
|
+
[f.INTERPOLATE]: "mdi-transit-connection-horizontal",
|
|
229
|
+
[f.SHIFT_DATETIMES]: "mdi-calendar",
|
|
230
|
+
[f.FILL_GAPS]: "mdi-keyboard-space"
|
|
228
231
|
};
|
|
229
|
-
let
|
|
232
|
+
let r = [];
|
|
230
233
|
try {
|
|
231
234
|
if (Array.isArray(t)) {
|
|
232
|
-
for (let
|
|
233
|
-
const i = t[
|
|
235
|
+
for (let o = 0; o < t.length; o++) {
|
|
236
|
+
const i = t[o][0], h = t[o].slice(1, t[o].length), l = {
|
|
234
237
|
method: i,
|
|
235
238
|
args: h,
|
|
236
|
-
icon:
|
|
239
|
+
icon: n[i],
|
|
237
240
|
isLoading: !1
|
|
238
241
|
};
|
|
239
242
|
this.history.push(l);
|
|
240
243
|
}
|
|
241
|
-
for (let
|
|
242
|
-
const i = this.history[
|
|
244
|
+
for (let o = this.history.length - t.length; o < this.history.length; o++) {
|
|
245
|
+
const i = this.history[o];
|
|
243
246
|
i.isLoading = !0;
|
|
244
|
-
const h = await
|
|
247
|
+
const h = await p(async () => await e[i.method].apply(
|
|
245
248
|
this,
|
|
246
249
|
i.args
|
|
247
250
|
));
|
|
248
|
-
i.duration = h.duration, i.isLoading = !1,
|
|
251
|
+
i.duration = h.duration, i.isLoading = !1, r.push(h.response);
|
|
249
252
|
}
|
|
250
253
|
} else {
|
|
251
|
-
const
|
|
254
|
+
const o = {
|
|
252
255
|
method: t,
|
|
253
|
-
args:
|
|
254
|
-
icon:
|
|
256
|
+
args: a,
|
|
257
|
+
icon: n[t],
|
|
255
258
|
isLoading: !0
|
|
256
259
|
};
|
|
257
|
-
this.history.push(
|
|
258
|
-
const i = await
|
|
259
|
-
|
|
260
|
+
this.history.push(o);
|
|
261
|
+
const i = await p(async () => await e[t].apply(this, a));
|
|
262
|
+
r = i.response, o.duration = i.duration, o.isLoading = !1;
|
|
260
263
|
}
|
|
261
|
-
} catch (
|
|
264
|
+
} catch (o) {
|
|
262
265
|
console.log(
|
|
263
266
|
`Failed to execute operation: ${t} with arguments: `,
|
|
264
|
-
|
|
265
|
-
), console.log(
|
|
267
|
+
a
|
|
268
|
+
), console.log(o);
|
|
266
269
|
}
|
|
267
|
-
return
|
|
270
|
+
return r;
|
|
268
271
|
}
|
|
269
272
|
/** Filter operations do not transform the data and are not logged in history */
|
|
270
|
-
async dispatchFilter(t, ...
|
|
273
|
+
async dispatchFilter(t, ...a) {
|
|
271
274
|
const e = {
|
|
272
|
-
FIND_GAPS: this._findGaps,
|
|
273
|
-
VALUE_THRESHOLD: this._valueThreshold,
|
|
274
|
-
PERSISTENCE: this._persistence,
|
|
275
|
-
RATE_OF_CHANGE: this._rateOfChange
|
|
275
|
+
[T.FIND_GAPS]: this._findGaps,
|
|
276
|
+
[T.VALUE_THRESHOLD]: this._valueThreshold,
|
|
277
|
+
[T.PERSISTENCE]: this._persistence,
|
|
278
|
+
[T.RATE_OF_CHANGE]: this._rateOfChange
|
|
276
279
|
};
|
|
277
|
-
let
|
|
280
|
+
let n = [];
|
|
278
281
|
try {
|
|
279
282
|
if (Array.isArray(t))
|
|
280
|
-
for (let
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
+
for (let r = 0; r < t.length; r++) {
|
|
284
|
+
const o = t[r][0], i = t[r].slice(1, t[r].length), h = await e[o].apply(this, i);
|
|
285
|
+
n.push(h);
|
|
283
286
|
}
|
|
284
287
|
else
|
|
285
|
-
|
|
286
|
-
} catch (
|
|
288
|
+
n = await e[t].apply(this, a);
|
|
289
|
+
} catch (r) {
|
|
287
290
|
console.log(
|
|
288
291
|
`Failed to execute filter operation: ${t} with arguments: `,
|
|
289
|
-
|
|
290
|
-
), console.log(
|
|
292
|
+
a
|
|
293
|
+
), console.log(r);
|
|
291
294
|
}
|
|
292
|
-
return
|
|
295
|
+
return n;
|
|
293
296
|
}
|
|
294
297
|
/**
|
|
295
298
|
* @param index An array containing the list of index of values to perform the operations on.
|
|
@@ -297,45 +300,45 @@ class G {
|
|
|
297
300
|
* @param value The value to use in the operation
|
|
298
301
|
* @returns The modified DataFrame
|
|
299
302
|
*/
|
|
300
|
-
_changeValues(t,
|
|
301
|
-
const
|
|
302
|
-
switch (
|
|
303
|
-
case
|
|
304
|
-
return
|
|
305
|
-
case
|
|
303
|
+
_changeValues(t, a, e) {
|
|
304
|
+
const n = (r) => {
|
|
305
|
+
switch (a) {
|
|
306
|
+
case y.ADD:
|
|
307
|
+
return r + e;
|
|
308
|
+
case y.ASSIGN:
|
|
306
309
|
return e;
|
|
307
|
-
case
|
|
308
|
-
return
|
|
309
|
-
case
|
|
310
|
-
return
|
|
311
|
-
case
|
|
312
|
-
return
|
|
310
|
+
case y.DIV:
|
|
311
|
+
return r / e;
|
|
312
|
+
case y.MULT:
|
|
313
|
+
return r * e;
|
|
314
|
+
case y.SUB:
|
|
315
|
+
return r - e;
|
|
313
316
|
default:
|
|
314
|
-
return
|
|
317
|
+
return r;
|
|
315
318
|
}
|
|
316
319
|
};
|
|
317
|
-
t.forEach((
|
|
318
|
-
this.dataset.source.y[
|
|
320
|
+
t.forEach((r) => {
|
|
321
|
+
this.dataset.source.y[r] = n(this.dataset.source.y[r]);
|
|
319
322
|
});
|
|
320
323
|
}
|
|
321
324
|
_interpolate(t) {
|
|
322
325
|
this._getConsecutiveGroups(t).forEach((e) => {
|
|
323
|
-
const
|
|
324
|
-
let
|
|
326
|
+
const n = e[0], r = e[e.length - 1];
|
|
327
|
+
let o = Math.max(0, n - 1), i = Math.min(this.dataset.source.y.length - 1, r + 1);
|
|
325
328
|
const h = this.dataset.source.x, l = this.dataset.source.y;
|
|
326
329
|
for (let c = 0; c < e.length; c++)
|
|
327
330
|
this.dataset.source.y[e[c]] = this._interpolateLinear(
|
|
328
331
|
h[e[c]],
|
|
329
|
-
h[
|
|
330
|
-
l[
|
|
332
|
+
h[o],
|
|
333
|
+
l[o],
|
|
331
334
|
h[i],
|
|
332
335
|
l[i]
|
|
333
336
|
);
|
|
334
337
|
});
|
|
335
338
|
}
|
|
336
339
|
/** Interpolate existing values in the data source */
|
|
337
|
-
_interpolateLinear(t,
|
|
338
|
-
return e + (t -
|
|
340
|
+
_interpolateLinear(t, a, e, n, r) {
|
|
341
|
+
return e + (t - a) * (r - e) / (n - a);
|
|
339
342
|
}
|
|
340
343
|
/**
|
|
341
344
|
* Shifts the selected indexes by specified amount of units. Elements are reinserted according to their datetime.
|
|
@@ -344,34 +347,34 @@ class G {
|
|
|
344
347
|
* @param unit {@link TimeUnit}
|
|
345
348
|
* @returns
|
|
346
349
|
*/
|
|
347
|
-
async _shift(t,
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
this.dataY[
|
|
350
|
+
async _shift(t, a, e) {
|
|
351
|
+
const n = t.map((r) => [
|
|
352
|
+
V(this.dataX[r], a, e),
|
|
353
|
+
this.dataY[r]
|
|
351
354
|
]);
|
|
352
|
-
await this._deleteDataPoints(t), await this._addDataPoints(
|
|
355
|
+
await this._deleteDataPoints(t), await this._addDataPoints(n);
|
|
353
356
|
}
|
|
354
|
-
async _fillGapsV2(t,
|
|
355
|
-
const
|
|
357
|
+
async _fillGapsV2(t, a, e, n) {
|
|
358
|
+
const r = navigator.hardwareConcurrency || 1, o = [], i = [], h = this.dataX.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
|
|
356
359
|
maxByteLength: this.dataX.buffer.maxByteLength
|
|
357
360
|
}), c = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
|
|
358
361
|
maxByteLength: this.dataY.buffer.maxByteLength
|
|
359
362
|
});
|
|
360
|
-
for (let u = 0; u <
|
|
363
|
+
for (let u = 0; u < r; u++)
|
|
361
364
|
i.push(
|
|
362
|
-
new Promise((
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
+
new Promise((d) => {
|
|
366
|
+
const E = new C();
|
|
367
|
+
o.push(E), E.postMessage({
|
|
365
368
|
bufferX: this.dataX.buffer,
|
|
366
369
|
bufferY: this.dataY.buffer,
|
|
367
370
|
outputBufferX: l,
|
|
368
371
|
outputBufferY: c
|
|
369
|
-
}),
|
|
370
|
-
|
|
372
|
+
}), E.onmessage = (g) => {
|
|
373
|
+
d(g.data);
|
|
371
374
|
};
|
|
372
375
|
})
|
|
373
376
|
);
|
|
374
|
-
await Promise.all(i),
|
|
377
|
+
await Promise.all(i), o.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
|
|
375
378
|
}
|
|
376
379
|
/**
|
|
377
380
|
* Find gaps and fill them with placeholder value
|
|
@@ -381,20 +384,20 @@ class G {
|
|
|
381
384
|
* @returns
|
|
382
385
|
*/
|
|
383
386
|
// TODO: this needs to be improved using web workers
|
|
384
|
-
_fillGaps(t,
|
|
385
|
-
const
|
|
386
|
-
for (let
|
|
387
|
-
const i =
|
|
388
|
-
let
|
|
389
|
-
for (;
|
|
390
|
-
const
|
|
391
|
-
|
|
387
|
+
_fillGaps(t, a, e, n) {
|
|
388
|
+
const r = this._findGaps(t[0], t[1], n);
|
|
389
|
+
for (let o = r.length - 1; o >= 0; o--) {
|
|
390
|
+
const i = r[o], h = this.dataX[i[0]], l = this.dataX[i[1]], c = [], u = a[0] * A[a[1]] * 1e3;
|
|
391
|
+
let d = h + u;
|
|
392
|
+
for (; d < l; ) {
|
|
393
|
+
const E = e ? this._interpolateLinear(
|
|
394
|
+
d,
|
|
392
395
|
this.dataX[i[0]],
|
|
393
396
|
this.dataY[i[0]],
|
|
394
397
|
this.dataX[i[1]],
|
|
395
398
|
this.dataY[i[1]]
|
|
396
399
|
) : -9999;
|
|
397
|
-
c.push([
|
|
400
|
+
c.push([d, E]), d += u;
|
|
398
401
|
}
|
|
399
402
|
this._addDataPoints(c);
|
|
400
403
|
}
|
|
@@ -409,40 +412,40 @@ class G {
|
|
|
409
412
|
*/
|
|
410
413
|
// TODO: implement similar multithread solutions for other operations
|
|
411
414
|
async _deleteDataPoints(t) {
|
|
412
|
-
const
|
|
413
|
-
for (let u = 0; u <
|
|
414
|
-
const
|
|
415
|
-
|
|
415
|
+
const a = navigator.hardwareConcurrency || 1, e = Math.ceil(this.dataX.length / a), n = [], r = [];
|
|
416
|
+
for (let u = 0; u < a; u++) {
|
|
417
|
+
const d = u * e, E = Math.min((u + 1) * e - 1, this.dataX.length - 1), g = k(t, d), _ = B(t, E), m = t.slice(g, _ + 1);
|
|
418
|
+
r.push({ start: d, end: E, deleteSegment: m });
|
|
416
419
|
}
|
|
417
|
-
const
|
|
418
|
-
for (let u = 1; u <
|
|
419
|
-
|
|
420
|
+
const o = new Array(a).fill(0);
|
|
421
|
+
for (let u = 1; u < a; u++)
|
|
422
|
+
o[u] = o[u - 1] + r[u - 1].deleteSegment.length;
|
|
420
423
|
const i = [], h = this.dataX.length - t.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
|
|
421
424
|
maxByteLength: this.dataX.buffer.maxByteLength
|
|
422
425
|
}), c = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
|
|
423
426
|
maxByteLength: this.dataY.buffer.maxByteLength
|
|
424
427
|
});
|
|
425
|
-
for (let u = 0; u <
|
|
426
|
-
const { start:
|
|
428
|
+
for (let u = 0; u < a; u++) {
|
|
429
|
+
const { start: d, end: E, deleteSegment: g } = r[u], _ = d - o[u];
|
|
427
430
|
i.push(
|
|
428
431
|
new Promise((m) => {
|
|
429
|
-
const
|
|
430
|
-
|
|
432
|
+
const w = new M();
|
|
433
|
+
n.push(w), w.postMessage({
|
|
431
434
|
bufferX: this.dataX.buffer,
|
|
432
435
|
bufferY: this.dataY.buffer,
|
|
433
436
|
outputBufferX: l,
|
|
434
437
|
outputBufferY: c,
|
|
435
|
-
start:
|
|
436
|
-
end:
|
|
437
|
-
deleteSegment:
|
|
438
|
-
startTarget:
|
|
439
|
-
}),
|
|
440
|
-
m(
|
|
438
|
+
start: d,
|
|
439
|
+
end: E,
|
|
440
|
+
deleteSegment: g,
|
|
441
|
+
startTarget: _
|
|
442
|
+
}), w.onmessage = (P) => {
|
|
443
|
+
m(P.data);
|
|
441
444
|
};
|
|
442
445
|
})
|
|
443
446
|
);
|
|
444
447
|
}
|
|
445
|
-
await Promise.all(i),
|
|
448
|
+
await Promise.all(i), n.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
|
|
446
449
|
}
|
|
447
450
|
/**
|
|
448
451
|
*
|
|
@@ -450,10 +453,10 @@ class G {
|
|
|
450
453
|
* @param end The end index
|
|
451
454
|
* @param value The drift amount
|
|
452
455
|
*/
|
|
453
|
-
_driftCorrection(t,
|
|
454
|
-
const
|
|
455
|
-
for (let l = t; l <
|
|
456
|
-
this.dataset.source.y[l] =
|
|
456
|
+
_driftCorrection(t, a, e) {
|
|
457
|
+
const n = this.dataset.source.x, r = this.dataset.source.y, o = n[t], h = n[a] - o;
|
|
458
|
+
for (let l = t; l < a; l++)
|
|
459
|
+
this.dataset.source.y[l] = r[l] + e * ((n[l] - o) / h);
|
|
457
460
|
}
|
|
458
461
|
/** Traverses the index array and returns groups of consecutive values.
|
|
459
462
|
* i.e.: `[0, 1, 3, 4, 6] => [[0, 1], [3, 4], [6]]`
|
|
@@ -461,27 +464,27 @@ class G {
|
|
|
461
464
|
* @param index: the index array (sorted)
|
|
462
465
|
*/
|
|
463
466
|
_getConsecutiveGroups(t) {
|
|
464
|
-
const
|
|
465
|
-
return t.reduce((e,
|
|
466
|
-
const
|
|
467
|
-
return !
|
|
468
|
-
},
|
|
467
|
+
const a = [[]];
|
|
468
|
+
return t.reduce((e, n) => {
|
|
469
|
+
const r = e[e.length - 1];
|
|
470
|
+
return !r.length || n == r[r.length - 1] + 1 ? r.push(n) : e.push([n]), e;
|
|
471
|
+
}, a), a;
|
|
469
472
|
}
|
|
470
473
|
/**
|
|
471
474
|
* Adds data points. Their insert index is determined using `findFirstGreaterOrEqual` in the x-axis.
|
|
472
475
|
* @param dataPoints
|
|
473
476
|
*/
|
|
474
477
|
async _addDataPoints(t) {
|
|
475
|
-
const
|
|
476
|
-
this._growBuffer(
|
|
477
|
-
const e = t.map((
|
|
478
|
-
this._resizeTo(
|
|
479
|
-
let
|
|
480
|
-
for (let
|
|
481
|
-
const
|
|
482
|
-
for (let h = i; h >=
|
|
483
|
-
this.dataX[h +
|
|
484
|
-
|
|
478
|
+
const a = this.dataX.length + t.length;
|
|
479
|
+
this._growBuffer(a), t.sort((r, o) => r[0] - o[0]);
|
|
480
|
+
const e = t.map((r) => B(this.dataX, r[0]) + 1);
|
|
481
|
+
this._resizeTo(a), e.push(this.dataX.length);
|
|
482
|
+
let n = t.length;
|
|
483
|
+
for (let r = e.length - 1; r > 0; r--) {
|
|
484
|
+
const o = e[r - 1], i = e[r] - 1;
|
|
485
|
+
for (let h = i; h >= o; h--)
|
|
486
|
+
this.dataX[h + n] = this.dataX[h], this.dataY[h + n] = this.dataY[h];
|
|
487
|
+
n--, this.dataX[o + n] = t[r - 1][0], this.dataY[o + n] = t[r - 1][1];
|
|
485
488
|
}
|
|
486
489
|
}
|
|
487
490
|
// =======================
|
|
@@ -493,13 +496,13 @@ class G {
|
|
|
493
496
|
* @returns
|
|
494
497
|
*/
|
|
495
498
|
_valueThreshold(t) {
|
|
496
|
-
const
|
|
497
|
-
return this.dataset.source.y.forEach((e,
|
|
498
|
-
Object.keys(t).some((
|
|
499
|
+
const a = [];
|
|
500
|
+
return this.dataset.source.y.forEach((e, n) => {
|
|
501
|
+
Object.keys(t).some((r) => x[r]?.(
|
|
499
502
|
e,
|
|
500
|
-
t[
|
|
501
|
-
)) &&
|
|
502
|
-
}),
|
|
503
|
+
t[r]
|
|
504
|
+
)) && a.push(n);
|
|
505
|
+
}), a;
|
|
503
506
|
}
|
|
504
507
|
/**
|
|
505
508
|
*
|
|
@@ -507,14 +510,14 @@ class G {
|
|
|
507
510
|
* @param value
|
|
508
511
|
* @returns
|
|
509
512
|
*/
|
|
510
|
-
_rateOfChange(t,
|
|
511
|
-
const e = [],
|
|
512
|
-
for (let
|
|
513
|
-
const
|
|
514
|
-
|
|
513
|
+
_rateOfChange(t, a) {
|
|
514
|
+
const e = [], n = this.dataset.source.y;
|
|
515
|
+
for (let r = 1; r < n.length; r++) {
|
|
516
|
+
const o = n[r - 1], h = (n[r] - o) / Math.abs(o);
|
|
517
|
+
U[t]?.(
|
|
515
518
|
h,
|
|
516
|
-
|
|
517
|
-
) && e.push(
|
|
519
|
+
a
|
|
520
|
+
) && e.push(r);
|
|
518
521
|
}
|
|
519
522
|
return e;
|
|
520
523
|
}
|
|
@@ -525,16 +528,16 @@ class G {
|
|
|
525
528
|
* @param range If specified, the gaps will be found only within the range
|
|
526
529
|
* @returns
|
|
527
530
|
*/
|
|
528
|
-
_findGaps(t,
|
|
529
|
-
const
|
|
530
|
-
let
|
|
531
|
-
e?.[0] && e?.[1] && (
|
|
532
|
-
let h =
|
|
533
|
-
for (let l =
|
|
534
|
-
const c =
|
|
535
|
-
c - h > t *
|
|
531
|
+
_findGaps(t, a, e) {
|
|
532
|
+
const n = [], r = this.dataset.source.x;
|
|
533
|
+
let o = 0, i = r.length;
|
|
534
|
+
e?.[0] && e?.[1] && (o = e[0], i = e[1]);
|
|
535
|
+
let h = r[o];
|
|
536
|
+
for (let l = o + 1; l <= i; l++) {
|
|
537
|
+
const c = r[l];
|
|
538
|
+
c - h > t * A[a] * 1e3 && n.push([l - 1, l]), h = c;
|
|
536
539
|
}
|
|
537
|
-
return
|
|
540
|
+
return n;
|
|
538
541
|
}
|
|
539
542
|
/**
|
|
540
543
|
* Find points where the values are the same at least x times in a row
|
|
@@ -542,15 +545,22 @@ class G {
|
|
|
542
545
|
* @param range If specified, the points will be found only within the range
|
|
543
546
|
* @returns
|
|
544
547
|
*/
|
|
545
|
-
_persistence(t,
|
|
546
|
-
let e = [],
|
|
547
|
-
|
|
548
|
-
let i = r
|
|
549
|
-
for (let l =
|
|
550
|
-
|
|
548
|
+
_persistence(t, a) {
|
|
549
|
+
let e = [], n = this.dataset.source.y, r = 0, o = n.length;
|
|
550
|
+
a?.[0] && a?.[1] && (r = a[0], o = a[1]);
|
|
551
|
+
let i = n[r], h = [];
|
|
552
|
+
for (let l = r + 1; l < o; l++)
|
|
553
|
+
n[l] != i || l === o ? (h.length >= t && (e = [...e, ...h]), h = []) : h.push(l);
|
|
551
554
|
return e;
|
|
552
555
|
}
|
|
553
556
|
}
|
|
554
557
|
export {
|
|
555
|
-
|
|
558
|
+
f as EnumEditOperations,
|
|
559
|
+
T as EnumFilterOperations,
|
|
560
|
+
X as FilterOperation,
|
|
561
|
+
x as FilterOperationFn,
|
|
562
|
+
q as ObservationRecord,
|
|
563
|
+
y as Operator,
|
|
564
|
+
U as RateOfChangeComparator,
|
|
565
|
+
G as RateOfChangeOperation
|
|
556
566
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`,
|
|
3
|
-
`,
|
|
1
|
+
(function(d,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(d=typeof globalThis<"u"?globalThis:d||self,c(d["@uwrl/qc-utils"]={}))})(this,function(d){"use strict";var c=(s=>(s.ADD_POINTS="ADD_POINTS",s.CHANGE_VALUES="CHANGE_VALUES",s.DELETE_POINTS="DELETE_POINTS",s.DRIFT_CORRECTION="DRIFT_CORRECTION",s.INTERPOLATE="INTERPOLATE",s.SHIFT_DATETIMES="SHIFT_DATETIMES",s.FILL_GAPS="FILL_GAPS",s))(c||{}),L=(s=>(s.FIND_GAPS="FIND_GAPS",s.PERSISTENCE="PERSISTENCE",s.RATE_OF_CHANGE="RATE_OF_CHANGE",s.VALUE_THRESHOLD="VALUE_THRESHOLD",s))(L||{}),R=(s=>(s.LT="Less than",s.LTE="Less than or equal to",s.GT="Greater than",s.GTE="Greater than or equal to",s.E="Equal",s.START="Start datetime",s.END="End datetime",s))(R||{});const B={"Less than":(s,t)=>s<t,"Less than or equal to":(s,t)=>s<=t,"Greater than":(s,t)=>s>t,"Greater than or equal to":(s,t)=>s>=t,Equal:(s,t)=>s==t,"Start datetime":(s,t)=>s==t,"End datetime":(s,t)=>s==t};var g=(s=>(s.ADD="ADD",s.SUB="SUB",s.MULT="MULT",s.DIV="DIV",s.ASSIGN="ASSIGN",s))(g||{}),I=(s=>(s.LT="Less than",s.LTE="Less than or equal to",s.GT="Greater than",s.GTE="Greater than or equal to",s.E="Equal",s))(I||{});const N={"Less than":(s,t)=>s<t,"Less than or equal to":(s,t)=>s<=t,"Greater than":(s,t)=>s>t,"Greater than or equal to":(s,t)=>s>=t,Equal:(s,t)=>s==t},F=`(function(){"use strict";self.onmessage=o=>{const{bufferX:s,bufferY:n,outputBufferX:u,outputBufferY:f,start:l,end:y,deleteSegment:a,startTarget:c}=o.data,A=new Float64Array(s),d=new Float32Array(n),g=new Float64Array(u),p=new Float32Array(f);let e=0,r=c;for(let t=l;t<=y;t++)e<a.length&&t===a[e]?e++:(g[r]=A[t],p[r]=d[t],r++);self.postMessage("Done")}})();
|
|
2
|
+
`,Y=typeof self<"u"&&self.Blob&&new Blob([F],{type:"text/javascript;charset=utf-8"});function x(s){let t;try{if(t=Y&&(self.URL||self.webkitURL).createObjectURL(Y),!t)throw"";const a=new Worker(t,{name:s?.name});return a.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),a}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(F),{name:s?.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}const P=`(function(){"use strict";self.onmessage=function(e){const{bufferX:f,bufferY:t,outputBufferX:u,outputBufferY:s}=e.data;self.postMessage("Done")}})();
|
|
3
|
+
`,X=typeof self<"u"&&self.Blob&&new Blob([P],{type:"text/javascript;charset=utf-8"});function C(s){let t;try{if(t=X&&(self.URL||self.webkitURL).createObjectURL(X),!t)throw"";const a=new Worker(t,{name:s?.name});return a.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),a}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(P),{name:s?.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}const k=(s,t)=>{let a=0,e=s.length;for(;a<e;){const n=a+e>>1;s[n]<t?a=n+1:e=n}return a},G=(s,t)=>{let a=0,e=s.length;for(;a<e;){const n=a+e>>1;s[n]>t?e=n:a=n+1}return a-1},_=async(s,t)=>{const a=performance.now(),e=await s(),n=performance.now();console.log(` Done in ${(n-a).toFixed(2)} ms`);const r=+(n-a);return{response:e,duration:r}},U=1,M=U*60,p=M*60,w=p*24,O=w*7,v=p*30,H=w*365,A={s:U,m:M,h:p,D:w,W:O,M:v,Y:H},j=(s,t,a)=>{if(a==="M"){const e=new Date(s);return e.setMonth(e.getMonth()+t),e.getTime()}else if(a==="Y"){const e=new Date(s);return e.setFullYear(e.getFullYear()+t),e.getTime()}else return s+t*A[a]*1e3},T=20*1e3,q=["date","value","qualifier"];class V{dataset={dimensions:q,source:{x:new Float64Array(new SharedArrayBuffer(T*Float64Array.BYTES_PER_ELEMENT,{maxByteLength:T*Float64Array.BYTES_PER_ELEMENT})),y:new Float32Array(new SharedArrayBuffer(T*Float32Array.BYTES_PER_ELEMENT,{maxByteLength:T*Float32Array.BYTES_PER_ELEMENT}))}};history=[];loadingTime=null;isLoading=!0;rawData;constructor(t){this.history=[],this.rawData=t,this.loadData(this.rawData)}async loadData(t){if(!t)return;this.isLoading=!0;const a=await _(()=>{this._growBuffer(t.datetimes.length),this._resizeTo(t.datetimes.length),this.dataX.set(t.datetimes),this.dataY.set(t.dataValues)});this.loadingTime=a.duration,this.history.length=0,this.isLoading=!1}get dataX(){return this.dataset.source.x}get dataY(){return this.dataset.source.y}_resizeTo(t){this.dataset.source.x=new Float64Array(this.dataset.source.x.buffer).subarray(0,t),this.dataset.source.y=new Float32Array(this.dataset.source.y.buffer).subarray(0,t)}_growBuffer(t){const a=t*Float64Array.BYTES_PER_ELEMENT;let e=this.dataX.buffer.byteLength;for(;a>e;)e+=T*Float64Array.BYTES_PER_ELEMENT;if(e*Float64Array.BYTES_PER_ELEMENT>this.dataX.buffer.maxByteLength){const n=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:e*Float64Array.BYTES_PER_ELEMENT}),r=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:e*Float32Array.BYTES_PER_ELEMENT}),o=new Float64Array(n),i=new Float32Array(r);o.set(this.dataX),i.set(this.dataY),this.dataset.source.x=o,this.dataset.source.y=i}this.dataX.buffer.byteLength<t*Float64Array.BYTES_PER_ELEMENT&&(this.dataX.buffer.grow(t*Float64Array.BYTES_PER_ELEMENT),this.dataY.buffer.grow(t*Float32Array.BYTES_PER_ELEMENT))}async reload(){this.loadingTime=null,this.isLoading=!0,this.history.length=0,await this.loadData(this.rawData)}async reloadHistory(t){const a=this.history.slice(0,t+1);await this.reload(),await this.dispatch(a.map(e=>[e.method,...e.args||[]]))}async removeHistoryItem(t){const a=[...this.history];a.splice(t,1),await this.reload(),await this.dispatch(a.map(e=>[e.method,...e.args||[]]))}get beginTime(){return this.dataset.source.x.length?new Date(this.dataset.source.x[0]):null}get endTime(){return this.dataset.source.x.length?new Date(this.dataset.source.x[this.dataset.source.x.length-1]):null}async dispatch(t,...a){const e={[c.ADD_POINTS]:this._addDataPoints,[c.CHANGE_VALUES]:this._changeValues,[c.DELETE_POINTS]:this._deleteDataPoints,[c.DRIFT_CORRECTION]:this._driftCorrection,[c.INTERPOLATE]:this._interpolate,[c.SHIFT_DATETIMES]:this._shift,[c.FILL_GAPS]:this._fillGaps},n={[c.ADD_POINTS]:"mdi-plus",[c.CHANGE_VALUES]:"mdi-pencil",[c.DELETE_POINTS]:"mdi-trash-can",[c.DRIFT_CORRECTION]:"mdi-chart-sankey",[c.INTERPOLATE]:"mdi-transit-connection-horizontal",[c.SHIFT_DATETIMES]:"mdi-calendar",[c.FILL_GAPS]:"mdi-keyboard-space"};let r=[];try{if(Array.isArray(t)){for(let o=0;o<t.length;o++){const i=t[o][0],h=t[o].slice(1,t[o].length),l={method:i,args:h,icon:n[i],isLoading:!1};this.history.push(l)}for(let o=this.history.length-t.length;o<this.history.length;o++){const i=this.history[o];i.isLoading=!0;const h=await _(async()=>await e[i.method].apply(this,i.args));i.duration=h.duration,i.isLoading=!1,r.push(h.response)}}else{const o={method:t,args:a,icon:n[t],isLoading:!0};this.history.push(o);const i=await _(async()=>await e[t].apply(this,a));r=i.response,o.duration=i.duration,o.isLoading=!1}}catch(o){console.log(`Failed to execute operation: ${t} with arguments: `,a),console.log(o)}return r}async dispatchFilter(t,...a){const e={[L.FIND_GAPS]:this._findGaps,[L.VALUE_THRESHOLD]:this._valueThreshold,[L.PERSISTENCE]:this._persistence,[L.RATE_OF_CHANGE]:this._rateOfChange};let n=[];try{if(Array.isArray(t))for(let r=0;r<t.length;r++){const o=t[r][0],i=t[r].slice(1,t[r].length),h=await e[o].apply(this,i);n.push(h)}else n=await e[t].apply(this,a)}catch(r){console.log(`Failed to execute filter operation: ${t} with arguments: `,a),console.log(r)}return n}_changeValues(t,a,e){const n=r=>{switch(a){case g.ADD:return r+e;case g.ASSIGN:return e;case g.DIV:return r/e;case g.MULT:return r*e;case g.SUB:return r-e;default:return r}};t.forEach(r=>{this.dataset.source.y[r]=n(this.dataset.source.y[r])})}_interpolate(t){this._getConsecutiveGroups(t).forEach(e=>{const n=e[0],r=e[e.length-1];let o=Math.max(0,n-1),i=Math.min(this.dataset.source.y.length-1,r+1);const h=this.dataset.source.x,l=this.dataset.source.y;for(let f=0;f<e.length;f++)this.dataset.source.y[e[f]]=this._interpolateLinear(h[e[f]],h[o],l[o],h[i],l[i])})}_interpolateLinear(t,a,e,n,r){return e+(t-a)*(r-e)/(n-a)}async _shift(t,a,e){const n=t.map(r=>[j(this.dataX[r],a,e),this.dataY[r]]);await this._deleteDataPoints(t),await this._addDataPoints(n)}async _fillGapsV2(t,a,e,n){const r=navigator.hardwareConcurrency||1,o=[],i=[],h=this.dataX.length,l=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),f=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let u=0;u<r;u++)i.push(new Promise(E=>{const y=new C;o.push(y),y.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:l,outputBufferY:f}),y.onmessage=m=>{E(m.data)}}));await Promise.all(i),o.forEach(u=>u.terminate()),this.dataset.source.x=new Float64Array(l),this.dataset.source.y=new Float32Array(f),this._resizeTo(h)}_fillGaps(t,a,e,n){const r=this._findGaps(t[0],t[1],n);for(let o=r.length-1;o>=0;o--){const i=r[o],h=this.dataX[i[0]],l=this.dataX[i[1]],f=[],u=a[0]*A[a[1]]*1e3;let E=h+u;for(;E<l;){const y=e?this._interpolateLinear(E,this.dataX[i[0]],this.dataY[i[0]],this.dataX[i[1]],this.dataY[i[1]]):-9999;f.push([E,y]),E+=u}this._addDataPoints(f)}}async _deleteDataPoints(t){const a=navigator.hardwareConcurrency||1,e=Math.ceil(this.dataX.length/a),n=[],r=[];for(let u=0;u<a;u++){const E=u*e,y=Math.min((u+1)*e-1,this.dataX.length-1),m=k(t,E),S=G(t,y),D=t.slice(m,S+1);r.push({start:E,end:y,deleteSegment:D})}const o=new Array(a).fill(0);for(let u=1;u<a;u++)o[u]=o[u-1]+r[u-1].deleteSegment.length;const i=[],h=this.dataX.length-t.length,l=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),f=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let u=0;u<a;u++){const{start:E,end:y,deleteSegment:m}=r[u],S=E-o[u];i.push(new Promise(D=>{const b=new x;n.push(b),b.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:l,outputBufferY:f,start:E,end:y,deleteSegment:m,startTarget:S}),b.onmessage=W=>{D(W.data)}}))}await Promise.all(i),n.forEach(u=>u.terminate()),this.dataset.source.x=new Float64Array(l),this.dataset.source.y=new Float32Array(f),this._resizeTo(h)}_driftCorrection(t,a,e){const n=this.dataset.source.x,r=this.dataset.source.y,o=n[t],h=n[a]-o;for(let l=t;l<a;l++)this.dataset.source.y[l]=r[l]+e*((n[l]-o)/h)}_getConsecutiveGroups(t){const a=[[]];return t.reduce((e,n)=>{const r=e[e.length-1];return!r.length||n==r[r.length-1]+1?r.push(n):e.push([n]),e},a),a}async _addDataPoints(t){const a=this.dataX.length+t.length;this._growBuffer(a),t.sort((r,o)=>r[0]-o[0]);const e=t.map(r=>G(this.dataX,r[0])+1);this._resizeTo(a),e.push(this.dataX.length);let n=t.length;for(let r=e.length-1;r>0;r--){const o=e[r-1],i=e[r]-1;for(let h=i;h>=o;h--)this.dataX[h+n]=this.dataX[h],this.dataY[h+n]=this.dataY[h];n--,this.dataX[o+n]=t[r-1][0],this.dataY[o+n]=t[r-1][1]}}_valueThreshold(t){const a=[];return this.dataset.source.y.forEach((e,n)=>{Object.keys(t).some(r=>B[r]?.(e,t[r]))&&a.push(n)}),a}_rateOfChange(t,a){const e=[],n=this.dataset.source.y;for(let r=1;r<n.length;r++){const o=n[r-1],h=(n[r]-o)/Math.abs(o);N[t]?.(h,a)&&e.push(r)}return e}_findGaps(t,a,e){const n=[],r=this.dataset.source.x;let o=0,i=r.length;e?.[0]&&e?.[1]&&(o=e[0],i=e[1]);let h=r[o];for(let l=o+1;l<=i;l++){const f=r[l];f-h>t*A[a]*1e3&&n.push([l-1,l]),h=f}return n}_persistence(t,a){let e=[],n=this.dataset.source.y,r=0,o=n.length;a?.[0]&&a?.[1]&&(r=a[0],o=a[1]);let i=n[r],h=[];for(let l=r+1;l<o;l++)n[l]!=i||l===o?(h.length>=t&&(e=[...e,...h]),h=[]):h.push(l);return e}}d.EnumEditOperations=c,d.EnumFilterOperations=L,d.FilterOperation=R,d.FilterOperationFn=B,d.ObservationRecord=V,d.Operator=g,d.RateOfChangeComparator=N,d.RateOfChangeOperation=I,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare enum EnumEditOperations {
|
|
2
|
+
ADD_POINTS = "ADD_POINTS",
|
|
3
|
+
CHANGE_VALUES = "CHANGE_VALUES",
|
|
4
|
+
DELETE_POINTS = "DELETE_POINTS",
|
|
5
|
+
DRIFT_CORRECTION = "DRIFT_CORRECTION",
|
|
6
|
+
INTERPOLATE = "INTERPOLATE",
|
|
7
|
+
SHIFT_DATETIMES = "SHIFT_DATETIMES",
|
|
8
|
+
FILL_GAPS = "FILL_GAPS"
|
|
9
|
+
}
|
|
10
|
+
export declare enum EnumFilterOperations {
|
|
11
|
+
FIND_GAPS = "FIND_GAPS",
|
|
12
|
+
PERSISTENCE = "PERSISTENCE",
|
|
13
|
+
RATE_OF_CHANGE = "RATE_OF_CHANGE",
|
|
14
|
+
VALUE_THRESHOLD = "VALUE_THRESHOLD"
|
|
15
|
+
}
|
|
16
|
+
export type HistoryItem = {
|
|
17
|
+
method: EnumEditOperations;
|
|
18
|
+
icon: string;
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
args?: any[];
|
|
21
|
+
duration?: number;
|
|
22
|
+
status?: 'success' | 'failed';
|
|
23
|
+
};
|
|
24
|
+
export type EnumDictionary<T extends string | symbol | number, U> = {
|
|
25
|
+
[K in T]: U;
|
|
26
|
+
};
|
|
27
|
+
export declare enum FilterOperation {
|
|
28
|
+
LT = "Less than",
|
|
29
|
+
LTE = "Less than or equal to",
|
|
30
|
+
GT = "Greater than",
|
|
31
|
+
GTE = "Greater than or equal to",
|
|
32
|
+
E = "Equal",
|
|
33
|
+
START = "Start datetime",
|
|
34
|
+
END = "End datetime"
|
|
35
|
+
}
|
|
36
|
+
export declare const FilterOperationFn: EnumDictionary<FilterOperation, (value: number, toCompare: number) => boolean>;
|
|
37
|
+
export declare enum Operator {
|
|
38
|
+
ADD = "ADD",
|
|
39
|
+
SUB = "SUB",
|
|
40
|
+
MULT = "MULT",
|
|
41
|
+
DIV = "DIV",
|
|
42
|
+
ASSIGN = "ASSIGN"
|
|
43
|
+
}
|
|
44
|
+
export declare enum RateOfChangeOperation {
|
|
45
|
+
LT = "Less than",
|
|
46
|
+
LTE = "Less than or equal to",
|
|
47
|
+
GT = "Greater than",
|
|
48
|
+
GTE = "Greater than or equal to",
|
|
49
|
+
E = "Equal"
|
|
50
|
+
}
|
|
51
|
+
export declare const RateOfChangeComparator: EnumDictionary<RateOfChangeOperation, (value: number, toCompare: number) => boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare const DEFAULT_SNACK_DURATION = 3000;
|
|
2
|
+
export declare enum SnackColor {
|
|
3
|
+
Warning = "warning",
|
|
4
|
+
Success = "success",
|
|
5
|
+
Error = "error",
|
|
6
|
+
Info = "info"
|
|
7
|
+
}
|
|
8
|
+
export declare enum SnackIcon {
|
|
9
|
+
Success = "mdi-checkbox-marked-circle",
|
|
10
|
+
Warning = "mdi-alert",
|
|
11
|
+
Error = "mdi-alert-circle",
|
|
12
|
+
Info = "mdi-information",
|
|
13
|
+
None = "none"
|
|
14
|
+
}
|
|
15
|
+
export declare enum SnackTitle {
|
|
16
|
+
Warning = "Warning",
|
|
17
|
+
Success = "Success",
|
|
18
|
+
Error = "Error",
|
|
19
|
+
Info = "Info"
|
|
20
|
+
}
|
|
21
|
+
export declare enum Position {
|
|
22
|
+
Center = "center",
|
|
23
|
+
Left = "left",
|
|
24
|
+
Right = "right",
|
|
25
|
+
Bottom = "bottom",
|
|
26
|
+
Top = "top"
|
|
27
|
+
}
|
|
28
|
+
export declare class Snack {
|
|
29
|
+
message: string;
|
|
30
|
+
color: SnackColor;
|
|
31
|
+
icon: SnackIcon;
|
|
32
|
+
title: SnackTitle;
|
|
33
|
+
timeout: number;
|
|
34
|
+
position: Position;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
constructor(message?: string, color?: SnackColor, icon?: SnackIcon, title?: SnackTitle, timeout?: number, position?: Position, visible?: boolean);
|
|
37
|
+
}
|
|
38
|
+
export declare class Snackbar {
|
|
39
|
+
private static subject;
|
|
40
|
+
static get snack$(): import("rxjs").Observable<Snack>;
|
|
41
|
+
private static createSnackbar;
|
|
42
|
+
static success(message: string): void;
|
|
43
|
+
static warn(message: string): void;
|
|
44
|
+
static error(message: string): void;
|
|
45
|
+
static info(message: string): void;
|
|
46
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { EnumDictionary, EnumEditOperations, EnumFilterOperations, HistoryItem } from '../../types';
|
|
2
|
+
export declare function subtractHours(timestamp: string, hours: number): string;
|
|
3
|
+
/** Returns the index of the first value that is greater or equal to the target value */
|
|
4
|
+
export declare const findFirstGreaterOrEqual: (array: number[] | Float64Array<SharedArrayBuffer>, target: number) => number;
|
|
5
|
+
/** Returns the index of the last value that is lesser or equal to the target value */
|
|
6
|
+
export declare const findLastLessOrEqual: (array: number[] | Float64Array<SharedArrayBuffer>, target: number) => number;
|
|
7
|
+
export declare const measureEllapsedTime: (fn: () => any, message?: string) => Promise<{
|
|
8
|
+
response: any;
|
|
9
|
+
duration: number;
|
|
10
|
+
}>;
|
|
11
|
+
export declare enum TimeUnit {
|
|
12
|
+
SECOND = "s",
|
|
13
|
+
MINUTE = "m",
|
|
14
|
+
HOUR = "h",
|
|
15
|
+
DAY = "D",
|
|
16
|
+
WEEK = "W",
|
|
17
|
+
MONTH = "M",
|
|
18
|
+
YEAR = "Y"
|
|
19
|
+
}
|
|
20
|
+
export declare const timeUnitMultipliers: EnumDictionary<TimeUnit, number>;
|
|
21
|
+
export declare const formatDate: (date: Date) => string;
|
|
22
|
+
export declare const formatDuration: (duration: number) => string;
|
|
23
|
+
export declare const shiftDatetime: (datetime: number, amount: number, unit: TimeUnit) => number;
|
|
24
|
+
/**
|
|
25
|
+
* This number should approximate the number of observations that a dataset could increase by during a session.
|
|
26
|
+
* The lower this number, the less memory the entire app uses.
|
|
27
|
+
* Note that when a dataset number of data points increases by more than `INCREASE_AMOUNT`,
|
|
28
|
+
* the `_growBuffer()` method will allocate a new buffer, and the data will be copied into it.
|
|
29
|
+
*/
|
|
30
|
+
export declare const INCREASE_AMOUNT: number;
|
|
31
|
+
export declare class ObservationRecord {
|
|
32
|
+
/** The generated dataset to be used for plotting */
|
|
33
|
+
dataset: {
|
|
34
|
+
dimensions: string[];
|
|
35
|
+
source: {
|
|
36
|
+
x: Float64Array<SharedArrayBuffer>;
|
|
37
|
+
y: Float32Array<SharedArrayBuffer>;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
history: HistoryItem[];
|
|
41
|
+
loadingTime: number | null;
|
|
42
|
+
isLoading: boolean;
|
|
43
|
+
rawData: {
|
|
44
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
45
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
46
|
+
};
|
|
47
|
+
constructor(dataArrays: {
|
|
48
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
49
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
50
|
+
});
|
|
51
|
+
loadData(dataArrays: {
|
|
52
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
53
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
get dataX(): Float64Array<SharedArrayBuffer>;
|
|
56
|
+
get dataY(): Float32Array<SharedArrayBuffer>;
|
|
57
|
+
/**
|
|
58
|
+
* Resizes the typed array
|
|
59
|
+
* @param length The total number of elements that the view will contain
|
|
60
|
+
*/
|
|
61
|
+
private _resizeTo;
|
|
62
|
+
/**
|
|
63
|
+
* Buffer size is always in increments of `INCREASE_AMOUNT`.
|
|
64
|
+
* Grows the buffer by `INCREASE_AMOUNT` in bytes if the current data doesn't fit
|
|
65
|
+
* @param newLength The total number of elements that the view will contain
|
|
66
|
+
*/
|
|
67
|
+
private _growBuffer;
|
|
68
|
+
/**
|
|
69
|
+
* Reloads the dataset with the raw data
|
|
70
|
+
*/
|
|
71
|
+
reload(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* @param index
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
reloadHistory(index: number): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Remove a history item
|
|
79
|
+
* @param index
|
|
80
|
+
*/
|
|
81
|
+
removeHistoryItem(index: number): Promise<void>;
|
|
82
|
+
get beginTime(): Date | null;
|
|
83
|
+
get endTime(): Date | null;
|
|
84
|
+
/** Dispatch an operation and log its signature in hisotry */
|
|
85
|
+
dispatch(action: EnumEditOperations | [EnumEditOperations, ...any][], ...args: any): Promise<any[]>;
|
|
86
|
+
/** Filter operations do not transform the data and are not logged in history */
|
|
87
|
+
dispatchFilter(action: EnumFilterOperations | [EnumFilterOperations, ...any][], ...args: any): Promise<any>;
|
|
88
|
+
/**
|
|
89
|
+
* @param index An array containing the list of index of values to perform the operations on.
|
|
90
|
+
* @param operator The operator that will be applied
|
|
91
|
+
* @param value The value to use in the operation
|
|
92
|
+
* @returns The modified DataFrame
|
|
93
|
+
*/
|
|
94
|
+
private _changeValues;
|
|
95
|
+
private _interpolate;
|
|
96
|
+
/** Interpolate existing values in the data source */
|
|
97
|
+
private _interpolateLinear;
|
|
98
|
+
/**
|
|
99
|
+
* Shifts the selected indexes by specified amount of units. Elements are reinserted according to their datetime.
|
|
100
|
+
* @param index The index of the elements to shift
|
|
101
|
+
* @param amount Number of {@link TimeUnit}
|
|
102
|
+
* @param unit {@link TimeUnit}
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
private _shift;
|
|
106
|
+
private _fillGapsV2;
|
|
107
|
+
/**
|
|
108
|
+
* Find gaps and fill them with placeholder value
|
|
109
|
+
* @param gap Intervals to detect as gaps
|
|
110
|
+
* @param fill Interval used to fill the detected gaps
|
|
111
|
+
* @param interpolateValues If true, the new values will be linearly interpolated
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
private _fillGaps;
|
|
115
|
+
/**
|
|
116
|
+
Deletes data points from a large array using worker threads.
|
|
117
|
+
1. The main thread divides the original array into equal parts to distribute work among workers.
|
|
118
|
+
2. For each segment, binary search locates the indexes to delete (deleteSegment), ensuring efficient lookups.
|
|
119
|
+
3. The cumulative deletions before each segment help compute the starting index (startTarget) for each worker's output, ensuring no overlap.
|
|
120
|
+
4. Each worker processes its segment linearly, skipping deletions and copying kept elements to their computed positions.
|
|
121
|
+
* @param deleteIndices
|
|
122
|
+
*/
|
|
123
|
+
private _deleteDataPoints;
|
|
124
|
+
/**
|
|
125
|
+
*
|
|
126
|
+
* @param start The start index
|
|
127
|
+
* @param end The end index
|
|
128
|
+
* @param value The drift amount
|
|
129
|
+
*/
|
|
130
|
+
private _driftCorrection;
|
|
131
|
+
/** Traverses the index array and returns groups of consecutive values.
|
|
132
|
+
* i.e.: `[0, 1, 3, 4, 6] => [[0, 1], [3, 4], [6]]`
|
|
133
|
+
* Assumes the input array is sorted.
|
|
134
|
+
* @param index: the index array (sorted)
|
|
135
|
+
*/
|
|
136
|
+
private _getConsecutiveGroups;
|
|
137
|
+
/**
|
|
138
|
+
* Adds data points. Their insert index is determined using `findFirstGreaterOrEqual` in the x-axis.
|
|
139
|
+
* @param dataPoints
|
|
140
|
+
*/
|
|
141
|
+
private _addDataPoints;
|
|
142
|
+
/**
|
|
143
|
+
* Filter by applying a set of logical operations
|
|
144
|
+
* @param appliedFilters
|
|
145
|
+
* @returns
|
|
146
|
+
*/
|
|
147
|
+
private _valueThreshold;
|
|
148
|
+
/**
|
|
149
|
+
*
|
|
150
|
+
* @param comparator
|
|
151
|
+
* @param value
|
|
152
|
+
* @returns
|
|
153
|
+
*/
|
|
154
|
+
private _rateOfChange;
|
|
155
|
+
/**
|
|
156
|
+
* Find gaps in the data
|
|
157
|
+
* @param value The time value
|
|
158
|
+
* @param unit The time unit (TimeUnit)
|
|
159
|
+
* @param range If specified, the gaps will be found only within the range
|
|
160
|
+
* @returns
|
|
161
|
+
*/
|
|
162
|
+
private _findGaps;
|
|
163
|
+
/**
|
|
164
|
+
* Find points where the values are the same at least x times in a row
|
|
165
|
+
* @param times The number of times in a row that points can be equal
|
|
166
|
+
* @param range If specified, the points will be found only within the range
|
|
167
|
+
* @returns
|
|
168
|
+
*/
|
|
169
|
+
private _persistence;
|
|
170
|
+
}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwrl/qc-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "Quality Control Utilities",
|
|
5
5
|
"homepage": "https://github.com/hydroserver2/qc-utils#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
},
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"author": "Maurier Ramirez",
|
|
15
|
-
"type": "module",
|
|
16
15
|
"main": "./dist/index.cjs",
|
|
17
16
|
"module": "./dist/index.js",
|
|
18
17
|
"exports": {
|
|
@@ -21,11 +20,13 @@
|
|
|
21
20
|
"import": "./dist/index.js"
|
|
22
21
|
}
|
|
23
22
|
},
|
|
23
|
+
"types": "./dist/types.d.ts",
|
|
24
24
|
"files": [
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
|
+
"type": "module",
|
|
27
28
|
"scripts": {
|
|
28
|
-
"build": "npm run clean:dist && vite build --mode prod",
|
|
29
|
+
"build": "npm run clean:dist && vite build --mode prod && vue-tsc --declaration --emitDeclarationOnly",
|
|
29
30
|
"pub": "npm publish --access public",
|
|
30
31
|
"clean:dist": "rimraf dist",
|
|
31
32
|
"clean:coverage": "rimraf coverage",
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"link": "npm link"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
41
|
+
"rxjs": "^7.8.2",
|
|
40
42
|
"vite": "^7.0.4"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"stylelint": "^16.20.0",
|
|
50
52
|
"taze": "^19.1.0",
|
|
51
53
|
"typescript": "latest",
|
|
52
|
-
"vitest": "^3.2.4"
|
|
54
|
+
"vitest": "^3.2.4",
|
|
55
|
+
"vue-tsc": "^3.0.5"
|
|
53
56
|
}
|
|
54
57
|
}
|