@genome-spy/app 0.51.0 → 0.53.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/{index-C8lYPtq_.js → index-B5cesONJ.js} +21 -21
- package/dist/index-BJLu48Hz.js +274 -0
- package/dist/{index-Sk-Wtwdn.js → index-BywMLhhd.js} +963 -989
- package/dist/{index-BwFvhduA.js → index-CSayoXbw.js} +7 -9
- package/dist/{index-CkI3Kd2P.js → index-DAJ8JQLE.js} +6 -5
- package/dist/{index-BtRKzKhM.js → index-_tI-fMQF.js} +414 -415
- package/dist/{index-CmBp-spD.js → index-e0oKgZbZ.js} +36 -36
- package/dist/{index-Z7JiNsFI.js → index-oqw_s02W.js} +10 -11
- package/dist/{index-mihmTLo-.js → index-uO0O4Uv-.js} +22 -22
- package/dist/index.es.js +10691 -7888
- package/dist/index.js +489 -360
- package/dist/{long-CYrAUkxh.js → long-D4tVjLLz.js} +5 -5
- package/dist/remoteFile-BkTxwFub.js +90 -0
- package/dist/style.css +1 -1
- package/package.json +5 -6
- package/LICENSE +0 -21
- package/dist/index-Dixm7K89.js +0 -279
- package/dist/remoteFile-1_eCK3VV.js +0 -96
@@ -1,10 +1,9 @@
|
|
1
|
-
import { L as
|
2
|
-
import { b as
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
|
7
|
-
class U {
|
1
|
+
import { L as V, u as k, a as Q } from "./long-D4tVjLLz.js";
|
2
|
+
import { b as I } from "./index-B5cesONJ.js";
|
3
|
+
import { L as A } from "./__vite-browser-external-C--ziKoh.js";
|
4
|
+
import { R } from "./remoteFile-BkTxwFub.js";
|
5
|
+
import { _ as Y, L as W } from "./index-uO0O4Uv-.js";
|
6
|
+
class D {
|
8
7
|
constructor(e, t) {
|
9
8
|
this.blockPosition = e, this.dataPosition = t;
|
10
9
|
}
|
@@ -23,17 +22,17 @@ class U {
|
|
23
22
|
return t;
|
24
23
|
}
|
25
24
|
}
|
26
|
-
function
|
25
|
+
function x(o, e = 0, t = !1) {
|
27
26
|
if (t)
|
28
27
|
throw new Error("big-endian virtual file offsets not implemented");
|
29
|
-
return new
|
28
|
+
return new D(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
29
|
}
|
31
|
-
class
|
30
|
+
class $ {
|
32
31
|
constructor(e, t, n, r) {
|
33
32
|
this.minv = e, this.maxv = t, this.bin = n, this._fetchedSize = r;
|
34
33
|
}
|
35
34
|
toUniqueString() {
|
36
|
-
return `${this.minv}..${this.maxv} (bin ${this.bin}, fetchedSize ${this.fetchedSize()})`;
|
35
|
+
return `${this.minv.toString()}..${this.maxv.toString()} (bin ${this.bin}, fetchedSize ${this.fetchedSize()})`;
|
37
36
|
}
|
38
37
|
toString() {
|
39
38
|
return this.toUniqueString();
|
@@ -45,15 +44,15 @@ class z {
|
|
45
44
|
return this._fetchedSize !== void 0 ? this._fetchedSize : this.maxv.blockPosition + 65536 - this.minv.blockPosition;
|
46
45
|
}
|
47
46
|
}
|
48
|
-
function
|
47
|
+
function X(o) {
|
49
48
|
return new Promise((e) => setTimeout(e, o));
|
50
49
|
}
|
51
|
-
function
|
50
|
+
function J(o) {
|
52
51
|
if (o.greaterThan(Number.MAX_SAFE_INTEGER) || o.lessThan(Number.MIN_SAFE_INTEGER))
|
53
52
|
throw new Error("integer overflow");
|
54
53
|
return o.toNumber();
|
55
54
|
}
|
56
|
-
function
|
55
|
+
function K(o) {
|
57
56
|
if (o && o.aborted)
|
58
57
|
if (typeof DOMException > "u") {
|
59
58
|
const e = new Error("aborted");
|
@@ -61,45 +60,45 @@ function te(o) {
|
|
61
60
|
} else
|
62
61
|
throw new DOMException("aborted", "AbortError");
|
63
62
|
}
|
64
|
-
function
|
63
|
+
function Z(o, e) {
|
65
64
|
return e.minv.blockPosition - o.maxv.blockPosition < 65e3 && e.maxv.blockPosition - o.minv.blockPosition < 5e6;
|
66
65
|
}
|
67
|
-
function
|
66
|
+
function ee(o = {}) {
|
68
67
|
return "aborted" in o ? { signal: o } : o;
|
69
68
|
}
|
70
|
-
function
|
69
|
+
function U(o, e) {
|
71
70
|
const t = [];
|
72
71
|
let n;
|
73
72
|
if (o.length === 0)
|
74
73
|
return o;
|
75
|
-
o.sort((r,
|
76
|
-
const
|
77
|
-
return
|
74
|
+
o.sort((r, s) => {
|
75
|
+
const a = r.minv.blockPosition - s.minv.blockPosition;
|
76
|
+
return a === 0 ? r.minv.dataPosition - s.minv.dataPosition : a;
|
78
77
|
});
|
79
78
|
for (const r of o)
|
80
|
-
(!e || r.maxv.compareTo(e) > 0) && (n === void 0 ? (t.push(r), n = r) :
|
79
|
+
(!e || r.maxv.compareTo(e) > 0) && (n === void 0 ? (t.push(r), n = r) : Z(n, r) ? r.maxv.compareTo(n.maxv) > 0 && (n.maxv = r.maxv) : (t.push(r), n = r));
|
81
80
|
return t;
|
82
81
|
}
|
83
|
-
function
|
84
|
-
return { lineCount:
|
82
|
+
function z(o, e) {
|
83
|
+
return { lineCount: J(V.fromBytesLE(Array.prototype.slice.call(o, e, e + 8), !0)) };
|
85
84
|
}
|
86
|
-
function
|
85
|
+
function L(o, e) {
|
87
86
|
return o ? o.compareTo(e) > 0 ? e : o : e;
|
88
87
|
}
|
89
|
-
function
|
88
|
+
function te(o, e = (t) => t) {
|
90
89
|
let t = 0, n = 0;
|
91
|
-
const r = [],
|
92
|
-
for (let
|
93
|
-
if (!o[
|
94
|
-
if (n <
|
95
|
-
let
|
96
|
-
|
90
|
+
const r = [], s = {};
|
91
|
+
for (let a = 0; a < o.length; a += 1)
|
92
|
+
if (!o[a]) {
|
93
|
+
if (n < a) {
|
94
|
+
let h = o.toString("utf8", n, a);
|
95
|
+
h = e(h), r[t] = h, s[h] = t;
|
97
96
|
}
|
98
|
-
n =
|
97
|
+
n = a + 1, t += 1;
|
99
98
|
}
|
100
|
-
return { refNameToId:
|
99
|
+
return { refNameToId: s, refIdToName: r };
|
101
100
|
}
|
102
|
-
class
|
101
|
+
class O {
|
103
102
|
/**
|
104
103
|
* @param {filehandle} filehandle
|
105
104
|
* @param {function} [renameRefSeqs]
|
@@ -108,14 +107,14 @@ class G {
|
|
108
107
|
this.filehandle = e, this.renameRefSeq = t;
|
109
108
|
}
|
110
109
|
}
|
111
|
-
const
|
112
|
-
function
|
110
|
+
const ne = 21578050;
|
111
|
+
function re(o, e) {
|
113
112
|
return o - o % e;
|
114
113
|
}
|
115
|
-
function
|
114
|
+
function se(o, e) {
|
116
115
|
return o - o % e + e;
|
117
116
|
}
|
118
|
-
function
|
117
|
+
function ie(o, e) {
|
119
118
|
return e -= 1, [
|
120
119
|
[0, 0],
|
121
120
|
[1 + (o >> 26), 1 + (e >> 26)],
|
@@ -125,7 +124,7 @@ function de(o, e) {
|
|
125
124
|
[4681 + (o >> 14), 4681 + (e >> 14)]
|
126
125
|
];
|
127
126
|
}
|
128
|
-
class
|
127
|
+
class v extends O {
|
129
128
|
async lineCount(e, t) {
|
130
129
|
var n, r;
|
131
130
|
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;
|
@@ -133,100 +132,100 @@ class A extends G {
|
|
133
132
|
// fetch and parse the index
|
134
133
|
async _parse(e) {
|
135
134
|
const t = await this.filehandle.readFile(e);
|
136
|
-
if (t.readUInt32LE(0) !==
|
135
|
+
if (t.readUInt32LE(0) !== ne)
|
137
136
|
throw new Error("Not a BAI file");
|
138
|
-
const n = t.readInt32LE(4),
|
139
|
-
let
|
140
|
-
const
|
141
|
-
for (let
|
142
|
-
const l = t.readInt32LE(
|
137
|
+
const n = t.readInt32LE(4), s = ((1 << (5 + 1) * 3) - 1) / 7;
|
138
|
+
let a = 8, h;
|
139
|
+
const c = new Array(n);
|
140
|
+
for (let i = 0; i < n; i++) {
|
141
|
+
const l = t.readInt32LE(a);
|
143
142
|
let u;
|
144
|
-
|
145
|
-
const
|
146
|
-
for (let
|
147
|
-
const
|
148
|
-
if (
|
149
|
-
|
143
|
+
a += 4;
|
144
|
+
const f = {};
|
145
|
+
for (let g = 0; g < l; g += 1) {
|
146
|
+
const m = t.readUInt32LE(a);
|
147
|
+
if (a += 4, m === s + 1)
|
148
|
+
a += 4, u = z(t, a + 16), a += 32;
|
150
149
|
else {
|
151
|
-
if (
|
150
|
+
if (m > s + 1)
|
152
151
|
throw new Error("bai index contains too many bins, please use CSI");
|
153
152
|
{
|
154
|
-
const
|
155
|
-
|
156
|
-
const
|
157
|
-
for (let
|
158
|
-
const
|
159
|
-
|
160
|
-
const S =
|
161
|
-
|
153
|
+
const p = t.readInt32LE(a);
|
154
|
+
a += 4;
|
155
|
+
const w = new Array(p);
|
156
|
+
for (let E = 0; E < p; E++) {
|
157
|
+
const y = x(t, a);
|
158
|
+
a += 8;
|
159
|
+
const S = x(t, a);
|
160
|
+
a += 8, h = L(h, y), w[E] = new $(y, S, m);
|
162
161
|
}
|
163
|
-
|
162
|
+
f[m] = w;
|
164
163
|
}
|
165
164
|
}
|
166
165
|
}
|
167
|
-
const
|
168
|
-
|
169
|
-
const
|
170
|
-
for (let
|
171
|
-
const
|
172
|
-
|
166
|
+
const d = t.readInt32LE(a);
|
167
|
+
a += 4;
|
168
|
+
const _ = new Array(d);
|
169
|
+
for (let g = 0; g < d; g++) {
|
170
|
+
const m = x(t, a);
|
171
|
+
a += 8, h = L(h, m), _[g] = m;
|
173
172
|
}
|
174
|
-
|
173
|
+
c[i] = { binIndex: f, linearIndex: _, stats: u };
|
175
174
|
}
|
176
175
|
return {
|
177
176
|
bai: !0,
|
178
|
-
firstDataLine:
|
177
|
+
firstDataLine: h,
|
179
178
|
maxBlockSize: 65536,
|
180
|
-
indices:
|
179
|
+
indices: c,
|
181
180
|
refCount: n
|
182
181
|
};
|
183
182
|
}
|
184
183
|
async indexCov(e, t, n, r = {}) {
|
185
|
-
const
|
186
|
-
if (!
|
184
|
+
const a = t !== void 0, c = (await this.parse(r)).indices[e];
|
185
|
+
if (!c)
|
187
186
|
return [];
|
188
|
-
const { linearIndex:
|
189
|
-
if (
|
187
|
+
const { linearIndex: i = [], stats: l } = c;
|
188
|
+
if (i.length === 0)
|
190
189
|
return [];
|
191
|
-
const u = n === void 0 ? (
|
192
|
-
if (u > (
|
190
|
+
const u = n === void 0 ? (i.length - 1) * 16384 : se(n, 16384), f = t === void 0 ? 0 : re(t, 16384), d = a ? new Array((u - f) / 16384) : new Array(i.length - 1), _ = i[i.length - 1].blockPosition;
|
191
|
+
if (u > (i.length - 1) * 16384)
|
193
192
|
throw new Error("query outside of range of linear index");
|
194
|
-
let
|
195
|
-
for (let
|
196
|
-
|
197
|
-
score:
|
198
|
-
start:
|
199
|
-
end:
|
200
|
-
},
|
201
|
-
return
|
202
|
-
...
|
203
|
-
score:
|
193
|
+
let g = i[f / 16384].blockPosition;
|
194
|
+
for (let m = f / 16384, p = 0; m < u / 16384; m++, p++)
|
195
|
+
d[p] = {
|
196
|
+
score: i[m + 1].blockPosition - g,
|
197
|
+
start: m * 16384,
|
198
|
+
end: m * 16384 + 16384
|
199
|
+
}, g = i[m + 1].blockPosition;
|
200
|
+
return d.map((m) => ({
|
201
|
+
...m,
|
202
|
+
score: m.score * ((l == null ? void 0 : l.lineCount) || 0) / _
|
204
203
|
}));
|
205
204
|
}
|
206
205
|
async blocksForRange(e, t, n, r = {}) {
|
207
206
|
t < 0 && (t = 0);
|
208
|
-
const
|
209
|
-
if (!
|
207
|
+
const s = await this.parse(r);
|
208
|
+
if (!s)
|
210
209
|
return [];
|
211
|
-
const
|
212
|
-
if (!
|
210
|
+
const a = s.indices[e];
|
211
|
+
if (!a)
|
213
212
|
return [];
|
214
|
-
const
|
215
|
-
for (const [
|
216
|
-
for (let
|
217
|
-
if (
|
218
|
-
const
|
219
|
-
for (const
|
220
|
-
|
213
|
+
const h = ie(t, n), c = [];
|
214
|
+
for (const [d, _] of h)
|
215
|
+
for (let g = d; g <= _; g++)
|
216
|
+
if (a.binIndex[g]) {
|
217
|
+
const m = a.binIndex[g];
|
218
|
+
for (const p of m)
|
219
|
+
c.push(p);
|
221
220
|
}
|
222
|
-
const
|
221
|
+
const i = a.linearIndex.length;
|
223
222
|
let l;
|
224
|
-
const u = Math.min(t >> 14,
|
225
|
-
for (let
|
226
|
-
const
|
227
|
-
|
223
|
+
const u = Math.min(t >> 14, i - 1), f = Math.min(n >> 14, i - 1);
|
224
|
+
for (let d = u; d <= f; ++d) {
|
225
|
+
const _ = a.linearIndex[d];
|
226
|
+
_ && (!l || _.compareTo(l) < 0) && (l = _);
|
228
227
|
}
|
229
|
-
return
|
228
|
+
return U(c, l);
|
230
229
|
}
|
231
230
|
async parse(e = {}) {
|
232
231
|
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
@@ -238,7 +237,10 @@ class A extends G {
|
|
238
237
|
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
239
238
|
}
|
240
239
|
}
|
241
|
-
|
240
|
+
function ae(o) {
|
241
|
+
return o && o.__esModule && Object.prototype.hasOwnProperty.call(o, "default") ? o.default : o;
|
242
|
+
}
|
243
|
+
const oe = new Int32Array([
|
242
244
|
0,
|
243
245
|
1996959894,
|
244
246
|
3993919788,
|
@@ -495,46 +497,45 @@ var I = E.Buffer, M = [
|
|
495
497
|
3272380065,
|
496
498
|
1510334235,
|
497
499
|
755167117
|
498
|
-
];
|
499
|
-
|
500
|
-
|
501
|
-
if (I.isBuffer(o))
|
500
|
+
]);
|
501
|
+
function H(o) {
|
502
|
+
if (Buffer.isBuffer(o))
|
502
503
|
return o;
|
503
|
-
var e = typeof I.alloc == "function" && typeof I.from == "function";
|
504
504
|
if (typeof o == "number")
|
505
|
-
return
|
505
|
+
return Buffer.alloc(o);
|
506
506
|
if (typeof o == "string")
|
507
|
-
return
|
507
|
+
return Buffer.from(o);
|
508
508
|
throw new Error("input must be buffer, number, or string, received " + typeof o);
|
509
509
|
}
|
510
510
|
function ce(o) {
|
511
|
-
|
511
|
+
const e = H(4);
|
512
512
|
return e.writeInt32BE(o, 0), e;
|
513
513
|
}
|
514
|
-
function
|
515
|
-
o =
|
516
|
-
|
517
|
-
|
514
|
+
function T(o, e) {
|
515
|
+
o = H(o), Buffer.isBuffer(e) && (e = e.readUInt32BE(0));
|
516
|
+
let t = ~~e ^ -1;
|
517
|
+
for (var n = 0; n < o.length; n++)
|
518
|
+
t = oe[(t ^ o[n]) & 255] ^ t >>> 8;
|
518
519
|
return t ^ -1;
|
519
520
|
}
|
520
|
-
function
|
521
|
-
return ce(
|
521
|
+
function M() {
|
522
|
+
return ce(T.apply(null, arguments));
|
522
523
|
}
|
523
|
-
|
524
|
-
return
|
524
|
+
M.signed = function() {
|
525
|
+
return T.apply(null, arguments);
|
525
526
|
};
|
526
|
-
|
527
|
-
return
|
527
|
+
M.unsigned = function() {
|
528
|
+
return T.apply(null, arguments) >>> 0;
|
528
529
|
};
|
529
|
-
var
|
530
|
-
const
|
531
|
-
function
|
530
|
+
var he = M;
|
531
|
+
const de = /* @__PURE__ */ ae(he), fe = 21582659, le = 38359875;
|
532
|
+
function ue(o, e) {
|
532
533
|
return o * 2 ** e;
|
533
534
|
}
|
534
|
-
function
|
535
|
+
function B(o, e) {
|
535
536
|
return Math.floor(o / 2 ** e);
|
536
537
|
}
|
537
|
-
class
|
538
|
+
class P extends O {
|
538
539
|
constructor() {
|
539
540
|
super(...arguments), this.maxBinNumber = 0, this.depth = 0, this.minShift = 0;
|
540
541
|
}
|
@@ -546,91 +547,91 @@ class T extends G {
|
|
546
547
|
return [];
|
547
548
|
}
|
548
549
|
parseAuxData(e, t) {
|
549
|
-
const n = e.readInt32LE(t), r = n & 65536 ? "zero-based-half-open" : "1-based-closed",
|
550
|
-
if (!
|
550
|
+
const n = e.readInt32LE(t), r = n & 65536 ? "zero-based-half-open" : "1-based-closed", s = { 0: "generic", 1: "SAM", 2: "VCF" }[n & 15];
|
551
|
+
if (!s)
|
551
552
|
throw new Error(`invalid Tabix preset format flags ${n}`);
|
552
|
-
const
|
553
|
+
const a = {
|
553
554
|
ref: e.readInt32LE(t + 4),
|
554
555
|
start: e.readInt32LE(t + 8),
|
555
556
|
end: e.readInt32LE(t + 12)
|
556
|
-
},
|
557
|
+
}, h = e.readInt32LE(t + 16), c = h ? String.fromCharCode(h) : "", i = e.readInt32LE(t + 20), l = e.readInt32LE(t + 24);
|
557
558
|
return {
|
558
|
-
columnNumbers:
|
559
|
+
columnNumbers: a,
|
559
560
|
coordinateType: r,
|
560
|
-
metaValue:
|
561
|
-
metaChar:
|
562
|
-
skipLines:
|
563
|
-
format:
|
561
|
+
metaValue: h,
|
562
|
+
metaChar: c,
|
563
|
+
skipLines: i,
|
564
|
+
format: s,
|
564
565
|
formatFlags: n,
|
565
|
-
...
|
566
|
+
...te(e.subarray(t + 28, t + 28 + l), this.renameRefSeq)
|
566
567
|
};
|
567
568
|
}
|
568
569
|
// fetch and parse the index
|
569
570
|
async _parse(e) {
|
570
|
-
const t = await this.filehandle.readFile(e), n = await
|
571
|
+
const t = await this.filehandle.readFile(e), n = await k(t);
|
571
572
|
let r;
|
572
|
-
if (n.readUInt32LE(0) ===
|
573
|
+
if (n.readUInt32LE(0) === fe)
|
573
574
|
r = 1;
|
574
|
-
else if (n.readUInt32LE(0) ===
|
575
|
+
else if (n.readUInt32LE(0) === le)
|
575
576
|
r = 2;
|
576
577
|
else
|
577
578
|
throw new Error("Not a CSI file");
|
578
579
|
this.minShift = n.readInt32LE(4), this.depth = n.readInt32LE(8), this.maxBinNumber = ((1 << (this.depth + 1) * 3) - 1) / 7;
|
579
|
-
const
|
580
|
-
let
|
581
|
-
const l = new Array(
|
582
|
-
for (let u = 0; u <
|
583
|
-
const
|
584
|
-
|
585
|
-
const
|
586
|
-
let
|
587
|
-
for (let
|
588
|
-
const
|
589
|
-
if (
|
590
|
-
|
580
|
+
const s = n.readInt32LE(12), a = s >= 30 ? this.parseAuxData(n, 16) : void 0, h = n.readInt32LE(16 + s);
|
581
|
+
let c = 16 + s + 4, i;
|
582
|
+
const l = new Array(h);
|
583
|
+
for (let u = 0; u < h; u++) {
|
584
|
+
const f = n.readInt32LE(c);
|
585
|
+
c += 4;
|
586
|
+
const d = {};
|
587
|
+
let _;
|
588
|
+
for (let g = 0; g < f; g++) {
|
589
|
+
const m = n.readUInt32LE(c);
|
590
|
+
if (c += 4, m > this.maxBinNumber)
|
591
|
+
_ = z(n, c + 28), c += 44;
|
591
592
|
else {
|
592
|
-
|
593
|
-
const
|
594
|
-
|
595
|
-
const
|
596
|
-
for (let
|
597
|
-
const
|
598
|
-
|
599
|
-
const S =
|
600
|
-
|
593
|
+
i = L(i, x(n, c)), c += 8;
|
594
|
+
const p = n.readInt32LE(c);
|
595
|
+
c += 4;
|
596
|
+
const w = new Array(p);
|
597
|
+
for (let E = 0; E < p; E += 1) {
|
598
|
+
const y = x(n, c);
|
599
|
+
c += 8;
|
600
|
+
const S = x(n, c);
|
601
|
+
c += 8, i = L(i, y), w[E] = new $(y, S, m);
|
601
602
|
}
|
602
|
-
|
603
|
+
d[m] = w;
|
603
604
|
}
|
604
605
|
}
|
605
|
-
l[u] = { binIndex:
|
606
|
+
l[u] = { binIndex: d, stats: _ };
|
606
607
|
}
|
607
608
|
return {
|
608
609
|
csiVersion: r,
|
609
|
-
firstDataLine:
|
610
|
+
firstDataLine: i,
|
610
611
|
indices: l,
|
611
|
-
refCount:
|
612
|
+
refCount: h,
|
612
613
|
csi: !0,
|
613
614
|
maxBlockSize: 65536,
|
614
|
-
...
|
615
|
+
...a
|
615
616
|
};
|
616
617
|
}
|
617
618
|
async blocksForRange(e, t, n, r = {}) {
|
618
619
|
t < 0 && (t = 0);
|
619
|
-
const
|
620
|
-
if (!
|
620
|
+
const s = await this.parse(r), a = s == null ? void 0 : s.indices[e];
|
621
|
+
if (!a)
|
621
622
|
return [];
|
622
|
-
const
|
623
|
-
if (
|
623
|
+
const h = this.reg2bins(t, n);
|
624
|
+
if (h.length === 0)
|
624
625
|
return [];
|
625
|
-
const
|
626
|
-
for (const [
|
627
|
-
for (let u =
|
628
|
-
if (
|
629
|
-
const
|
630
|
-
for (const
|
631
|
-
|
626
|
+
const c = [];
|
627
|
+
for (const [i, l] of h)
|
628
|
+
for (let u = i; u <= l; u++)
|
629
|
+
if (a.binIndex[u]) {
|
630
|
+
const f = a.binIndex[u];
|
631
|
+
for (const d of f)
|
632
|
+
c.push(d);
|
632
633
|
}
|
633
|
-
return
|
634
|
+
return U(c, new D(0, 0));
|
634
635
|
}
|
635
636
|
/**
|
636
637
|
* calculate the list of bins that may overlap with region [beg,end)
|
@@ -638,15 +639,15 @@ class T extends G {
|
|
638
639
|
*/
|
639
640
|
reg2bins(e, t) {
|
640
641
|
e -= 1, e < 1 && (e = 1), t > 2 ** 50 && (t = 2 ** 34), t -= 1;
|
641
|
-
let n = 0, r = 0,
|
642
|
-
const
|
643
|
-
for (; n <= this.depth;
|
644
|
-
const
|
645
|
-
if (
|
642
|
+
let n = 0, r = 0, s = this.minShift + this.depth * 3;
|
643
|
+
const a = [];
|
644
|
+
for (; n <= this.depth; s -= 3, r += ue(1, n * 3), n += 1) {
|
645
|
+
const h = r + B(e, s), c = r + B(t, s);
|
646
|
+
if (c - h + a.length > this.maxBinNumber)
|
646
647
|
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
|
-
|
648
|
+
a.push([h, c]);
|
648
649
|
}
|
649
|
-
return
|
650
|
+
return a;
|
650
651
|
}
|
651
652
|
async parse(e = {}) {
|
652
653
|
return this.setupP || (this.setupP = this._parse(e).catch((t) => {
|
@@ -658,7 +659,7 @@ class T extends G {
|
|
658
659
|
return !!(!((n = (await this.parse(t)).indices[e]) === null || n === void 0) && n.binIndex);
|
659
660
|
}
|
660
661
|
}
|
661
|
-
const
|
662
|
+
const b = {
|
662
663
|
// the read is paired in sequencing, no matter whether it is mapped in a pair
|
663
664
|
BAM_FPAIRED: 1,
|
664
665
|
// the read is mapped in a proper pair
|
@@ -683,12 +684,12 @@ const _ = {
|
|
683
684
|
BAM_FDUP: 1024,
|
684
685
|
// supplementary alignment
|
685
686
|
BAM_FSUPPLEMENTARY: 2048
|
686
|
-
},
|
687
|
-
class
|
687
|
+
}, F = "=ACMGRSVTWYHKDBN".split(""), C = "MIDNSHP=X???????".split("");
|
688
|
+
class me {
|
688
689
|
constructor(e) {
|
689
690
|
this.data = {}, this._tagList = [], this._allTagsParsed = !1;
|
690
|
-
const { bytes: t, fileOffset: n } = e, { byteArray: r, start:
|
691
|
-
this.data = {}, this.bytes = t, this._id = n, this._refID = r.readInt32LE(
|
691
|
+
const { bytes: t, fileOffset: n } = e, { byteArray: r, start: s } = t;
|
692
|
+
this.data = {}, this.bytes = t, this._id = n, this._refID = r.readInt32LE(s + 4), this.data.start = r.readInt32LE(s + 8), this.flags = (r.readInt32LE(s + 16) & 4294901760) >> 16;
|
692
693
|
}
|
693
694
|
get(e) {
|
694
695
|
return this[e] ? this.data[e] ? this.data[e] : (this.data[e] = this[e](), this.data[e]) : this._get(e.toLowerCase());
|
@@ -709,13 +710,13 @@ class be {
|
|
709
710
|
let e = ["seq"];
|
710
711
|
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
712
|
for (const n of Object.keys(this.data))
|
712
|
-
n
|
713
|
+
!n.startsWith("_") && n !== "next_seq_id" && e.push(n);
|
713
714
|
const t = {};
|
714
715
|
return e.filter((n) => {
|
715
716
|
if (n in this.data && this.data[n] === void 0 || n === "CG" || n === "cg")
|
716
717
|
return !1;
|
717
|
-
const r = n.toLowerCase(),
|
718
|
-
return t[r] = !0, !
|
718
|
+
const r = n.toLowerCase(), s = t[r];
|
719
|
+
return t[r] = !0, !s;
|
719
720
|
});
|
720
721
|
}
|
721
722
|
parent() {
|
@@ -770,101 +771,101 @@ class be {
|
|
770
771
|
return;
|
771
772
|
const { byteArray: t, start: n } = this.bytes;
|
772
773
|
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
|
774
|
-
let
|
775
|
-
for (; r <
|
776
|
-
const
|
777
|
-
|
778
|
-
const
|
774
|
+
const s = this.bytes.end;
|
775
|
+
let a;
|
776
|
+
for (; r < s && a !== e; ) {
|
777
|
+
const h = String.fromCharCode(t[r], t[r + 1]);
|
778
|
+
a = h.toLowerCase();
|
779
|
+
const c = String.fromCharCode(t[r + 2]);
|
779
780
|
r += 3;
|
780
|
-
let
|
781
|
-
switch (
|
781
|
+
let i;
|
782
|
+
switch (c) {
|
782
783
|
case "A": {
|
783
|
-
|
784
|
+
i = String.fromCharCode(t[r]), r += 1;
|
784
785
|
break;
|
785
786
|
}
|
786
787
|
case "i": {
|
787
|
-
|
788
|
+
i = t.readInt32LE(r), r += 4;
|
788
789
|
break;
|
789
790
|
}
|
790
791
|
case "I": {
|
791
|
-
|
792
|
+
i = t.readUInt32LE(r), r += 4;
|
792
793
|
break;
|
793
794
|
}
|
794
795
|
case "c": {
|
795
|
-
|
796
|
+
i = t.readInt8(r), r += 1;
|
796
797
|
break;
|
797
798
|
}
|
798
799
|
case "C": {
|
799
|
-
|
800
|
+
i = t.readUInt8(r), r += 1;
|
800
801
|
break;
|
801
802
|
}
|
802
803
|
case "s": {
|
803
|
-
|
804
|
+
i = t.readInt16LE(r), r += 2;
|
804
805
|
break;
|
805
806
|
}
|
806
807
|
case "S": {
|
807
|
-
|
808
|
+
i = t.readUInt16LE(r), r += 2;
|
808
809
|
break;
|
809
810
|
}
|
810
811
|
case "f": {
|
811
|
-
|
812
|
+
i = t.readFloatLE(r), r += 4;
|
812
813
|
break;
|
813
814
|
}
|
814
815
|
case "Z":
|
815
816
|
case "H": {
|
816
|
-
for (
|
817
|
+
for (i = ""; r <= s; ) {
|
817
818
|
const l = t[r++];
|
818
819
|
if (l === 0)
|
819
820
|
break;
|
820
|
-
|
821
|
+
i += String.fromCharCode(l);
|
821
822
|
}
|
822
823
|
break;
|
823
824
|
}
|
824
825
|
case "B": {
|
825
|
-
|
826
|
-
const l = t[r++], u = String.fromCharCode(l),
|
826
|
+
i = "";
|
827
|
+
const l = t[r++], u = String.fromCharCode(l), f = t.readInt32LE(r);
|
827
828
|
if (r += 4, u === "i")
|
828
|
-
if (
|
829
|
-
for (let
|
830
|
-
const
|
831
|
-
|
829
|
+
if (h === "CG")
|
830
|
+
for (let d = 0; d < f; d++) {
|
831
|
+
const _ = t.readInt32LE(r), g = _ >> 4, m = C[_ & 15];
|
832
|
+
i += g + m, r += 4;
|
832
833
|
}
|
833
834
|
else
|
834
|
-
for (let
|
835
|
-
|
835
|
+
for (let d = 0; d < f; d++)
|
836
|
+
i += t.readInt32LE(r), d + 1 < f && (i += ","), r += 4;
|
836
837
|
if (u === "I")
|
837
|
-
if (
|
838
|
-
for (let
|
839
|
-
const
|
840
|
-
|
838
|
+
if (h === "CG")
|
839
|
+
for (let d = 0; d < f; d++) {
|
840
|
+
const _ = t.readUInt32LE(r), g = _ >> 4, m = C[_ & 15];
|
841
|
+
i += g + m, r += 4;
|
841
842
|
}
|
842
843
|
else
|
843
|
-
for (let
|
844
|
-
|
844
|
+
for (let d = 0; d < f; d++)
|
845
|
+
i += t.readUInt32LE(r), d + 1 < f && (i += ","), r += 4;
|
845
846
|
if (u === "s")
|
846
|
-
for (let
|
847
|
-
|
847
|
+
for (let d = 0; d < f; d++)
|
848
|
+
i += t.readInt16LE(r), d + 1 < f && (i += ","), r += 2;
|
848
849
|
if (u === "S")
|
849
|
-
for (let
|
850
|
-
|
850
|
+
for (let d = 0; d < f; d++)
|
851
|
+
i += t.readUInt16LE(r), d + 1 < f && (i += ","), r += 2;
|
851
852
|
if (u === "c")
|
852
|
-
for (let
|
853
|
-
|
853
|
+
for (let d = 0; d < f; d++)
|
854
|
+
i += t.readInt8(r), d + 1 < f && (i += ","), r += 1;
|
854
855
|
if (u === "C")
|
855
|
-
for (let
|
856
|
-
|
856
|
+
for (let d = 0; d < f; d++)
|
857
|
+
i += t.readUInt8(r), d + 1 < f && (i += ","), r += 1;
|
857
858
|
if (u === "f")
|
858
|
-
for (let
|
859
|
-
|
859
|
+
for (let d = 0; d < f; d++)
|
860
|
+
i += t.readFloatLE(r), d + 1 < f && (i += ","), r += 4;
|
860
861
|
break;
|
861
862
|
}
|
862
863
|
default:
|
863
|
-
console.warn(`Unknown BAM tag type '${
|
864
|
+
console.warn(`Unknown BAM tag type '${c}', tags may be incomplete`), i = void 0, r = s;
|
864
865
|
}
|
865
|
-
if (this._tagOffset = r, this._tagList.push(
|
866
|
-
return
|
867
|
-
this.data[
|
866
|
+
if (this._tagOffset = r, this._tagList.push(h), a === e)
|
867
|
+
return i;
|
868
|
+
this.data[a] = i;
|
868
869
|
}
|
869
870
|
this._allTagsParsed = !0;
|
870
871
|
}
|
@@ -881,66 +882,64 @@ class be {
|
|
881
882
|
* @returns {boolean} true if the read is paired, regardless of whether both segments are mapped
|
882
883
|
*/
|
883
884
|
isPaired() {
|
884
|
-
return !!(this.flags &
|
885
|
+
return !!(this.flags & b.BAM_FPAIRED);
|
885
886
|
}
|
886
887
|
/** @returns {boolean} true if the read is paired, and both segments are mapped */
|
887
888
|
isProperlyPaired() {
|
888
|
-
return !!(this.flags &
|
889
|
+
return !!(this.flags & b.BAM_FPROPER_PAIR);
|
889
890
|
}
|
890
891
|
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
891
892
|
isSegmentUnmapped() {
|
892
|
-
return !!(this.flags &
|
893
|
+
return !!(this.flags & b.BAM_FUNMAP);
|
893
894
|
}
|
894
895
|
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
895
896
|
isMateUnmapped() {
|
896
|
-
return !!(this.flags &
|
897
|
+
return !!(this.flags & b.BAM_FMUNMAP);
|
897
898
|
}
|
898
899
|
/** @returns {boolean} true if the read is mapped to the reverse strand */
|
899
900
|
isReverseComplemented() {
|
900
|
-
return !!(this.flags &
|
901
|
+
return !!(this.flags & b.BAM_FREVERSE);
|
901
902
|
}
|
902
903
|
/** @returns {boolean} true if the mate is mapped to the reverse strand */
|
903
904
|
isMateReverseComplemented() {
|
904
|
-
return !!(this.flags &
|
905
|
+
return !!(this.flags & b.BAM_FMREVERSE);
|
905
906
|
}
|
906
907
|
/** @returns {boolean} true if this is read number 1 in a pair */
|
907
908
|
isRead1() {
|
908
|
-
return !!(this.flags &
|
909
|
+
return !!(this.flags & b.BAM_FREAD1);
|
909
910
|
}
|
910
911
|
/** @returns {boolean} true if this is read number 2 in a pair */
|
911
912
|
isRead2() {
|
912
|
-
return !!(this.flags &
|
913
|
+
return !!(this.flags & b.BAM_FREAD2);
|
913
914
|
}
|
914
915
|
/** @returns {boolean} true if this is a secondary alignment */
|
915
916
|
isSecondary() {
|
916
|
-
return !!(this.flags &
|
917
|
+
return !!(this.flags & b.BAM_FSECONDARY);
|
917
918
|
}
|
918
919
|
/** @returns {boolean} true if this read has failed QC checks */
|
919
920
|
isFailedQc() {
|
920
|
-
return !!(this.flags &
|
921
|
+
return !!(this.flags & b.BAM_FQCFAIL);
|
921
922
|
}
|
922
923
|
/** @returns {boolean} true if the read is an optical or PCR duplicate */
|
923
924
|
isDuplicate() {
|
924
|
-
return !!(this.flags &
|
925
|
+
return !!(this.flags & b.BAM_FDUP);
|
925
926
|
}
|
926
927
|
/** @returns {boolean} true if this is a supplementary alignment */
|
927
928
|
isSupplementary() {
|
928
|
-
return !!(this.flags &
|
929
|
+
return !!(this.flags & b.BAM_FSUPPLEMENTARY);
|
929
930
|
}
|
930
931
|
cigar() {
|
931
932
|
if (this.isSegmentUnmapped())
|
932
933
|
return;
|
933
934
|
const { byteArray: e, start: t } = this.bytes, n = this.get("_n_cigar_op");
|
934
935
|
let r = t + 36 + this.get("_l_read_name");
|
935
|
-
const
|
936
|
-
let
|
937
|
-
if (l === "S" &&
|
938
|
-
return r += 4,
|
936
|
+
const s = this.get("seq_length");
|
937
|
+
let a = "", h = 0, c = e.readInt32LE(r), i = c >> 4, l = C[c & 15];
|
938
|
+
if (l === "S" && i === s)
|
939
|
+
return r += 4, c = e.readInt32LE(r), i = c >> 4, l = C[c & 15], l !== "N" && console.warn("CG tag with no N tag"), this.data.length_on_ref = i, this.get("CG");
|
939
940
|
for (let u = 0; u < n; ++u)
|
940
|
-
|
941
|
-
return this.data.length_on_ref =
|
942
|
-
}
|
943
|
-
_flags() {
|
941
|
+
c = e.readInt32LE(r), i = c >> 4, l = C[c & 15], a += i + l, l !== "H" && l !== "S" && l !== "I" && (h += i), r += 4;
|
942
|
+
return this.data.length_on_ref = h, a;
|
944
943
|
}
|
945
944
|
length_on_ref() {
|
946
945
|
return this.data.length_on_ref ? this.data.length_on_ref : (this.get("cigar"), this.data.length_on_ref);
|
@@ -961,13 +960,13 @@ class be {
|
|
961
960
|
return this.seq();
|
962
961
|
}
|
963
962
|
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"),
|
965
|
-
let
|
966
|
-
for (let
|
967
|
-
const
|
968
|
-
|
963
|
+
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"), s = this.get("seq_length");
|
964
|
+
let a = "", h = 0;
|
965
|
+
for (let c = 0; c < r; ++c) {
|
966
|
+
const i = e[n + c];
|
967
|
+
a += F[(i & 240) >> 4], h++, h < s && (a += F[i & 15], h++);
|
969
968
|
}
|
970
|
-
return
|
969
|
+
return a;
|
971
970
|
}
|
972
971
|
// adapted from igv.js
|
973
972
|
getPairOrientation() {
|
@@ -975,8 +974,8 @@ class be {
|
|
975
974
|
const e = this.isReverseComplemented() ? "R" : "F", t = this.isMateReverseComplemented() ? "R" : "F";
|
976
975
|
let n = " ", r = " ";
|
977
976
|
this.isRead1() ? (n = "1", r = "2") : this.isRead2() && (n = "2", r = "1");
|
978
|
-
const
|
979
|
-
return this.template_length() > 0 ? (
|
977
|
+
const s = [];
|
978
|
+
return this.template_length() > 0 ? (s[0] = e, s[1] = n, s[2] = t, s[3] = r) : (s[2] = e, s[3] = n, s[0] = t, s[1] = r), s.join("");
|
980
979
|
}
|
981
980
|
return "";
|
982
981
|
}
|
@@ -1001,32 +1000,32 @@ class be {
|
|
1001
1000
|
toJSON() {
|
1002
1001
|
const e = {};
|
1003
1002
|
for (const t of Object.keys(this))
|
1004
|
-
t.
|
1003
|
+
t.startsWith("_") || t === "bytes" || (e[t] = this[t]);
|
1005
1004
|
return e;
|
1006
1005
|
}
|
1007
1006
|
}
|
1008
|
-
function
|
1007
|
+
function G(o) {
|
1009
1008
|
const e = o.split(/\r?\n/), t = [];
|
1010
1009
|
for (const n of e) {
|
1011
|
-
const [r, ...
|
1010
|
+
const [r, ...s] = n.split(/\t/);
|
1012
1011
|
r && t.push({
|
1013
1012
|
tag: r.slice(1),
|
1014
|
-
data:
|
1015
|
-
const
|
1016
|
-
return { tag: c, value:
|
1013
|
+
data: s.map((a) => {
|
1014
|
+
const h = a.indexOf(":"), c = a.slice(0, h), i = a.slice(h + 1);
|
1015
|
+
return { tag: c, value: i };
|
1017
1016
|
})
|
1018
1017
|
});
|
1019
1018
|
}
|
1020
1019
|
return t;
|
1021
1020
|
}
|
1022
|
-
const
|
1023
|
-
async function
|
1021
|
+
const j = 21840194, q = 65536;
|
1022
|
+
async function ge(o) {
|
1024
1023
|
let e = [];
|
1025
1024
|
for await (const t of o)
|
1026
1025
|
e = e.concat(t);
|
1027
1026
|
return e;
|
1028
1027
|
}
|
1029
|
-
class
|
1028
|
+
class _e {
|
1030
1029
|
read() {
|
1031
1030
|
throw new Error("never called");
|
1032
1031
|
}
|
@@ -1040,45 +1039,45 @@ class ge {
|
|
1040
1039
|
throw new Error("never called");
|
1041
1040
|
}
|
1042
1041
|
}
|
1043
|
-
class
|
1044
|
-
constructor({ bamFilehandle: e, bamPath: t, bamUrl: n, baiPath: r, baiFilehandle:
|
1045
|
-
if (this.htsget = !1, this.featureCache = new
|
1046
|
-
cache: new
|
1042
|
+
class pe {
|
1043
|
+
constructor({ bamFilehandle: e, bamPath: t, bamUrl: n, baiPath: r, baiFilehandle: s, baiUrl: a, csiPath: h, csiFilehandle: c, csiUrl: i, htsget: l, yieldThreadTime: u = 100, renameRefSeqs: f = (d) => d }) {
|
1044
|
+
if (this.htsget = !1, this.featureCache = new Y({
|
1045
|
+
cache: new W({
|
1047
1046
|
maxSize: 50
|
1048
1047
|
}),
|
1049
|
-
fill: async (
|
1050
|
-
const { chunk:
|
1051
|
-
chunk:
|
1052
|
-
opts: { ...
|
1048
|
+
fill: async (d, _) => {
|
1049
|
+
const { chunk: g, opts: m } = d, { data: p, cpositions: w, dpositions: E } = await this._readChunk({
|
1050
|
+
chunk: g,
|
1051
|
+
opts: { ...m, signal: _ }
|
1053
1052
|
});
|
1054
|
-
return this.readBamFeatures(
|
1053
|
+
return this.readBamFeatures(p, w, E, g);
|
1055
1054
|
}
|
1056
|
-
}), this.renameRefSeq =
|
1055
|
+
}), this.renameRefSeq = f, e)
|
1057
1056
|
this.bam = e;
|
1058
1057
|
else if (t)
|
1059
|
-
this.bam = new
|
1058
|
+
this.bam = new A(t);
|
1060
1059
|
else if (n)
|
1061
|
-
this.bam = new
|
1060
|
+
this.bam = new R(n);
|
1062
1061
|
else if (l)
|
1063
|
-
this.htsget = !0, this.bam = new
|
1062
|
+
this.htsget = !0, this.bam = new _e();
|
1064
1063
|
else
|
1065
1064
|
throw new Error("unable to initialize bam");
|
1066
|
-
if (
|
1067
|
-
this.index = new
|
1068
|
-
else if (
|
1069
|
-
this.index = new
|
1065
|
+
if (c)
|
1066
|
+
this.index = new P({ filehandle: c });
|
1067
|
+
else if (h)
|
1068
|
+
this.index = new P({ filehandle: new A(h) });
|
1069
|
+
else if (i)
|
1070
|
+
this.index = new P({ filehandle: new R(i) });
|
1070
1071
|
else if (s)
|
1071
|
-
this.index = new
|
1072
|
-
else if (a)
|
1073
|
-
this.index = new A({ filehandle: a });
|
1072
|
+
this.index = new v({ filehandle: s });
|
1074
1073
|
else if (r)
|
1075
|
-
this.index = new
|
1076
|
-
else if (
|
1077
|
-
this.index = new
|
1074
|
+
this.index = new v({ filehandle: new A(r) });
|
1075
|
+
else if (a)
|
1076
|
+
this.index = new v({ filehandle: new R(a) });
|
1078
1077
|
else if (t)
|
1079
|
-
this.index = new
|
1078
|
+
this.index = new v({ filehandle: new A(`${t}.bai`) });
|
1080
1079
|
else if (n)
|
1081
|
-
this.index = new
|
1080
|
+
this.index = new v({ filehandle: new R(`${n}.bai`) });
|
1082
1081
|
else if (l)
|
1083
1082
|
this.htsget = !0;
|
1084
1083
|
else
|
@@ -1086,25 +1085,25 @@ class _e {
|
|
1086
1085
|
this.yieldThreadTime = u;
|
1087
1086
|
}
|
1088
1087
|
async getHeaderPre(e) {
|
1089
|
-
const t =
|
1088
|
+
const t = ee(e);
|
1090
1089
|
if (!this.index)
|
1091
1090
|
return;
|
1092
1091
|
const n = await this.index.parse(t), r = n.firstDataLine ? n.firstDataLine.blockPosition + 65535 : void 0;
|
1093
|
-
let
|
1092
|
+
let s;
|
1094
1093
|
if (r) {
|
1095
|
-
const l = r +
|
1094
|
+
const l = r + q, u = await this.bam.read(I.Buffer.alloc(l), 0, l, 0, t);
|
1096
1095
|
if (!u.bytesRead)
|
1097
1096
|
throw new Error("Error reading header");
|
1098
|
-
|
1097
|
+
s = u.buffer.subarray(0, Math.min(u.bytesRead, r));
|
1099
1098
|
} else
|
1100
|
-
|
1101
|
-
const
|
1102
|
-
if (
|
1099
|
+
s = await this.bam.readFile(t);
|
1100
|
+
const a = await k(s);
|
1101
|
+
if (a.readInt32LE(0) !== j)
|
1103
1102
|
throw new Error("Not a BAM file");
|
1104
|
-
const
|
1105
|
-
this.header =
|
1106
|
-
const { chrToIndex:
|
1107
|
-
return this.chrToIndex =
|
1103
|
+
const h = a.readInt32LE(4);
|
1104
|
+
this.header = a.toString("utf8", 8, 8 + h);
|
1105
|
+
const { chrToIndex: c, indexToChr: i } = await this._readRefSeqs(h + 8, 65535, t);
|
1106
|
+
return this.chrToIndex = c, this.indexToChr = i, G(this.header);
|
1108
1107
|
}
|
1109
1108
|
getHeader(e) {
|
1110
1109
|
return this.headerP || (this.headerP = this.getHeaderPre(e).catch((t) => {
|
@@ -1119,105 +1118,105 @@ class _e {
|
|
1119
1118
|
async _readRefSeqs(e, t, n) {
|
1120
1119
|
if (e > t)
|
1121
1120
|
return this._readRefSeqs(e, t * 2, n);
|
1122
|
-
const r = t +
|
1123
|
-
if (!
|
1121
|
+
const r = t + q, { bytesRead: s, buffer: a } = await this.bam.read(I.Buffer.alloc(r), 0, t, 0, n);
|
1122
|
+
if (!s)
|
1124
1123
|
throw new Error("Error reading refseqs from header");
|
1125
|
-
const
|
1126
|
-
let
|
1124
|
+
const h = await k(a.subarray(0, Math.min(s, t))), c = h.readInt32LE(e);
|
1125
|
+
let i = e + 4;
|
1127
1126
|
const l = {}, u = [];
|
1128
|
-
for (let
|
1129
|
-
const
|
1130
|
-
if (l[
|
1127
|
+
for (let f = 0; f < c; f += 1) {
|
1128
|
+
const d = h.readInt32LE(i), _ = this.renameRefSeq(h.toString("utf8", i + 4, i + 4 + d - 1)), g = h.readInt32LE(i + d + 4);
|
1129
|
+
if (l[_] = f, u.push({ refName: _, length: g }), i = i + 8 + d, i > h.length)
|
1131
1130
|
return console.warn(`BAM header is very big. Re-fetching ${t} bytes.`), this._readRefSeqs(e, t * 2, n);
|
1132
1131
|
}
|
1133
1132
|
return { chrToIndex: l, indexToChr: u };
|
1134
1133
|
}
|
1135
1134
|
async getRecordsForRange(e, t, n, r) {
|
1136
|
-
return
|
1135
|
+
return ge(this.streamRecordsForRange(e, t, n, r));
|
1137
1136
|
}
|
1138
1137
|
async *streamRecordsForRange(e, t, n, r) {
|
1139
|
-
var
|
1138
|
+
var s;
|
1140
1139
|
await this.getHeader(r);
|
1141
|
-
const
|
1142
|
-
if (
|
1140
|
+
const a = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1141
|
+
if (a === void 0 || !this.index)
|
1143
1142
|
yield [];
|
1144
1143
|
else {
|
1145
|
-
const
|
1146
|
-
yield* this._fetchChunkFeatures(
|
1144
|
+
const h = await this.index.blocksForRange(a, t - 1, n, r);
|
1145
|
+
yield* this._fetchChunkFeatures(h, a, t, n, r);
|
1147
1146
|
}
|
1148
1147
|
}
|
1149
|
-
async *_fetchChunkFeatures(e, t, n, r,
|
1150
|
-
const { viewAsPairs:
|
1151
|
-
let
|
1152
|
-
for (const
|
1153
|
-
const l = await this.featureCache.get(
|
1154
|
-
for (const
|
1155
|
-
if (
|
1156
|
-
if (
|
1157
|
-
|
1148
|
+
async *_fetchChunkFeatures(e, t, n, r, s = {}) {
|
1149
|
+
const { viewAsPairs: a } = s, h = [];
|
1150
|
+
let c = !1;
|
1151
|
+
for (const i of e) {
|
1152
|
+
const l = await this.featureCache.get(i.toString(), { chunk: i, opts: s }, s.signal), u = [];
|
1153
|
+
for (const f of l)
|
1154
|
+
if (f.seq_id() === t)
|
1155
|
+
if (f.get("start") >= r) {
|
1156
|
+
c = !0;
|
1158
1157
|
break;
|
1159
1158
|
} else
|
1160
|
-
|
1161
|
-
if (
|
1159
|
+
f.get("end") >= n && u.push(f);
|
1160
|
+
if (h.push(u), yield u, c)
|
1162
1161
|
break;
|
1163
1162
|
}
|
1164
|
-
|
1163
|
+
K(s.signal), a && (yield this.fetchPairs(t, h, s));
|
1165
1164
|
}
|
1166
1165
|
async fetchPairs(e, t, n) {
|
1167
|
-
const { pairAcrossChr: r, maxInsertSize:
|
1168
|
-
t.map((
|
1169
|
-
const
|
1170
|
-
for (const
|
1171
|
-
const
|
1172
|
-
|
1166
|
+
const { pairAcrossChr: r, maxInsertSize: s = 2e5 } = n, a = {}, h = {};
|
1167
|
+
t.map((f) => {
|
1168
|
+
const d = {};
|
1169
|
+
for (const _ of f) {
|
1170
|
+
const g = _.name(), m = _.id();
|
1171
|
+
d[g] || (d[g] = 0), d[g]++, h[m] = 1;
|
1173
1172
|
}
|
1174
|
-
for (const [
|
1175
|
-
|
1173
|
+
for (const [_, g] of Object.entries(d))
|
1174
|
+
g === 1 && (a[_] = !0);
|
1176
1175
|
});
|
1177
|
-
const
|
1178
|
-
t.map((
|
1179
|
-
for (const
|
1180
|
-
const
|
1181
|
-
this.index &&
|
1176
|
+
const c = [];
|
1177
|
+
t.map((f) => {
|
1178
|
+
for (const d of f) {
|
1179
|
+
const _ = d.name(), g = d.get("start"), m = d._next_pos(), p = d._next_refid();
|
1180
|
+
this.index && a[_] && (r || p === e && Math.abs(g - m) < s) && c.push(this.index.blocksForRange(p, m, m + 1, n));
|
1182
1181
|
}
|
1183
1182
|
});
|
1184
|
-
const
|
1185
|
-
for (const
|
1186
|
-
|
1187
|
-
return (await Promise.all([...
|
1188
|
-
const { data:
|
1189
|
-
chunk:
|
1183
|
+
const i = /* @__PURE__ */ new Map(), l = await Promise.all(c);
|
1184
|
+
for (const f of l.flat())
|
1185
|
+
i.has(f.toString()) || i.set(f.toString(), f);
|
1186
|
+
return (await Promise.all([...i.values()].map(async (f) => {
|
1187
|
+
const { data: d, cpositions: _, dpositions: g, chunk: m } = await this._readChunk({
|
1188
|
+
chunk: f,
|
1190
1189
|
opts: n
|
1191
|
-
}),
|
1192
|
-
for (const
|
1193
|
-
|
1194
|
-
return
|
1190
|
+
}), p = [];
|
1191
|
+
for (const w of await this.readBamFeatures(d, _, g, m))
|
1192
|
+
a[w.get("name")] && !h[w.id()] && p.push(w);
|
1193
|
+
return p;
|
1195
1194
|
}))).flat();
|
1196
1195
|
}
|
1197
1196
|
async _readRegion(e, t, n = {}) {
|
1198
|
-
const { bytesRead: r, buffer:
|
1199
|
-
return
|
1197
|
+
const { bytesRead: r, buffer: s } = await this.bam.read(I.Buffer.alloc(t), 0, t, e, n);
|
1198
|
+
return s.subarray(0, Math.min(r, t));
|
1200
1199
|
}
|
1201
1200
|
async _readChunk({ chunk: e, opts: t }) {
|
1202
|
-
const n = await this._readRegion(e.minv.blockPosition, e.fetchedSize(), t), { buffer: r, cpositions:
|
1203
|
-
return { data: r, cpositions:
|
1201
|
+
const n = await this._readRegion(e.minv.blockPosition, e.fetchedSize(), t), { buffer: r, cpositions: s, dpositions: a } = await Q(n, e);
|
1202
|
+
return { data: r, cpositions: s, dpositions: a, chunk: e };
|
1204
1203
|
}
|
1205
1204
|
async readBamFeatures(e, t, n, r) {
|
1206
|
-
let
|
1207
|
-
const
|
1208
|
-
let
|
1209
|
-
for (;
|
1210
|
-
const
|
1205
|
+
let s = 0;
|
1206
|
+
const a = [];
|
1207
|
+
let h = 0, c = +Date.now();
|
1208
|
+
for (; s + 4 < e.length; ) {
|
1209
|
+
const i = e.readInt32LE(s), l = s + 4 + i - 1;
|
1211
1210
|
if (n) {
|
1212
|
-
for (;
|
1211
|
+
for (; s + r.minv.dataPosition >= n[h++]; )
|
1213
1212
|
;
|
1214
|
-
|
1213
|
+
h--;
|
1215
1214
|
}
|
1216
1215
|
if (l < e.length) {
|
1217
|
-
const u = new
|
1216
|
+
const u = new me({
|
1218
1217
|
bytes: {
|
1219
1218
|
byteArray: e,
|
1220
|
-
start:
|
1219
|
+
start: s,
|
1221
1220
|
end: l
|
1222
1221
|
},
|
1223
1222
|
// the below results in an automatically calculated file-offset based
|
@@ -1240,16 +1239,16 @@ class _e {
|
|
1240
1239
|
//
|
1241
1240
|
// the +1 is just to avoid any possible uniqueId 0 but this does not
|
1242
1241
|
// realistically happen
|
1243
|
-
fileOffset: t.length > 0 ? t[
|
1242
|
+
fileOffset: t.length > 0 ? t[h] * 256 + (s - n[h]) + r.minv.dataPosition + 1 : (
|
1244
1243
|
// must be slice, not subarray for buffer polyfill on web
|
1245
|
-
|
1244
|
+
de.signed(e.slice(s, l))
|
1246
1245
|
)
|
1247
1246
|
});
|
1248
|
-
|
1247
|
+
a.push(u), this.yieldThreadTime && +Date.now() - c > this.yieldThreadTime && (await X(1), c = +Date.now());
|
1249
1248
|
}
|
1250
|
-
|
1249
|
+
s = l + 1;
|
1251
1250
|
}
|
1252
|
-
return
|
1251
|
+
return a;
|
1253
1252
|
}
|
1254
1253
|
async hasRefSeq(e) {
|
1255
1254
|
var t, n;
|
@@ -1266,49 +1265,49 @@ class _e {
|
|
1266
1265
|
if (!this.index)
|
1267
1266
|
return [];
|
1268
1267
|
await this.index.parse();
|
1269
|
-
const
|
1270
|
-
return
|
1268
|
+
const s = (r = this.chrToIndex) === null || r === void 0 ? void 0 : r[e];
|
1269
|
+
return s === void 0 ? [] : this.index.indexCov(s, t, n);
|
1271
1270
|
}
|
1272
1271
|
async blocksForRange(e, t, n, r) {
|
1273
|
-
var
|
1272
|
+
var s;
|
1274
1273
|
if (!this.index)
|
1275
1274
|
return [];
|
1276
1275
|
await this.index.parse();
|
1277
|
-
const
|
1278
|
-
return
|
1276
|
+
const a = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1277
|
+
return a === void 0 ? [] : this.index.blocksForRange(a, t, n, r);
|
1279
1278
|
}
|
1280
1279
|
}
|
1281
|
-
async function
|
1280
|
+
async function N(o, e) {
|
1282
1281
|
const t = await Promise.all(o.map(async (n) => {
|
1283
|
-
const { url: r, headers:
|
1282
|
+
const { url: r, headers: s } = n;
|
1284
1283
|
if (r.startsWith("data:"))
|
1285
|
-
return
|
1284
|
+
return I.Buffer.from(r.split(",")[1], "base64");
|
1286
1285
|
{
|
1287
|
-
const { referer:
|
1286
|
+
const { referer: a, ...h } = s, c = await fetch(r, {
|
1288
1287
|
...e,
|
1289
|
-
headers: { ...e == null ? void 0 : e.headers, ...
|
1288
|
+
headers: { ...e == null ? void 0 : e.headers, ...h }
|
1290
1289
|
});
|
1291
|
-
if (!
|
1292
|
-
throw new Error(`HTTP ${
|
1293
|
-
return
|
1290
|
+
if (!c.ok)
|
1291
|
+
throw new Error(`HTTP ${c.status} fetching ${r}: ${await c.text()}`);
|
1292
|
+
return I.Buffer.from(await c.arrayBuffer());
|
1294
1293
|
}
|
1295
1294
|
}));
|
1296
|
-
return
|
1295
|
+
return I.Buffer.concat(await Promise.all(t.map((n) => k(n))));
|
1297
1296
|
}
|
1298
|
-
class
|
1297
|
+
class ye extends pe {
|
1299
1298
|
constructor(e) {
|
1300
1299
|
super({ htsget: !0 }), this.baseUrl = e.baseUrl, this.trackId = e.trackId;
|
1301
1300
|
}
|
1302
1301
|
async *streamRecordsForRange(e, t, n, r) {
|
1303
|
-
var
|
1304
|
-
const
|
1305
|
-
if (
|
1302
|
+
var s;
|
1303
|
+
const h = `${`${this.baseUrl}/${this.trackId}`}?referenceName=${e}&start=${t}&end=${n}&format=BAM`, c = (s = this.chrToIndex) === null || s === void 0 ? void 0 : s[e];
|
1304
|
+
if (c === void 0)
|
1306
1305
|
yield [];
|
1307
1306
|
else {
|
1308
|
-
const
|
1309
|
-
if (!
|
1310
|
-
throw new Error(`HTTP ${
|
1311
|
-
const l = await
|
1307
|
+
const i = await fetch(h, { ...r });
|
1308
|
+
if (!i.ok)
|
1309
|
+
throw new Error(`HTTP ${i.status} fetching ${h}: ${await i.text()}`);
|
1310
|
+
const l = await i.json(), u = await N(l.htsget.urls.slice(1), r);
|
1312
1311
|
yield* this._fetchChunkFeatures([
|
1313
1312
|
// fake stuff to pretend to be a Chunk
|
1314
1313
|
{
|
@@ -1338,7 +1337,7 @@ class Ae extends _e {
|
|
1338
1337
|
return `${e}_${t}_${n}`;
|
1339
1338
|
}
|
1340
1339
|
}
|
1341
|
-
],
|
1340
|
+
], c, t, n, r);
|
1342
1341
|
}
|
1343
1342
|
}
|
1344
1343
|
async _readChunk({ chunk: e }) {
|
@@ -1350,23 +1349,23 @@ class Ae extends _e {
|
|
1350
1349
|
const t = `${this.baseUrl}/${this.trackId}?referenceName=na&class=header`, n = await fetch(t, e);
|
1351
1350
|
if (!n.ok)
|
1352
1351
|
throw new Error(`HTTP ${n.status} fetching ${t}: ${await n.text()}`);
|
1353
|
-
const r = await n.json(),
|
1354
|
-
if (
|
1352
|
+
const r = await n.json(), s = await N(r.htsget.urls, e);
|
1353
|
+
if (s.readInt32LE(0) !== j)
|
1355
1354
|
throw new Error("Not a BAM file");
|
1356
|
-
const
|
1357
|
-
for (const [
|
1358
|
-
let
|
1359
|
-
for (const
|
1360
|
-
|
1361
|
-
l[
|
1355
|
+
const a = s.readInt32LE(4), h = s.toString("utf8", 8, 8 + a), c = G(h), i = [], l = {}, u = c.filter((f) => f.tag === "SQ");
|
1356
|
+
for (const [f, d] of u.entries()) {
|
1357
|
+
let _ = "", g = 0;
|
1358
|
+
for (const m of d.data)
|
1359
|
+
m.tag === "SN" ? _ = m.value : m.tag === "LN" && (g = +m.value);
|
1360
|
+
l[_] = f, i[f] = { refName: _, length: g };
|
1362
1361
|
}
|
1363
|
-
return this.chrToIndex = l, this.indexToChr =
|
1362
|
+
return this.chrToIndex = l, this.indexToChr = i, c;
|
1364
1363
|
}
|
1365
1364
|
}
|
1366
1365
|
export {
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1366
|
+
v as BAI,
|
1367
|
+
pe as BamFile,
|
1368
|
+
me as BamRecord,
|
1369
|
+
P as CSI,
|
1370
|
+
ye as HtsgetFile
|
1372
1371
|
};
|