UNPKG

taxonium-component

Version:

React component for exploring large phylogenetic trees in the browser

260 lines (259 loc) 9.37 kB
function m(c) { return c.replaceAll(/%([0-9A-Fa-f]{2})/g, (e, r) => String.fromCharCode(parseInt(r, 16))); } function y(c) { if (!c.length || c === ".") return {}; const e = {}; return c.replace(/\r?\n$/, "").split(";").forEach((r) => { var t; const i = r.split("=", 2); if (!(!((t = i[1]) === null || t === void 0) && t.length)) return; i[0] = i[0].trim(); let n = e[i[0].trim()]; n || (n = [], e[i[0]] = n), n.push(...i[1].split(",").map((a) => a.trim()).map(m)); }), e; } function F(c) { const e = c.split(" ").map((t) => t === "." || t === "" ? null : t); return { seq_id: e[0] && m(e[0]), source: e[1] && m(e[1]), type: e[2] && m(e[2]), start: e[3] === null ? null : parseInt(e[3], 10), end: e[4] === null ? null : parseInt(e[4], 10), score: e[5] === null ? null : parseFloat(e[5]), strand: e[6], phase: e[7], attributes: e[8] === null ? null : y(e[8]) }; } function D(c) { var e, r; const t = /^\s*##\s*(\S+)\s*(.*)/.exec(c); if (!t) return null; const [, i] = t; let [, , n] = t; const a = { directive: i }; if (n.length && (n = n.replace(/\r?\n$/, ""), a.value = n), i === "sequence-region") { const s = n.split(/\s+/, 3); return { ...a, seq_id: s[0], start: (e = s[1]) === null || e === void 0 ? void 0 : e.replaceAll(/\D/g, ""), end: (r = s[2]) === null || r === void 0 ? void 0 : r.replaceAll(/\D/g, "") }; } else if (i === "genome-build") { const [s, o] = n.split(/\s+/, 2); return { ...a, source: s, buildName: o }; } return a; } const C = { Parent: "child_features", Derives_from: "derived_features" }; class A { constructor(e) { this.seqCallback = e, this.currentSequence = void 0; } addLine(e) { const r = /^>\s*(\S+)\s*(.*)/.exec(e); r ? (this._flush(), this.currentSequence = { id: r[1], sequence: "" }, r[2] && (this.currentSequence.description = r[2].trim())) : this.currentSequence && /\S/.test(e) && (this.currentSequence.sequence += e.replaceAll(/\s/g, "")); } _flush() { this.currentSequence && this.seqCallback(this.currentSequence); } finish() { this._flush(); } } class S { constructor(e) { this.fastaParser = void 0, this.eof = !1, this.lineNumber = 0, this._underConstructionTopLevel = [], this._underConstructionById = {}, this._completedReferences = {}, this._underConstructionOrphans = {}; const r = () => { }; this.featureCallback = e.featureCallback || r, this.endCallback = e.endCallback || r, this.commentCallback = e.commentCallback || r, this.errorCallback = e.errorCallback || r, this.directiveCallback = e.directiveCallback || r, this.sequenceCallback = e.sequenceCallback || r, this.disableDerivesFromReferences = e.disableDerivesFromReferences || !1, this.bufferSize = e.bufferSize === void 0 ? 1e3 : e.bufferSize; } addLine(e) { if (this.fastaParser) { this.fastaParser.addLine(e); return; } if (this.eof) return; if (this.lineNumber += 1, /^\s*[^#\s>]/.test(e)) { this._bufferLine(e); return; } const r = /^\s*(#+)(.*)/.exec(e); if (r) { const [, t] = r; let [, , i] = r; if (t.length === 3) this._emitAllUnderConstructionFeatures(); else if (t.length === 2) { const n = D(e); n && (n.directive === "FASTA" ? (this._emitAllUnderConstructionFeatures(), this.eof = !0, this.fastaParser = new A(this.sequenceCallback)) : this._emitItem(n)); } else i = i.replace(/\s*/, ""), this._emitItem({ comment: i }); } else if (!/^\s*$/.test(e)) if (/^\s*>/.test(e)) this._emitAllUnderConstructionFeatures(), this.eof = !0, this.fastaParser = new A(this.sequenceCallback), this.fastaParser.addLine(e); else { const t = e.replaceAll(/\r?\n?$/g, ""); throw new Error(`GFF3 parse error. Cannot parse '${t}'.`); } } finish() { this._emitAllUnderConstructionFeatures(), this.fastaParser && this.fastaParser.finish(), this.endCallback(); } _emitItem(e) { Array.isArray(e) ? this.featureCallback(e) : "directive" in e ? this.directiveCallback(e) : "comment" in e && this.commentCallback(e); } _enforceBufferSizeLimit(e = 0) { const r = (t) => { var i, n; t && Array.isArray(t) && (!((n = (i = t[0].attributes) === null || i === void 0 ? void 0 : i.ID) === null || n === void 0) && n[0]) && (t[0].attributes.ID.forEach((s) => { delete this._underConstructionById[s], delete this._completedReferences[s]; }), t.forEach((s) => { s.child_features && s.child_features.forEach((o) => r(o)), s.derived_features && s.derived_features.forEach((o) => r(o)); })); }; for (; this._underConstructionTopLevel.length + e > this.bufferSize; ) { const t = this._underConstructionTopLevel.shift(); t && (this._emitItem(t), r(t)); } } /** * return all under-construction features, called when we know * there will be no additional data to attach to them */ _emitAllUnderConstructionFeatures() { if (this._underConstructionTopLevel.forEach(this._emitItem.bind(this)), this._underConstructionTopLevel = [], this._underConstructionById = {}, this._completedReferences = {}, Array.from(Object.values(this._underConstructionOrphans)).length) throw new Error(`some features reference other features that do not exist in the file (or in the same '###' scope). ${Object.keys(this._underConstructionOrphans).join(",")}`); } // do the right thing with a newly-parsed feature line _bufferLine(e) { var r, t, i; const a = { ...F(e), child_features: [], derived_features: [] }, s = ((r = a.attributes) === null || r === void 0 ? void 0 : r.ID) || [], o = ((t = a.attributes) === null || t === void 0 ? void 0 : t.Parent) || [], h = this.disableDerivesFromReferences ? [] : ((i = a.attributes) === null || i === void 0 ? void 0 : i.Derives_from) || []; if (!s.length && !o.length && !h.length) { this._emitItem([a]); return; } let l; s.forEach((f) => { const u = this._underConstructionById[f]; u ? (u[u.length - 1].type !== a.type && this._parseError(`multi-line feature "${f}" has inconsistent types: "${a.type}", "${u[u.length - 1].type}"`), u.push(a), l = u) : (l = [a], this._enforceBufferSizeLimit(1), !o.length && !h.length && this._underConstructionTopLevel.push(l), this._underConstructionById[f] = l, this._resolveReferencesTo(l, f)); }), this._resolveReferencesFrom(l || [a], { Parent: o, Derives_from: h }, s); } _resolveReferencesTo(e, r) { const t = this._underConstructionOrphans[r]; t && (e.forEach((i) => { i.child_features.push(...t.Parent); }), e.forEach((i) => { i.derived_features.push(...t.Derives_from); }), delete this._underConstructionOrphans[r]); } _parseError(e) { this.eof = !0, this.errorCallback(`${this.lineNumber}: ${e}`); } _resolveReferencesFrom(e, r, t) { function i(n, a, s) { let o = n[a]; o || (o = {}, n[a] = o); const h = o[s] || !1; return o[s] = !0, h; } r.Parent.forEach((n) => { const a = this._underConstructionById[n]; if (a) { const s = C.Parent; t.filter((o) => i(this._completedReferences, o, `Parent,${n}`)).length || a.forEach((o) => { o[s].push(e); }); } else { let s = this._underConstructionOrphans[n]; s || (s = { Parent: [], Derives_from: [] }, this._underConstructionOrphans[n] = s), s.Parent.push(e); } }), r.Derives_from.forEach((n) => { const a = this._underConstructionById[n]; if (a) { const s = C.Derives_from; t.filter((o) => i(this._completedReferences, o, `Derives_from,${n}`)).length || a.forEach((o) => { o[s].push(e); }); } else { let s = this._underConstructionOrphans[n]; s || (s = { Parent: [], Derives_from: [] }, this._underConstructionOrphans[n] = s), s.Derives_from.push(e); } }); } } function L(c) { const e = [], r = new S({ featureCallback: (t) => e.push(t), disableDerivesFromReferences: !0, errorCallback: (t) => { throw t; } }); for (const t of c.split(/\r?\n/)) r.addLine(t); return r.finish(), e; } function q(c) { const { end: e, start: r, child_features: t, derived_features: i, attributes: n, type: a, source: s, phase: o, seq_id: h, score: l, strand: f } = c; let u; f === "+" ? u = 1 : f === "-" ? u = -1 : f === "." && (u = 0); const k = /* @__PURE__ */ new Set([ "start", "end", "seq_id", "score", "type", "source", "phase", "strand" ]), v = n || {}, b = {}; for (const d of Object.keys(v)) { let _ = d.toLowerCase(); if (k.has(_) && (_ += "2"), v[d] && d !== "_lineHash") { let p = v[d]; Array.isArray(p) && p.length === 1 && ([p] = p), b[_] = p; } } return { ...b, start: r - 1, end: e, strand: u, type: a, source: s, refName: h, derived_features: i, phase: o === null ? void 0 : Number(o), score: l === null ? void 0 : l, subfeatures: t.flatMap((d) => d.map((_) => q(_))) }; } export { q as f, L as p }; //# sourceMappingURL=featureData-Bm8gwGZK.js.map