@genome-spy/app 0.37.4 → 0.38.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/dist/__vite-browser-external-ENoMJThg.js +8 -0
- package/dist/index-2VmK8MLN.js +1074 -0
- package/dist/index-2mPD1sXi.js +1372 -0
- package/dist/index-5BtgVTyz.js +515 -0
- package/dist/index-DD9IXliq.js +4050 -0
- package/dist/index-JuiSQXKu.js +501 -0
- package/dist/index-Nre2aQhT.js +2190 -0
- package/dist/index-UyB03NDZ.js +29302 -0
- package/dist/index-bYeOjUJA.js +638 -0
- package/dist/index-tnhTL94V.js +279 -0
- package/dist/index-yisZrslf.js +72 -0
- package/dist/index.es.js +9 -0
- package/dist/index.js +285 -307
- package/dist/long-WDeGicRf.js +2382 -0
- package/dist/remoteFile-1ad_qGwi.js +96 -0
- package/package.json +10 -9
@@ -0,0 +1,1372 @@
|
|
1
|
+
import { L as Y, u as L, a as X } from "./long-WDeGicRf.js";
|
2
|
+
import { b as E } from "./index-2VmK8MLN.js";
|
3
|
+
import { g as W } from "./index-UyB03NDZ.js";
|
4
|
+
import { L as R } from "./__vite-browser-external-ENoMJThg.js";
|
5
|
+
import { R as k } from "./remoteFile-1ad_qGwi.js";
|
6
|
+
import { _ as J, L as K } from "./index-5BtgVTyz.js";
|
7
|
+
class U {
|
8
|
+
constructor(e, t) {
|
9
|
+
this.blockPosition = e, this.dataPosition = t;
|
10
|
+
}
|
11
|
+
toString() {
|
12
|
+
return `${this.blockPosition}:${this.dataPosition}`;
|
13
|
+
}
|
14
|
+
compareTo(e) {
|
15
|
+
return this.blockPosition - e.blockPosition || this.dataPosition - e.dataPosition;
|
16
|
+
}
|
17
|
+
static min(...e) {
|
18
|
+
let t, n = 0;
|
19
|
+
for (; !t; n += 1)
|
20
|
+
t = e[n];
|
21
|
+
for (; n < e.length; n += 1)
|
22
|
+
t.compareTo(e[n]) > 0 && (t = e[n]);
|
23
|
+
return t;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
function y(o, e = 0, t = !1) {
|
27
|
+
if (t)
|
28
|
+
throw new Error("big-endian virtual file offsets not implemented");
|
29
|
+
return new U(o[e + 7] * 1099511627776 + o[e + 6] * 4294967296 + o[e + 5] * 16777216 + o[e + 4] * 65536 + o[e + 3] * 256 + o[e + 2], o[e + 1] << 8 | o[e]);
|
30
|
+
}
|
31
|
+
class z {
|
32
|
+
constructor(e, t, n, r) {
|
33
|
+
this.minv = e, this.maxv = t, this.bin = n, this._fetchedSize = r;
|
34
|
+
}
|
35
|
+
toUniqueString() {
|
36
|
+
return `${this.minv}..${this.maxv} (bin ${this.bin}, fetchedSize ${this.fetchedSize()})`;
|
37
|
+
}
|
38
|
+
toString() {
|
39
|
+
return this.toUniqueString();
|
40
|
+
}
|
41
|
+
compareTo(e) {
|
42
|
+
return this.minv.compareTo(e.minv) || this.maxv.compareTo(e.maxv) || this.bin - e.bin;
|
43
|
+
}
|
44
|
+
fetchedSize() {
|
45
|
+
return this._fetchedSize !== void 0 ? this._fetchedSize : this.maxv.blockPosition + 65536 - this.minv.blockPosition;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
function Z(o) {
|
49
|
+
return new Promise((e) => setTimeout(e, o));
|
50
|
+
}
|
51
|
+
function ee(o) {
|
52
|
+
if (o.greaterThan(Number.MAX_SAFE_INTEGER) || o.lessThan(Number.MIN_SAFE_INTEGER))
|
53
|
+
throw new Error("integer overflow");
|
54
|
+
return o.toNumber();
|
55
|
+
}
|
56
|
+
function te(o) {
|
57
|
+
if (o && o.aborted)
|
58
|
+
if (typeof DOMException > "u") {
|
59
|
+
const e = new Error("aborted");
|
60
|
+
throw e.code = "ERR_ABORTED", e;
|
61
|
+
} else
|
62
|
+
throw new DOMException("aborted", "AbortError");
|
63
|
+
}
|
64
|
+
function ne(o, e) {
|
65
|
+
return e.minv.blockPosition - o.maxv.blockPosition < 65e3 && e.maxv.blockPosition - o.minv.blockPosition < 5e6;
|
66
|
+
}
|
67
|
+
function re(o = {}) {
|
68
|
+
return "aborted" in o ? { signal: o } : o;
|
69
|
+
}
|
70
|
+
function O(o, e) {
|
71
|
+
const t = [];
|
72
|
+
let n;
|
73
|
+
if (o.length === 0)
|
74
|
+
return o;
|
75
|
+
o.sort((r, a) => {
|
76
|
+
const i = r.minv.blockPosition - a.minv.blockPosition;
|
77
|
+
return i === 0 ? r.minv.dataPosition - a.minv.dataPosition : i;
|
78
|
+
});
|
79
|
+
for (const r of o)
|
80
|
+
(!e || r.maxv.compareTo(e) > 0) && (n === void 0 ? (t.push(r), n = r) : ne(n, r) ? r.maxv.compareTo(n.maxv) > 0 && (n.maxv = r.maxv) : (t.push(r), n = r));
|
81
|
+
return t;
|
82
|
+
}
|
83
|
+
function H(o, e) {
|
84
|
+
return { lineCount: ee(Y.fromBytesLE(Array.prototype.slice.call(o, e, e + 8), !0)) };
|
85
|
+
}
|
86
|
+
function P(o, e) {
|
87
|
+
return o ? o.compareTo(e) > 0 ? e : o : e;
|
88
|
+
}
|
89
|
+
function ae(o, e = (t) => t) {
|
90
|
+
let t = 0, n = 0;
|
91
|
+
const r = [], a = {};
|
92
|
+
for (let i = 0; i < o.length; i += 1)
|
93
|
+
if (!o[i]) {
|
94
|
+
if (n < i) {
|
95
|
+
let c = o.toString("utf8", n, i);
|
96
|
+
c = e(c), r[t] = c, a[c] = t;
|
97
|
+
}
|
98
|
+
n = i + 1, t += 1;
|
99
|
+
}
|
100
|
+
return { refNameToId: a, refIdToName: r };
|
101
|
+
}
|
102
|
+
class G {
|
103
|
+
/**
|
104
|
+
* @param {filehandle} filehandle
|
105
|
+
* @param {function} [renameRefSeqs]
|
106
|
+
*/
|
107
|
+
constructor({ filehandle: e, renameRefSeq: t = (n) => n }) {
|
108
|
+
this.filehandle = e, this.renameRefSeq = t;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
const se = 21578050;
|
112
|
+
function ie(o, e) {
|
113
|
+
return o - o % e;
|
114
|
+
}
|
115
|
+
function oe(o, e) {
|
116
|
+
return o - o % e + e;
|
117
|
+
}
|
118
|
+
function de(o, e) {
|
119
|
+
return e -= 1, [
|
120
|
+
[0, 0],
|
121
|
+
[1 + (o >> 26), 1 + (e >> 26)],
|
122
|
+
[9 + (o >> 23), 9 + (e >> 23)],
|
123
|
+
[73 + (o >> 20), 73 + (e >> 20)],
|
124
|
+
[585 + (o >> 17), 585 + (e >> 17)],
|
125
|
+
[4681 + (o >> 14), 4681 + (e >> 14)]
|
126
|
+
];
|
127
|
+
}
|
128
|
+
class A extends G {
|
129
|
+
async lineCount(e, t) {
|
130
|
+
var n, r;
|
131
|
+
return ((r = (n = (await this.parse(t)).indices[e]) === null || n === void 0 ? void 0 : n.stats) === null || r === void 0 ? void 0 : r.lineCount) || 0;
|
132
|
+
}
|
133
|
+
// fetch and parse the index
|
134
|
+
async _parse(e) {
|
135
|
+
const t = await this.filehandle.readFile(e);
|
136
|
+
if (t.readUInt32LE(0) !== se)
|
137
|
+
throw new Error("Not a BAI file");
|
138
|
+
const n = t.readInt32LE(4), a = ((1 << (5 + 1) * 3) - 1) / 7;
|
139
|
+
let i = 8, c;
|
140
|
+
const d = new Array(n);
|
141
|
+
for (let s = 0; s < n; s++) {
|
142
|
+
const l = t.readInt32LE(i);
|
143
|
+
let u;
|
144
|
+
i += 4;
|
145
|
+
const h = {};
|
146
|
+
for (let b = 0; b < l; b += 1) {
|
147
|
+
const x = t.readUInt32LE(i);
|
148
|
+
if (i += 4, x === a + 1)
|
149
|
+
i += 4, u = H(t, i + 16), i += 32;
|
150
|
+
else {
|
151
|
+
if (x > a + 1)
|
152
|
+
throw new Error("bai index contains too many bins, please use CSI");
|
153
|
+
{
|
154
|
+
const g = t.readInt32LE(i);
|
155
|
+
i += 4;
|
156
|
+
const p = new Array(g);
|
157
|
+
for (let w = 0; w < g; w++) {
|
158
|
+
const v = y(t, i);
|
159
|
+
i += 8;
|
160
|
+
const S = y(t, i);
|
161
|
+
i += 8, c = P(c, v), p[w] = new z(v, S, x);
|
162
|
+
}
|
163
|
+
h[x] = p;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
const f = t.readInt32LE(i);
|
168
|
+
i += 4;
|
169
|
+
const m = new Array(f);
|
170
|
+
for (let b = 0; b < f; b++) {
|
171
|
+
const x = y(t, i);
|
172
|
+
i += 8, c = P(c, x), m[b] = x;
|
173
|
+
}
|
174
|
+
d[s] = { binIndex: h, linearIndex: m, stats: u };
|
175
|
+
}
|
176
|
+
return {
|
177
|
+
bai: !0,
|
178
|
+
firstDataLine: c,
|
179
|
+
maxBlockSize: 65536,
|
180
|
+
indices: d,
|
181
|
+
refCount: n
|
182
|
+
};
|
183
|
+
}
|
184
|
+
async indexCov(e, t, n, r = {}) {
|
185
|
+
const i = t !== void 0, d = (await this.parse(r)).indices[e];
|
186
|
+
if (!d)
|
187
|
+
return [];
|
188
|
+
const { linearIndex: s = [], stats: l } = d;
|
189
|
+
if (s.length === 0)
|
190
|
+
return [];
|
191
|
+
const u = n === void 0 ? (s.length - 1) * 16384 : oe(n, 16384), h = t === void 0 ? 0 : ie(t, 16384), f = i ? new Array((u - h) / 16384) : new Array(s.length - 1), m = s[s.length - 1].blockPosition;
|
192
|
+
if (u > (s.length - 1) * 16384)
|
193
|
+
throw new Error("query outside of range of linear index");
|
194
|
+
let b = s[h / 16384].blockPosition;
|
195
|
+
for (let x = h / 16384, g = 0; x < u / 16384; x++, g++)
|
196
|
+
f[g] = {
|
197
|
+
score: s[x + 1].blockPosition - b,
|
198
|
+
start: x * 16384,
|
199
|
+
end: x * 16384 + 16384
|
200
|
+
}, b = s[x + 1].blockPosition;
|
201
|
+
return f.map((x) => ({
|
202
|
+
...x,
|
203
|
+
score: x.score * ((l == null ? void 0 : l.lineCount) || 0) / m
|
204
|
+
}));
|
205
|
+
}
|
206
|
+
async blocksForRange(e, t, n, r = {}) {
|
207
|
+
t < 0 && (t = 0);
|
208
|
+
const a = await this.parse(r);
|
209
|
+
if (!a)
|
210
|
+
return [];
|
211
|
+
const i = a.indices[e];
|
212
|
+
if (!i)
|
213
|
+
return [];
|
214
|
+
const c = de(t, n), d = [];
|
215
|
+
for (const [f, m] of c)
|
216
|
+
for (let b = f; b <= m; b++)
|
217
|
+
if (i.binIndex[b]) {
|
218
|
+
const x = i.binIndex[b];
|
219
|
+
for (const g of x)
|
220
|
+
d.push(g);
|
221
|
+
}
|
222
|
+
const s = i.linearIndex.length;
|
223
|
+
let l;
|
224
|
+
const u = Math.min(t >> 14, s - 1), h = Math.min(n >> 14, s - 1);
|
225
|
+
for (let f = u; f <= h; ++f) {
|
226
|
+
const m = i.linearIndex[f];
|
227
|
+
m && (!l || m.compareTo(l) < 0) && (l = m);
|
228
|
+
}
|
229
|
+
return O(d, l);
|
230
|
+
}
|
231
|
+
async parse(e = {}) {
|
232
|
+
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
233
|
+
throw this.setupP = void 0, t;
|
234
|
+
})), this.setupP;
|
235
|
+
}
|
236
|
+
async hasRefSeq(e, t = {}) {
|
237
|
+
var n;
|
238
|
+
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
var I = E.Buffer, M = [
|
242
|
+
0,
|
243
|
+
1996959894,
|
244
|
+
3993919788,
|
245
|
+
2567524794,
|
246
|
+
124634137,
|
247
|
+
1886057615,
|
248
|
+
3915621685,
|
249
|
+
2657392035,
|
250
|
+
249268274,
|
251
|
+
2044508324,
|
252
|
+
3772115230,
|
253
|
+
2547177864,
|
254
|
+
162941995,
|
255
|
+
2125561021,
|
256
|
+
3887607047,
|
257
|
+
2428444049,
|
258
|
+
498536548,
|
259
|
+
1789927666,
|
260
|
+
4089016648,
|
261
|
+
2227061214,
|
262
|
+
450548861,
|
263
|
+
1843258603,
|
264
|
+
4107580753,
|
265
|
+
2211677639,
|
266
|
+
325883990,
|
267
|
+
1684777152,
|
268
|
+
4251122042,
|
269
|
+
2321926636,
|
270
|
+
335633487,
|
271
|
+
1661365465,
|
272
|
+
4195302755,
|
273
|
+
2366115317,
|
274
|
+
997073096,
|
275
|
+
1281953886,
|
276
|
+
3579855332,
|
277
|
+
2724688242,
|
278
|
+
1006888145,
|
279
|
+
1258607687,
|
280
|
+
3524101629,
|
281
|
+
2768942443,
|
282
|
+
901097722,
|
283
|
+
1119000684,
|
284
|
+
3686517206,
|
285
|
+
2898065728,
|
286
|
+
853044451,
|
287
|
+
1172266101,
|
288
|
+
3705015759,
|
289
|
+
2882616665,
|
290
|
+
651767980,
|
291
|
+
1373503546,
|
292
|
+
3369554304,
|
293
|
+
3218104598,
|
294
|
+
565507253,
|
295
|
+
1454621731,
|
296
|
+
3485111705,
|
297
|
+
3099436303,
|
298
|
+
671266974,
|
299
|
+
1594198024,
|
300
|
+
3322730930,
|
301
|
+
2970347812,
|
302
|
+
795835527,
|
303
|
+
1483230225,
|
304
|
+
3244367275,
|
305
|
+
3060149565,
|
306
|
+
1994146192,
|
307
|
+
31158534,
|
308
|
+
2563907772,
|
309
|
+
4023717930,
|
310
|
+
1907459465,
|
311
|
+
112637215,
|
312
|
+
2680153253,
|
313
|
+
3904427059,
|
314
|
+
2013776290,
|
315
|
+
251722036,
|
316
|
+
2517215374,
|
317
|
+
3775830040,
|
318
|
+
2137656763,
|
319
|
+
141376813,
|
320
|
+
2439277719,
|
321
|
+
3865271297,
|
322
|
+
1802195444,
|
323
|
+
476864866,
|
324
|
+
2238001368,
|
325
|
+
4066508878,
|
326
|
+
1812370925,
|
327
|
+
453092731,
|
328
|
+
2181625025,
|
329
|
+
4111451223,
|
330
|
+
1706088902,
|
331
|
+
314042704,
|
332
|
+
2344532202,
|
333
|
+
4240017532,
|
334
|
+
1658658271,
|
335
|
+
366619977,
|
336
|
+
2362670323,
|
337
|
+
4224994405,
|
338
|
+
1303535960,
|
339
|
+
984961486,
|
340
|
+
2747007092,
|
341
|
+
3569037538,
|
342
|
+
1256170817,
|
343
|
+
1037604311,
|
344
|
+
2765210733,
|
345
|
+
3554079995,
|
346
|
+
1131014506,
|
347
|
+
879679996,
|
348
|
+
2909243462,
|
349
|
+
3663771856,
|
350
|
+
1141124467,
|
351
|
+
855842277,
|
352
|
+
2852801631,
|
353
|
+
3708648649,
|
354
|
+
1342533948,
|
355
|
+
654459306,
|
356
|
+
3188396048,
|
357
|
+
3373015174,
|
358
|
+
1466479909,
|
359
|
+
544179635,
|
360
|
+
3110523913,
|
361
|
+
3462522015,
|
362
|
+
1591671054,
|
363
|
+
702138776,
|
364
|
+
2966460450,
|
365
|
+
3352799412,
|
366
|
+
1504918807,
|
367
|
+
783551873,
|
368
|
+
3082640443,
|
369
|
+
3233442989,
|
370
|
+
3988292384,
|
371
|
+
2596254646,
|
372
|
+
62317068,
|
373
|
+
1957810842,
|
374
|
+
3939845945,
|
375
|
+
2647816111,
|
376
|
+
81470997,
|
377
|
+
1943803523,
|
378
|
+
3814918930,
|
379
|
+
2489596804,
|
380
|
+
225274430,
|
381
|
+
2053790376,
|
382
|
+
3826175755,
|
383
|
+
2466906013,
|
384
|
+
167816743,
|
385
|
+
2097651377,
|
386
|
+
4027552580,
|
387
|
+
2265490386,
|
388
|
+
503444072,
|
389
|
+
1762050814,
|
390
|
+
4150417245,
|
391
|
+
2154129355,
|
392
|
+
426522225,
|
393
|
+
1852507879,
|
394
|
+
4275313526,
|
395
|
+
2312317920,
|
396
|
+
282753626,
|
397
|
+
1742555852,
|
398
|
+
4189708143,
|
399
|
+
2394877945,
|
400
|
+
397917763,
|
401
|
+
1622183637,
|
402
|
+
3604390888,
|
403
|
+
2714866558,
|
404
|
+
953729732,
|
405
|
+
1340076626,
|
406
|
+
3518719985,
|
407
|
+
2797360999,
|
408
|
+
1068828381,
|
409
|
+
1219638859,
|
410
|
+
3624741850,
|
411
|
+
2936675148,
|
412
|
+
906185462,
|
413
|
+
1090812512,
|
414
|
+
3747672003,
|
415
|
+
2825379669,
|
416
|
+
829329135,
|
417
|
+
1181335161,
|
418
|
+
3412177804,
|
419
|
+
3160834842,
|
420
|
+
628085408,
|
421
|
+
1382605366,
|
422
|
+
3423369109,
|
423
|
+
3138078467,
|
424
|
+
570562233,
|
425
|
+
1426400815,
|
426
|
+
3317316542,
|
427
|
+
2998733608,
|
428
|
+
733239954,
|
429
|
+
1555261956,
|
430
|
+
3268935591,
|
431
|
+
3050360625,
|
432
|
+
752459403,
|
433
|
+
1541320221,
|
434
|
+
2607071920,
|
435
|
+
3965973030,
|
436
|
+
1969922972,
|
437
|
+
40735498,
|
438
|
+
2617837225,
|
439
|
+
3943577151,
|
440
|
+
1913087877,
|
441
|
+
83908371,
|
442
|
+
2512341634,
|
443
|
+
3803740692,
|
444
|
+
2075208622,
|
445
|
+
213261112,
|
446
|
+
2463272603,
|
447
|
+
3855990285,
|
448
|
+
2094854071,
|
449
|
+
198958881,
|
450
|
+
2262029012,
|
451
|
+
4057260610,
|
452
|
+
1759359992,
|
453
|
+
534414190,
|
454
|
+
2176718541,
|
455
|
+
4139329115,
|
456
|
+
1873836001,
|
457
|
+
414664567,
|
458
|
+
2282248934,
|
459
|
+
4279200368,
|
460
|
+
1711684554,
|
461
|
+
285281116,
|
462
|
+
2405801727,
|
463
|
+
4167216745,
|
464
|
+
1634467795,
|
465
|
+
376229701,
|
466
|
+
2685067896,
|
467
|
+
3608007406,
|
468
|
+
1308918612,
|
469
|
+
956543938,
|
470
|
+
2808555105,
|
471
|
+
3495958263,
|
472
|
+
1231636301,
|
473
|
+
1047427035,
|
474
|
+
2932959818,
|
475
|
+
3654703836,
|
476
|
+
1088359270,
|
477
|
+
936918e3,
|
478
|
+
2847714899,
|
479
|
+
3736837829,
|
480
|
+
1202900863,
|
481
|
+
817233897,
|
482
|
+
3183342108,
|
483
|
+
3401237130,
|
484
|
+
1404277552,
|
485
|
+
615818150,
|
486
|
+
3134207493,
|
487
|
+
3453421203,
|
488
|
+
1423857449,
|
489
|
+
601450431,
|
490
|
+
3009837614,
|
491
|
+
3294710456,
|
492
|
+
1567103746,
|
493
|
+
711928724,
|
494
|
+
3020668471,
|
495
|
+
3272380065,
|
496
|
+
1510334235,
|
497
|
+
755167117
|
498
|
+
];
|
499
|
+
typeof Int32Array < "u" && (M = new Int32Array(M));
|
500
|
+
function j(o) {
|
501
|
+
if (I.isBuffer(o))
|
502
|
+
return o;
|
503
|
+
var e = typeof I.alloc == "function" && typeof I.from == "function";
|
504
|
+
if (typeof o == "number")
|
505
|
+
return e ? I.alloc(o) : new I(o);
|
506
|
+
if (typeof o == "string")
|
507
|
+
return e ? I.from(o) : new I(o);
|
508
|
+
throw new Error("input must be buffer, number, or string, received " + typeof o);
|
509
|
+
}
|
510
|
+
function ce(o) {
|
511
|
+
var e = j(4);
|
512
|
+
return e.writeInt32BE(o, 0), e;
|
513
|
+
}
|
514
|
+
function B(o, e) {
|
515
|
+
o = j(o), I.isBuffer(e) && (e = e.readUInt32BE(0));
|
516
|
+
for (var t = ~~e ^ -1, n = 0; n < o.length; n++)
|
517
|
+
t = M[(t ^ o[n]) & 255] ^ t >>> 8;
|
518
|
+
return t ^ -1;
|
519
|
+
}
|
520
|
+
function F() {
|
521
|
+
return ce(B.apply(null, arguments));
|
522
|
+
}
|
523
|
+
F.signed = function() {
|
524
|
+
return B.apply(null, arguments);
|
525
|
+
};
|
526
|
+
F.unsigned = function() {
|
527
|
+
return B.apply(null, arguments) >>> 0;
|
528
|
+
};
|
529
|
+
var fe = F;
|
530
|
+
const he = /* @__PURE__ */ W(fe), le = 21582659, ue = 38359875;
|
531
|
+
function xe(o, e) {
|
532
|
+
return o * 2 ** e;
|
533
|
+
}
|
534
|
+
function q(o, e) {
|
535
|
+
return Math.floor(o / 2 ** e);
|
536
|
+
}
|
537
|
+
class T extends G {
|
538
|
+
constructor() {
|
539
|
+
super(...arguments), this.maxBinNumber = 0, this.depth = 0, this.minShift = 0;
|
540
|
+
}
|
541
|
+
async lineCount(e, t) {
|
542
|
+
var n, r;
|
543
|
+
return ((r = (n = (await this.parse(t)).indices[e]) === null || n === void 0 ? void 0 : n.stats) === null || r === void 0 ? void 0 : r.lineCount) || 0;
|
544
|
+
}
|
545
|
+
async indexCov() {
|
546
|
+
return [];
|
547
|
+
}
|
548
|
+
parseAuxData(e, t) {
|
549
|
+
const n = e.readInt32LE(t), r = n & 65536 ? "zero-based-half-open" : "1-based-closed", a = { 0: "generic", 1: "SAM", 2: "VCF" }[n & 15];
|
550
|
+
if (!a)
|
551
|
+
throw new Error(`invalid Tabix preset format flags ${n}`);
|
552
|
+
const i = {
|
553
|
+
ref: e.readInt32LE(t + 4),
|
554
|
+
start: e.readInt32LE(t + 8),
|
555
|
+
end: e.readInt32LE(t + 12)
|
556
|
+
}, c = e.readInt32LE(t + 16), d = c ? String.fromCharCode(c) : "", s = e.readInt32LE(t + 20), l = e.readInt32LE(t + 24);
|
557
|
+
return {
|
558
|
+
columnNumbers: i,
|
559
|
+
coordinateType: r,
|
560
|
+
metaValue: c,
|
561
|
+
metaChar: d,
|
562
|
+
skipLines: s,
|
563
|
+
format: a,
|
564
|
+
formatFlags: n,
|
565
|
+
...ae(e.subarray(t + 28, t + 28 + l), this.renameRefSeq)
|
566
|
+
};
|
567
|
+
}
|
568
|
+
// fetch and parse the index
|
569
|
+
async _parse(e) {
|
570
|
+
const t = await this.filehandle.readFile(e), n = await L(t);
|
571
|
+
let r;
|
572
|
+
if (n.readUInt32LE(0) === le)
|
573
|
+
r = 1;
|
574
|
+
else if (n.readUInt32LE(0) === ue)
|
575
|
+
r = 2;
|
576
|
+
else
|
577
|
+
throw new Error("Not a CSI file");
|
578
|
+
this.minShift = n.readInt32LE(4), this.depth = n.readInt32LE(8), this.maxBinNumber = ((1 << (this.depth + 1) * 3) - 1) / 7;
|
579
|
+
const a = n.readInt32LE(12), i = a >= 30 ? this.parseAuxData(n, 16) : void 0, c = n.readInt32LE(16 + a);
|
580
|
+
let d = 16 + a + 4, s;
|
581
|
+
const l = new Array(c);
|
582
|
+
for (let u = 0; u < c; u++) {
|
583
|
+
const h = n.readInt32LE(d);
|
584
|
+
d += 4;
|
585
|
+
const f = {};
|
586
|
+
let m;
|
587
|
+
for (let b = 0; b < h; b++) {
|
588
|
+
const x = n.readUInt32LE(d);
|
589
|
+
if (d += 4, x > this.maxBinNumber)
|
590
|
+
m = H(n, d + 28), d += 28 + 16;
|
591
|
+
else {
|
592
|
+
s = P(s, y(n, d)), d += 8;
|
593
|
+
const g = n.readInt32LE(d);
|
594
|
+
d += 4;
|
595
|
+
const p = new Array(g);
|
596
|
+
for (let w = 0; w < g; w += 1) {
|
597
|
+
const v = y(n, d);
|
598
|
+
d += 8;
|
599
|
+
const S = y(n, d);
|
600
|
+
d += 8, s = P(s, v), p[w] = new z(v, S, x);
|
601
|
+
}
|
602
|
+
f[x] = p;
|
603
|
+
}
|
604
|
+
}
|
605
|
+
l[u] = { binIndex: f, stats: m };
|
606
|
+
}
|
607
|
+
return {
|
608
|
+
csiVersion: r,
|
609
|
+
firstDataLine: s,
|
610
|
+
indices: l,
|
611
|
+
refCount: c,
|
612
|
+
csi: !0,
|
613
|
+
maxBlockSize: 65536,
|
614
|
+
...i
|
615
|
+
};
|
616
|
+
}
|
617
|
+
async blocksForRange(e, t, n, r = {}) {
|
618
|
+
t < 0 && (t = 0);
|
619
|
+
const a = await this.parse(r), i = a == null ? void 0 : a.indices[e];
|
620
|
+
if (!i)
|
621
|
+
return [];
|
622
|
+
const c = this.reg2bins(t, n);
|
623
|
+
if (c.length === 0)
|
624
|
+
return [];
|
625
|
+
const d = [];
|
626
|
+
for (const [s, l] of c)
|
627
|
+
for (let u = s; u <= l; u++)
|
628
|
+
if (i.binIndex[u]) {
|
629
|
+
const h = i.binIndex[u];
|
630
|
+
for (const f of h)
|
631
|
+
d.push(f);
|
632
|
+
}
|
633
|
+
return O(d, new U(0, 0));
|
634
|
+
}
|
635
|
+
/**
|
636
|
+
* calculate the list of bins that may overlap with region [beg,end)
|
637
|
+
* (zero-based half-open)
|
638
|
+
*/
|
639
|
+
reg2bins(e, t) {
|
640
|
+
e -= 1, e < 1 && (e = 1), t > 2 ** 50 && (t = 2 ** 34), t -= 1;
|
641
|
+
let n = 0, r = 0, a = this.minShift + this.depth * 3;
|
642
|
+
const i = [];
|
643
|
+
for (; n <= this.depth; a -= 3, r += xe(1, n * 3), n += 1) {
|
644
|
+
const c = r + q(e, a), d = r + q(t, a);
|
645
|
+
if (d - c + i.length > this.maxBinNumber)
|
646
|
+
throw new Error(`query ${e}-${t} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`);
|
647
|
+
i.push([c, d]);
|
648
|
+
}
|
649
|
+
return i;
|
650
|
+
}
|
651
|
+
async parse(e = {}) {
|
652
|
+
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
653
|
+
throw this.setupP = void 0, t;
|
654
|
+
})), this.setupP;
|
655
|
+
}
|
656
|
+
async hasRefSeq(e, t = {}) {
|
657
|
+
var n;
|
658
|
+
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
659
|
+
}
|
660
|
+
}
|
661
|
+
const _ = {
|
662
|
+
// the read is paired in sequencing, no matter whether it is mapped in a pair
|
663
|
+
BAM_FPAIRED: 1,
|
664
|
+
// the read is mapped in a proper pair
|
665
|
+
BAM_FPROPER_PAIR: 2,
|
666
|
+
// the read itself is unmapped; conflictive with BAM_FPROPER_PAIR
|
667
|
+
BAM_FUNMAP: 4,
|
668
|
+
// the mate is unmapped
|
669
|
+
BAM_FMUNMAP: 8,
|
670
|
+
// the read is mapped to the reverse strand
|
671
|
+
BAM_FREVERSE: 16,
|
672
|
+
// the mate is mapped to the reverse strand
|
673
|
+
BAM_FMREVERSE: 32,
|
674
|
+
// this is read1
|
675
|
+
BAM_FREAD1: 64,
|
676
|
+
// this is read2
|
677
|
+
BAM_FREAD2: 128,
|
678
|
+
// not primary alignment
|
679
|
+
BAM_FSECONDARY: 256,
|
680
|
+
// QC failure
|
681
|
+
BAM_FQCFAIL: 512,
|
682
|
+
// optical or PCR duplicate
|
683
|
+
BAM_FDUP: 1024,
|
684
|
+
// supplementary alignment
|
685
|
+
BAM_FSUPPLEMENTARY: 2048
|
686
|
+
}, N = "=ACMGRSVTWYHKDBN".split(""), C = "MIDNSHP=X???????".split("");
|
687
|
+
class be {
|
688
|
+
constructor(e) {
|
689
|
+
this.data = {}, this._tagList = [], this._allTagsParsed = !1;
|
690
|
+
const { bytes: t, fileOffset: n } = e, { byteArray: r, start: a } = t;
|
691
|
+
this.data = {}, this.bytes = t, this._id = n, this._refID = r.readInt32LE(a + 4), this.data.start = r.readInt32LE(a + 8), this.flags = (r.readInt32LE(a + 16) & 4294901760) >> 16;
|
692
|
+
}
|
693
|
+
get(e) {
|
694
|
+
return this[e] ? this.data[e] ? this.data[e] : (this.data[e] = this[e](), this.data[e]) : this._get(e.toLowerCase());
|
695
|
+
}
|
696
|
+
end() {
|
697
|
+
return this.get("start") + this.get("length_on_ref");
|
698
|
+
}
|
699
|
+
seq_id() {
|
700
|
+
return this._refID;
|
701
|
+
}
|
702
|
+
// same as get(), except requires lower-case arguments. used
|
703
|
+
// internally to save lots of calls to field.toLowerCase()
|
704
|
+
_get(e) {
|
705
|
+
return e in this.data ? this.data[e] : (this.data[e] = this._parseTag(e), this.data[e]);
|
706
|
+
}
|
707
|
+
_tags() {
|
708
|
+
this._parseAllTags();
|
709
|
+
let e = ["seq"];
|
710
|
+
this.isSegmentUnmapped() || e.push("start", "end", "strand", "score", "qual", "MQ", "CIGAR", "length_on_ref", "template_length"), this.isPaired() && e.push("next_segment_position", "pair_orientation"), e = e.concat(this._tagList || []);
|
711
|
+
for (const n of Object.keys(this.data))
|
712
|
+
n[0] !== "_" && n !== "next_seq_id" && e.push(n);
|
713
|
+
const t = {};
|
714
|
+
return e.filter((n) => {
|
715
|
+
if (n in this.data && this.data[n] === void 0 || n === "CG" || n === "cg")
|
716
|
+
return !1;
|
717
|
+
const r = n.toLowerCase(), a = t[r];
|
718
|
+
return t[r] = !0, !a;
|
719
|
+
});
|
720
|
+
}
|
721
|
+
parent() {
|
722
|
+
}
|
723
|
+
children() {
|
724
|
+
return this.get("subfeatures");
|
725
|
+
}
|
726
|
+
id() {
|
727
|
+
return this._id;
|
728
|
+
}
|
729
|
+
// special parsers
|
730
|
+
/**
|
731
|
+
* Mapping quality score.
|
732
|
+
*/
|
733
|
+
mq() {
|
734
|
+
const e = (this.get("_bin_mq_nl") & 65280) >> 8;
|
735
|
+
return e === 255 ? void 0 : e;
|
736
|
+
}
|
737
|
+
score() {
|
738
|
+
return this.get("mq");
|
739
|
+
}
|
740
|
+
qual() {
|
741
|
+
var e;
|
742
|
+
return (e = this.qualRaw()) === null || e === void 0 ? void 0 : e.join(" ");
|
743
|
+
}
|
744
|
+
qualRaw() {
|
745
|
+
if (this.isSegmentUnmapped())
|
746
|
+
return;
|
747
|
+
const { start: e, byteArray: t } = this.bytes, n = e + 36 + this.get("_l_read_name") + this.get("_n_cigar_op") * 4 + this.get("_seq_bytes"), r = this.get("seq_length");
|
748
|
+
return t.subarray(n, n + r);
|
749
|
+
}
|
750
|
+
strand() {
|
751
|
+
return this.isReverseComplemented() ? -1 : 1;
|
752
|
+
}
|
753
|
+
multi_segment_next_segment_strand() {
|
754
|
+
if (!this.isMateUnmapped())
|
755
|
+
return this.isMateReverseComplemented() ? -1 : 1;
|
756
|
+
}
|
757
|
+
name() {
|
758
|
+
return this.get("_read_name");
|
759
|
+
}
|
760
|
+
_read_name() {
|
761
|
+
const e = this.get("_l_read_name"), { byteArray: t, start: n } = this.bytes;
|
762
|
+
return t.toString("ascii", n + 36, n + 36 + e - 1);
|
763
|
+
}
|
764
|
+
/**
|
765
|
+
* Get the value of a tag, parsing the tags as far as necessary.
|
766
|
+
* Only called if we have not already parsed that field.
|
767
|
+
*/
|
768
|
+
_parseTag(e) {
|
769
|
+
if (this._allTagsParsed)
|
770
|
+
return;
|
771
|
+
const { byteArray: t, start: n } = this.bytes;
|
772
|
+
let r = this._tagOffset || n + 36 + this.get("_l_read_name") + this.get("_n_cigar_op") * 4 + this.get("_seq_bytes") + this.get("seq_length");
|
773
|
+
const a = this.bytes.end;
|
774
|
+
let i;
|
775
|
+
for (; r < a && i !== e; ) {
|
776
|
+
const c = String.fromCharCode(t[r], t[r + 1]);
|
777
|
+
i = c.toLowerCase();
|
778
|
+
const d = String.fromCharCode(t[r + 2]);
|
779
|
+
r += 3;
|
780
|
+
let s;
|
781
|
+
switch (d) {
|
782
|
+
case "A": {
|
783
|
+
s = String.fromCharCode(t[r]), r += 1;
|
784
|
+
break;
|
785
|
+
}
|
786
|
+
case "i": {
|
787
|
+
s = t.readInt32LE(r), r += 4;
|
788
|
+
break;
|
789
|
+
}
|
790
|
+
case "I": {
|
791
|
+
s = t.readUInt32LE(r), r += 4;
|
792
|
+
break;
|
793
|
+
}
|
794
|
+
case "c": {
|
795
|
+
s = t.readInt8(r), r += 1;
|
796
|
+
break;
|
797
|
+
}
|
798
|
+
case "C": {
|
799
|
+
s = t.readUInt8(r), r += 1;
|
800
|
+
break;
|
801
|
+
}
|
802
|
+
case "s": {
|
803
|
+
s = t.readInt16LE(r), r += 2;
|
804
|
+
break;
|
805
|
+
}
|
806
|
+
case "S": {
|
807
|
+
s = t.readUInt16LE(r), r += 2;
|
808
|
+
break;
|
809
|
+
}
|
810
|
+
case "f": {
|
811
|
+
s = t.readFloatLE(r), r += 4;
|
812
|
+
break;
|
813
|
+
}
|
814
|
+
case "Z":
|
815
|
+
case "H": {
|
816
|
+
for (s = ""; r <= a; ) {
|
817
|
+
const l = t[r++];
|
818
|
+
if (l === 0)
|
819
|
+
break;
|
820
|
+
s += String.fromCharCode(l);
|
821
|
+
}
|
822
|
+
break;
|
823
|
+
}
|
824
|
+
case "B": {
|
825
|
+
s = "";
|
826
|
+
const l = t[r++], u = String.fromCharCode(l), h = t.readInt32LE(r);
|
827
|
+
if (r += 4, u === "i")
|
828
|
+
if (c === "CG")
|
829
|
+
for (let f = 0; f < h; f++) {
|
830
|
+
const m = t.readInt32LE(r), b = m >> 4, x = C[m & 15];
|
831
|
+
s += b + x, r += 4;
|
832
|
+
}
|
833
|
+
else
|
834
|
+
for (let f = 0; f < h; f++)
|
835
|
+
s += t.readInt32LE(r), f + 1 < h && (s += ","), r += 4;
|
836
|
+
if (u === "I")
|
837
|
+
if (c === "CG")
|
838
|
+
for (let f = 0; f < h; f++) {
|
839
|
+
const m = t.readUInt32LE(r), b = m >> 4, x = C[m & 15];
|
840
|
+
s += b + x, r += 4;
|
841
|
+
}
|
842
|
+
else
|
843
|
+
for (let f = 0; f < h; f++)
|
844
|
+
s += t.readUInt32LE(r), f + 1 < h && (s += ","), r += 4;
|
845
|
+
if (u === "s")
|
846
|
+
for (let f = 0; f < h; f++)
|
847
|
+
s += t.readInt16LE(r), f + 1 < h && (s += ","), r += 2;
|
848
|
+
if (u === "S")
|
849
|
+
for (let f = 0; f < h; f++)
|
850
|
+
s += t.readUInt16LE(r), f + 1 < h && (s += ","), r += 2;
|
851
|
+
if (u === "c")
|
852
|
+
for (let f = 0; f < h; f++)
|
853
|
+
s += t.readInt8(r), f + 1 < h && (s += ","), r += 1;
|
854
|
+
if (u === "C")
|
855
|
+
for (let f = 0; f < h; f++)
|
856
|
+
s += t.readUInt8(r), f + 1 < h && (s += ","), r += 1;
|
857
|
+
if (u === "f")
|
858
|
+
for (let f = 0; f < h; f++)
|
859
|
+
s += t.readFloatLE(r), f + 1 < h && (s += ","), r += 4;
|
860
|
+
break;
|
861
|
+
}
|
862
|
+
default:
|
863
|
+
console.warn(`Unknown BAM tag type '${d}', tags may be incomplete`), s = void 0, r = a;
|
864
|
+
}
|
865
|
+
if (this._tagOffset = r, this._tagList.push(c), i === e)
|
866
|
+
return s;
|
867
|
+
this.data[i] = s;
|
868
|
+
}
|
869
|
+
this._allTagsParsed = !0;
|
870
|
+
}
|
871
|
+
_parseAllTags() {
|
872
|
+
this._parseTag("");
|
873
|
+
}
|
874
|
+
_parseCigar(e) {
|
875
|
+
return (
|
876
|
+
//@ts-ignore
|
877
|
+
e.match(/\d+\D/g).map((t) => [t.match(/\D/)[0].toUpperCase(), Number.parseInt(t, 10)])
|
878
|
+
);
|
879
|
+
}
|
880
|
+
/**
|
881
|
+
* @returns {boolean} true if the read is paired, regardless of whether both segments are mapped
|
882
|
+
*/
|
883
|
+
isPaired() {
|
884
|
+
return !!(this.flags & _.BAM_FPAIRED);
|
885
|
+
}
|
886
|
+
/** @returns {boolean} true if the read is paired, and both segments are mapped */
|
887
|
+
isProperlyPaired() {
|
888
|
+
return !!(this.flags & _.BAM_FPROPER_PAIR);
|
889
|
+
}
|
890
|
+
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
891
|
+
isSegmentUnmapped() {
|
892
|
+
return !!(this.flags & _.BAM_FUNMAP);
|
893
|
+
}
|
894
|
+
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
895
|
+
isMateUnmapped() {
|
896
|
+
return !!(this.flags & _.BAM_FMUNMAP);
|
897
|
+
}
|
898
|
+
/** @returns {boolean} true if the read is mapped to the reverse strand */
|
899
|
+
isReverseComplemented() {
|
900
|
+
return !!(this.flags & _.BAM_FREVERSE);
|
901
|
+
}
|
902
|
+
/** @returns {boolean} true if the mate is mapped to the reverse strand */
|
903
|
+
isMateReverseComplemented() {
|
904
|
+
return !!(this.flags & _.BAM_FMREVERSE);
|
905
|
+
}
|
906
|
+
/** @returns {boolean} true if this is read number 1 in a pair */
|
907
|
+
isRead1() {
|
908
|
+
return !!(this.flags & _.BAM_FREAD1);
|
909
|
+
}
|
910
|
+
/** @returns {boolean} true if this is read number 2 in a pair */
|
911
|
+
isRead2() {
|
912
|
+
return !!(this.flags & _.BAM_FREAD2);
|
913
|
+
}
|
914
|
+
/** @returns {boolean} true if this is a secondary alignment */
|
915
|
+
isSecondary() {
|
916
|
+
return !!(this.flags & _.BAM_FSECONDARY);
|
917
|
+
}
|
918
|
+
/** @returns {boolean} true if this read has failed QC checks */
|
919
|
+
isFailedQc() {
|
920
|
+
return !!(this.flags & _.BAM_FQCFAIL);
|
921
|
+
}
|
922
|
+
/** @returns {boolean} true if the read is an optical or PCR duplicate */
|
923
|
+
isDuplicate() {
|
924
|
+
return !!(this.flags & _.BAM_FDUP);
|
925
|
+
}
|
926
|
+
/** @returns {boolean} true if this is a supplementary alignment */
|
927
|
+
isSupplementary() {
|
928
|
+
return !!(this.flags & _.BAM_FSUPPLEMENTARY);
|
929
|
+
}
|
930
|
+
cigar() {
|
931
|
+
if (this.isSegmentUnmapped())
|
932
|
+
return;
|
933
|
+
const { byteArray: e, start: t } = this.bytes, n = this.get("_n_cigar_op");
|
934
|
+
let r = t + 36 + this.get("_l_read_name");
|
935
|
+
const a = this.get("seq_length");
|
936
|
+
let i = "", c = 0, d = e.readInt32LE(r), s = d >> 4, l = C[d & 15];
|
937
|
+
if (l === "S" && s === a)
|
938
|
+
return r += 4, d = e.readInt32LE(r), s = d >> 4, l = C[d & 15], l !== "N" && console.warn("CG tag with no N tag"), this.data.length_on_ref = s, this.get("CG");
|
939
|
+
for (let u = 0; u < n; ++u)
|
940
|
+
d = e.readInt32LE(r), s = d >> 4, l = C[d & 15], i += s + l, l !== "H" && l !== "S" && l !== "I" && (c += s), r += 4;
|
941
|
+
return this.data.length_on_ref = c, i;
|
942
|
+
}
|
943
|
+
_flags() {
|
944
|
+
}
|
945
|
+
length_on_ref() {
|
946
|
+
return this.data.length_on_ref ? this.data.length_on_ref : (this.get("cigar"), this.data.length_on_ref);
|
947
|
+
}
|
948
|
+
_n_cigar_op() {
|
949
|
+
return this.get("_flag_nc") & 65535;
|
950
|
+
}
|
951
|
+
_l_read_name() {
|
952
|
+
return this.get("_bin_mq_nl") & 255;
|
953
|
+
}
|
954
|
+
/**
|
955
|
+
* number of bytes in the sequence field
|
956
|
+
*/
|
957
|
+
_seq_bytes() {
|
958
|
+
return this.get("seq_length") + 1 >> 1;
|
959
|
+
}
|
960
|
+
getReadBases() {
|
961
|
+
return this.seq();
|
962
|
+
}
|
963
|
+
seq() {
|
964
|
+
const { byteArray: e, start: t } = this.bytes, n = t + 36 + this.get("_l_read_name") + this.get("_n_cigar_op") * 4, r = this.get("_seq_bytes"), a = this.get("seq_length");
|
965
|
+
let i = "", c = 0;
|
966
|
+
for (let d = 0; d < r; ++d) {
|
967
|
+
const s = e[n + d];
|
968
|
+
i += N[(s & 240) >> 4], c++, c < a && (i += N[s & 15], c++);
|
969
|
+
}
|
970
|
+
return i;
|
971
|
+
}
|
972
|
+
// adapted from igv.js
|
973
|
+
getPairOrientation() {
|
974
|
+
if (!this.isSegmentUnmapped() && !this.isMateUnmapped() && this._refID === this._next_refid()) {
|
975
|
+
const e = this.isReverseComplemented() ? "R" : "F", t = this.isMateReverseComplemented() ? "R" : "F";
|
976
|
+
let n = " ", r = " ";
|
977
|
+
this.isRead1() ? (n = "1", r = "2") : this.isRead2() && (n = "2", r = "1");
|
978
|
+
const a = [];
|
979
|
+
return this.template_length() > 0 ? (a[0] = e, a[1] = n, a[2] = t, a[3] = r) : (a[2] = e, a[3] = n, a[0] = t, a[1] = r), a.join("");
|
980
|
+
}
|
981
|
+
return "";
|
982
|
+
}
|
983
|
+
_bin_mq_nl() {
|
984
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 12);
|
985
|
+
}
|
986
|
+
_flag_nc() {
|
987
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 16);
|
988
|
+
}
|
989
|
+
seq_length() {
|
990
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 20);
|
991
|
+
}
|
992
|
+
_next_refid() {
|
993
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 24);
|
994
|
+
}
|
995
|
+
_next_pos() {
|
996
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 28);
|
997
|
+
}
|
998
|
+
template_length() {
|
999
|
+
return this.bytes.byteArray.readInt32LE(this.bytes.start + 32);
|
1000
|
+
}
|
1001
|
+
toJSON() {
|
1002
|
+
const e = {};
|
1003
|
+
for (const t of Object.keys(this))
|
1004
|
+
t.charAt(0) === "_" || t === "bytes" || (e[t] = this[t]);
|
1005
|
+
return e;
|
1006
|
+
}
|
1007
|
+
}
|
1008
|
+
function V(o) {
|
1009
|
+
const e = o.split(/\r?\n/), t = [];
|
1010
|
+
for (const n of e) {
|
1011
|
+
const [r, ...a] = n.split(/\t/);
|
1012
|
+
r && t.push({
|
1013
|
+
tag: r.slice(1),
|
1014
|
+
data: a.map((i) => {
|
1015
|
+
const [c, d] = i.split(":", 2);
|
1016
|
+
return { tag: c, value: d };
|
1017
|
+
})
|
1018
|
+
});
|
1019
|
+
}
|
1020
|
+
return t;
|
1021
|
+
}
|
1022
|
+
const Q = 21840194, D = 65536;
|
1023
|
+
async function me(o) {
|
1024
|
+
let e = [];
|
1025
|
+
for await (const t of o)
|
1026
|
+
e = e.concat(t);
|
1027
|
+
return e;
|
1028
|
+
}
|
1029
|
+
class ge {
|
1030
|
+
read() {
|
1031
|
+
throw new Error("never called");
|
1032
|
+
}
|
1033
|
+
stat() {
|
1034
|
+
throw new Error("never called");
|
1035
|
+
}
|
1036
|
+
readFile() {
|
1037
|
+
throw new Error("never called");
|
1038
|
+
}
|
1039
|
+
close() {
|
1040
|
+
throw new Error("never called");
|
1041
|
+
}
|
1042
|
+
}
|
1043
|
+
class _e {
|
1044
|
+
constructor({ bamFilehandle: e, bamPath: t, bamUrl: n, baiPath: r, baiFilehandle: a, baiUrl: i, csiPath: c, csiFilehandle: d, csiUrl: s, htsget: l, yieldThreadTime: u = 100, renameRefSeqs: h = (f) => f }) {
|
1045
|
+
if (this.htsget = !1, this.featureCache = new J({
|
1046
|
+
cache: new K({
|
1047
|
+
maxSize: 50
|
1048
|
+
}),
|
1049
|
+
fill: async (f, m) => {
|
1050
|
+
const { chunk: b, opts: x } = f, { data: g, cpositions: p, dpositions: w } = await this._readChunk({
|
1051
|
+
chunk: b,
|
1052
|
+
opts: { ...x, signal: m }
|
1053
|
+
});
|
1054
|
+
return this.readBamFeatures(g, p, w, b);
|
1055
|
+
}
|
1056
|
+
}), this.renameRefSeq = h, e)
|
1057
|
+
this.bam = e;
|
1058
|
+
else if (t)
|
1059
|
+
this.bam = new R(t);
|
1060
|
+
else if (n)
|
1061
|
+
this.bam = new k(n);
|
1062
|
+
else if (l)
|
1063
|
+
this.htsget = !0, this.bam = new ge();
|
1064
|
+
else
|
1065
|
+
throw new Error("unable to initialize bam");
|
1066
|
+
if (d)
|
1067
|
+
this.index = new T({ filehandle: d });
|
1068
|
+
else if (c)
|
1069
|
+
this.index = new T({ filehandle: new R(c) });
|
1070
|
+
else if (s)
|
1071
|
+
this.index = new T({ filehandle: new k(s) });
|
1072
|
+
else if (a)
|
1073
|
+
this.index = new A({ filehandle: a });
|
1074
|
+
else if (r)
|
1075
|
+
this.index = new A({ filehandle: new R(r) });
|
1076
|
+
else if (i)
|
1077
|
+
this.index = new A({ filehandle: new k(i) });
|
1078
|
+
else if (t)
|
1079
|
+
this.index = new A({ filehandle: new R(`${t}.bai`) });
|
1080
|
+
else if (n)
|
1081
|
+
this.index = new A({ filehandle: new k(`${n}.bai`) });
|
1082
|
+
else if (l)
|
1083
|
+
this.htsget = !0;
|
1084
|
+
else
|
1085
|
+
throw new Error("unable to infer index format");
|
1086
|
+
this.yieldThreadTime = u;
|
1087
|
+
}
|
1088
|
+
async getHeaderPre(e) {
|
1089
|
+
const t = re(e);
|
1090
|
+
if (!this.index)
|
1091
|
+
return;
|
1092
|
+
const n = await this.index.parse(t), r = n.firstDataLine ? n.firstDataLine.blockPosition + 65535 : void 0;
|
1093
|
+
let a;
|
1094
|
+
if (r) {
|
1095
|
+
const l = r + D, u = await this.bam.read(E.Buffer.alloc(l), 0, l, 0, t);
|
1096
|
+
if (!u.bytesRead)
|
1097
|
+
throw new Error("Error reading header");
|
1098
|
+
a = u.buffer.subarray(0, Math.min(u.bytesRead, r));
|
1099
|
+
} else
|
1100
|
+
a = await this.bam.readFile(t);
|
1101
|
+
const i = await L(a);
|
1102
|
+
if (i.readInt32LE(0) !== Q)
|
1103
|
+
throw new Error("Not a BAM file");
|
1104
|
+
const c = i.readInt32LE(4);
|
1105
|
+
this.header = i.toString("utf8", 8, 8 + c);
|
1106
|
+
const { chrToIndex: d, indexToChr: s } = await this._readRefSeqs(c + 8, 65535, t);
|
1107
|
+
return this.chrToIndex = d, this.indexToChr = s, V(this.header);
|
1108
|
+
}
|
1109
|
+
getHeader(e) {
|
1110
|
+
return this.headerP || (this.headerP = this.getHeaderPre(e).catch((t) => {
|
1111
|
+
throw this.headerP = void 0, t;
|
1112
|
+
})), this.headerP;
|
1113
|
+
}
|
1114
|
+
async getHeaderText(e = {}) {
|
1115
|
+
return await this.getHeader(e), this.header;
|
1116
|
+
}
|
1117
|
+
// the full length of the refseq block is not given in advance so this grabs
|
1118
|
+
// a chunk and doubles it if all refseqs haven't been processed
|
1119
|
+
async _readRefSeqs(e, t, n) {
|
1120
|
+
if (e > t)
|
1121
|
+
return this._readRefSeqs(e, t * 2, n);
|
1122
|
+
const r = t + D, { bytesRead: a, buffer: i } = await this.bam.read(E.Buffer.alloc(r), 0, t, 0, n);
|
1123
|
+
if (!a)
|
1124
|
+
throw new Error("Error reading refseqs from header");
|
1125
|
+
const c = await L(i.subarray(0, Math.min(a, t))), d = c.readInt32LE(e);
|
1126
|
+
let s = e + 4;
|
1127
|
+
const l = {}, u = [];
|
1128
|
+
for (let h = 0; h < d; h += 1) {
|
1129
|
+
const f = c.readInt32LE(s), m = this.renameRefSeq(c.toString("utf8", s + 4, s + 4 + f - 1)), b = c.readInt32LE(s + f + 4);
|
1130
|
+
if (l[m] = h, u.push({ refName: m, length: b }), s = s + 8 + f, s > c.length)
|
1131
|
+
return console.warn(`BAM header is very big. Re-fetching ${t} bytes.`), this._readRefSeqs(e, t * 2, n);
|
1132
|
+
}
|
1133
|
+
return { chrToIndex: l, indexToChr: u };
|
1134
|
+
}
|
1135
|
+
async getRecordsForRange(e, t, n, r) {
|
1136
|
+
return me(this.streamRecordsForRange(e, t, n, r));
|
1137
|
+
}
|
1138
|
+
async *streamRecordsForRange(e, t, n, r) {
|
1139
|
+
var a;
|
1140
|
+
await this.getHeader(r);
|
1141
|
+
const i = (a = this.chrToIndex) === null || a === void 0 ? void 0 : a[e];
|
1142
|
+
if (i === void 0 || !this.index)
|
1143
|
+
yield [];
|
1144
|
+
else {
|
1145
|
+
const c = await this.index.blocksForRange(i, t - 1, n, r);
|
1146
|
+
yield* this._fetchChunkFeatures(c, i, t, n, r);
|
1147
|
+
}
|
1148
|
+
}
|
1149
|
+
async *_fetchChunkFeatures(e, t, n, r, a = {}) {
|
1150
|
+
const { viewAsPairs: i } = a, c = [];
|
1151
|
+
let d = !1;
|
1152
|
+
for (const s of e) {
|
1153
|
+
const l = await this.featureCache.get(s.toString(), { chunk: s, opts: a }, a.signal), u = [];
|
1154
|
+
for (const h of l)
|
1155
|
+
if (h.seq_id() === t)
|
1156
|
+
if (h.get("start") >= r) {
|
1157
|
+
d = !0;
|
1158
|
+
break;
|
1159
|
+
} else
|
1160
|
+
h.get("end") >= n && u.push(h);
|
1161
|
+
if (c.push(u), yield u, d)
|
1162
|
+
break;
|
1163
|
+
}
|
1164
|
+
te(a.signal), i && (yield this.fetchPairs(t, c, a));
|
1165
|
+
}
|
1166
|
+
async fetchPairs(e, t, n) {
|
1167
|
+
const { pairAcrossChr: r, maxInsertSize: a = 2e5 } = n, i = {}, c = {};
|
1168
|
+
t.map((h) => {
|
1169
|
+
const f = {};
|
1170
|
+
for (const m of h) {
|
1171
|
+
const b = m.name(), x = m.id();
|
1172
|
+
f[b] || (f[b] = 0), f[b]++, c[x] = 1;
|
1173
|
+
}
|
1174
|
+
for (const [m, b] of Object.entries(f))
|
1175
|
+
b === 1 && (i[m] = !0);
|
1176
|
+
});
|
1177
|
+
const d = [];
|
1178
|
+
t.map((h) => {
|
1179
|
+
for (const f of h) {
|
1180
|
+
const m = f.name(), b = f.get("start"), x = f._next_pos(), g = f._next_refid();
|
1181
|
+
this.index && i[m] && (r || g === e && Math.abs(b - x) < a) && d.push(this.index.blocksForRange(g, x, x + 1, n));
|
1182
|
+
}
|
1183
|
+
});
|
1184
|
+
const s = /* @__PURE__ */ new Map(), l = await Promise.all(d);
|
1185
|
+
for (const h of l.flat())
|
1186
|
+
s.has(h.toString()) || s.set(h.toString(), h);
|
1187
|
+
return (await Promise.all([...s.values()].map(async (h) => {
|
1188
|
+
const { data: f, cpositions: m, dpositions: b, chunk: x } = await this._readChunk({
|
1189
|
+
chunk: h,
|
1190
|
+
opts: n
|
1191
|
+
}), g = [];
|
1192
|
+
for (const p of await this.readBamFeatures(f, m, b, x))
|
1193
|
+
i[p.get("name")] && !c[p.id()] && g.push(p);
|
1194
|
+
return g;
|
1195
|
+
}))).flat();
|
1196
|
+
}
|
1197
|
+
async _readRegion(e, t, n = {}) {
|
1198
|
+
const { bytesRead: r, buffer: a } = await this.bam.read(E.Buffer.alloc(t), 0, t, e, n);
|
1199
|
+
return a.subarray(0, Math.min(r, t));
|
1200
|
+
}
|
1201
|
+
async _readChunk({ chunk: e, opts: t }) {
|
1202
|
+
const n = await this._readRegion(e.minv.blockPosition, e.fetchedSize(), t), { buffer: r, cpositions: a, dpositions: i } = await X(n, e);
|
1203
|
+
return { data: r, cpositions: a, dpositions: i, chunk: e };
|
1204
|
+
}
|
1205
|
+
async readBamFeatures(e, t, n, r) {
|
1206
|
+
let a = 0;
|
1207
|
+
const i = [];
|
1208
|
+
let c = 0, d = +Date.now();
|
1209
|
+
for (; a + 4 < e.length; ) {
|
1210
|
+
const s = e.readInt32LE(a), l = a + 4 + s - 1;
|
1211
|
+
if (n) {
|
1212
|
+
for (; a + r.minv.dataPosition >= n[c++]; )
|
1213
|
+
;
|
1214
|
+
c--;
|
1215
|
+
}
|
1216
|
+
if (l < e.length) {
|
1217
|
+
const u = new be({
|
1218
|
+
bytes: {
|
1219
|
+
byteArray: e,
|
1220
|
+
start: a,
|
1221
|
+
end: l
|
1222
|
+
},
|
1223
|
+
// the below results in an automatically calculated file-offset based
|
1224
|
+
// ID if the info for that is available, otherwise crc32 of the
|
1225
|
+
// features
|
1226
|
+
//
|
1227
|
+
// cpositions[pos] refers to actual file offset of a bgzip block
|
1228
|
+
// boundaries
|
1229
|
+
//
|
1230
|
+
// we multiply by (1 <<8) in order to make sure each block has a
|
1231
|
+
// "unique" address space so that data in that block could never
|
1232
|
+
// overlap
|
1233
|
+
//
|
1234
|
+
// then the blockStart-dpositions is an uncompressed file offset from
|
1235
|
+
// that bgzip block boundary, and since the cpositions are multiplied
|
1236
|
+
// by (1 << 8) these uncompressed offsets get a unique space
|
1237
|
+
//
|
1238
|
+
// this has an extra chunk.minv.dataPosition added on because it
|
1239
|
+
// blockStart starts at 0 instead of chunk.minv.dataPosition
|
1240
|
+
//
|
1241
|
+
// the +1 is just to avoid any possible uniqueId 0 but this does not
|
1242
|
+
// realistically happen
|
1243
|
+
fileOffset: t.length > 0 ? t[c] * 256 + (a - n[c]) + r.minv.dataPosition + 1 : (
|
1244
|
+
// must be slice, not subarray for buffer polyfill on web
|
1245
|
+
he.signed(e.slice(a, l))
|
1246
|
+
)
|
1247
|
+
});
|
1248
|
+
i.push(u), this.yieldThreadTime && +Date.now() - d > this.yieldThreadTime && (await Z(1), d = +Date.now());
|
1249
|
+
}
|
1250
|
+
a = l + 1;
|
1251
|
+
}
|
1252
|
+
return i;
|
1253
|
+
}
|
1254
|
+
async hasRefSeq(e) {
|
1255
|
+
var t, n;
|
1256
|
+
const r = (t = this.chrToIndex) === null || t === void 0 ? void 0 : t[e];
|
1257
|
+
return r === void 0 ? !1 : (n = this.index) === null || n === void 0 ? void 0 : n.hasRefSeq(r);
|
1258
|
+
}
|
1259
|
+
async lineCount(e) {
|
1260
|
+
var t;
|
1261
|
+
const n = (t = this.chrToIndex) === null || t === void 0 ? void 0 : t[e];
|
1262
|
+
return n === void 0 || !this.index ? 0 : this.index.lineCount(n);
|
1263
|
+
}
|
1264
|
+
async indexCov(e, t, n) {
|
1265
|
+
var r;
|
1266
|
+
if (!this.index)
|
1267
|
+
return [];
|
1268
|
+
await this.index.parse();
|
1269
|
+
const a = (r = this.chrToIndex) === null || r === void 0 ? void 0 : r[e];
|
1270
|
+
return a === void 0 ? [] : this.index.indexCov(a, t, n);
|
1271
|
+
}
|
1272
|
+
async blocksForRange(e, t, n, r) {
|
1273
|
+
var a;
|
1274
|
+
if (!this.index)
|
1275
|
+
return [];
|
1276
|
+
await this.index.parse();
|
1277
|
+
const i = (a = this.chrToIndex) === null || a === void 0 ? void 0 : a[e];
|
1278
|
+
return i === void 0 ? [] : this.index.blocksForRange(i, t, n, r);
|
1279
|
+
}
|
1280
|
+
}
|
1281
|
+
async function $(o, e) {
|
1282
|
+
const t = await Promise.all(o.map(async (n) => {
|
1283
|
+
const { url: r, headers: a } = n;
|
1284
|
+
if (r.startsWith("data:"))
|
1285
|
+
return E.Buffer.from(r.split(",")[1], "base64");
|
1286
|
+
{
|
1287
|
+
const { referer: i, ...c } = a, d = await fetch(r, {
|
1288
|
+
...e,
|
1289
|
+
headers: { ...e == null ? void 0 : e.headers, ...c }
|
1290
|
+
});
|
1291
|
+
if (!d.ok)
|
1292
|
+
throw new Error(`HTTP ${d.status} fetching ${r}: ${await d.text()}`);
|
1293
|
+
return E.Buffer.from(await d.arrayBuffer());
|
1294
|
+
}
|
1295
|
+
}));
|
1296
|
+
return E.Buffer.concat(await Promise.all(t.map((n) => L(n))));
|
1297
|
+
}
|
1298
|
+
class Ae extends _e {
|
1299
|
+
constructor(e) {
|
1300
|
+
super({ htsget: !0 }), this.baseUrl = e.baseUrl, this.trackId = e.trackId;
|
1301
|
+
}
|
1302
|
+
async *streamRecordsForRange(e, t, n, r) {
|
1303
|
+
var a;
|
1304
|
+
const c = `${`${this.baseUrl}/${this.trackId}`}?referenceName=${e}&start=${t}&end=${n}&format=BAM`, d = (a = this.chrToIndex) === null || a === void 0 ? void 0 : a[e];
|
1305
|
+
if (d === void 0)
|
1306
|
+
yield [];
|
1307
|
+
else {
|
1308
|
+
const s = await fetch(c, { ...r });
|
1309
|
+
if (!s.ok)
|
1310
|
+
throw new Error(`HTTP ${s.status} fetching ${c}: ${await s.text()}`);
|
1311
|
+
const l = await s.json(), u = await $(l.htsget.urls.slice(1), r);
|
1312
|
+
yield* this._fetchChunkFeatures([
|
1313
|
+
// fake stuff to pretend to be a Chunk
|
1314
|
+
{
|
1315
|
+
buffer: u,
|
1316
|
+
_fetchedSize: void 0,
|
1317
|
+
bin: 0,
|
1318
|
+
compareTo() {
|
1319
|
+
return 0;
|
1320
|
+
},
|
1321
|
+
toUniqueString() {
|
1322
|
+
return `${e}_${t}_${n}`;
|
1323
|
+
},
|
1324
|
+
fetchedSize() {
|
1325
|
+
return 0;
|
1326
|
+
},
|
1327
|
+
minv: {
|
1328
|
+
dataPosition: 0,
|
1329
|
+
blockPosition: 0,
|
1330
|
+
compareTo: () => 0
|
1331
|
+
},
|
1332
|
+
maxv: {
|
1333
|
+
dataPosition: Number.MAX_SAFE_INTEGER,
|
1334
|
+
blockPosition: 0,
|
1335
|
+
compareTo: () => 0
|
1336
|
+
},
|
1337
|
+
toString() {
|
1338
|
+
return `${e}_${t}_${n}`;
|
1339
|
+
}
|
1340
|
+
}
|
1341
|
+
], d, t, n, r);
|
1342
|
+
}
|
1343
|
+
}
|
1344
|
+
async _readChunk({ chunk: e }) {
|
1345
|
+
if (!e.buffer)
|
1346
|
+
throw new Error("expected chunk.buffer in htsget");
|
1347
|
+
return { data: e.buffer, cpositions: [], dpositions: [], chunk: e };
|
1348
|
+
}
|
1349
|
+
async getHeader(e = {}) {
|
1350
|
+
const t = `${this.baseUrl}/${this.trackId}?referenceName=na&class=header`, n = await fetch(t, e);
|
1351
|
+
if (!n.ok)
|
1352
|
+
throw new Error(`HTTP ${n.status} fetching ${t}: ${await n.text()}`);
|
1353
|
+
const r = await n.json(), a = await $(r.htsget.urls, e);
|
1354
|
+
if (a.readInt32LE(0) !== Q)
|
1355
|
+
throw new Error("Not a BAM file");
|
1356
|
+
const i = a.readInt32LE(4), c = a.toString("utf8", 8, 8 + i), d = V(c), s = [], l = {}, u = d.filter((h) => h.tag === "SQ");
|
1357
|
+
for (const [h, f] of u.entries()) {
|
1358
|
+
let m = "", b = 0;
|
1359
|
+
for (const x of f.data)
|
1360
|
+
x.tag === "SN" ? m = x.value : x.tag === "LN" && (b = +x.value);
|
1361
|
+
l[m] = h, s[h] = { refName: m, length: b };
|
1362
|
+
}
|
1363
|
+
return this.chrToIndex = l, this.indexToChr = s, d;
|
1364
|
+
}
|
1365
|
+
}
|
1366
|
+
export {
|
1367
|
+
A as BAI,
|
1368
|
+
_e as BamFile,
|
1369
|
+
be as BamRecord,
|
1370
|
+
T as CSI,
|
1371
|
+
Ae as HtsgetFile
|
1372
|
+
};
|