@jbrowse/bandage-core 11.2.0 → 11.4.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.
Files changed (64) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{chunk-5GRF7PJX.js → chunk-3HGYGISG.js} +4 -4
  3. package/dist/chunks/{chunk-A7VSP7MQ.js → chunk-3LZ334X4.js} +1 -1
  4. package/dist/chunks/{chunk-3UST3ZQE.js → chunk-6VVGFQ7S.js} +1 -1
  5. package/dist/chunks/{chunk-VWT3WZRQ.js → chunk-6YJESZND.js} +12 -12
  6. package/dist/chunks/{chunk-QTDBOJJO.js → chunk-7O7EGTYG.js} +1 -1
  7. package/dist/chunks/{chunk-3XSRT7RQ.js → chunk-B5ARSBOH.js} +36 -30
  8. package/dist/chunks/{chunk-RNYPCQZ3.js → chunk-BXLLMWC3.js} +1 -1
  9. package/dist/chunks/{chunk-AI5PTOSV.js → chunk-CE6ZIKJX.js} +1 -1
  10. package/dist/chunks/{chunk-W6EXQDV5.js → chunk-EFD753MS.js} +1 -1
  11. package/dist/chunks/{chunk-DR24UTRS.js → chunk-FRTYQQDI.js} +5 -2
  12. package/dist/chunks/{chunk-XVS52NMZ.js → chunk-G3I4TCEZ.js} +1 -1
  13. package/dist/chunks/{chunk-TABI4JEU.js → chunk-GM7M25NW.js} +1 -1
  14. package/dist/chunks/{chunk-ZU54STUX.js → chunk-I4BYUNJN.js} +2 -2
  15. package/dist/chunks/chunk-JDZ5GTZT.js +20 -0
  16. package/dist/chunks/{chunk-S2PUF4SX.js → chunk-JQ52XYD2.js} +5 -5
  17. package/dist/chunks/chunk-M75QPZNJ.js +502 -0
  18. package/dist/chunks/{chunk-TREAOGDV.js → chunk-N7G5ROIV.js} +7 -7
  19. package/dist/chunks/{chunk-WAST7UVB.js → chunk-QM7KEWWT.js} +1 -1
  20. package/dist/chunks/{chunk-KDU4EF66.js → chunk-REOWLPH4.js} +1 -1
  21. package/dist/chunks/{chunk-VQT3A57T.js → chunk-TEXAKEJX.js} +2 -2
  22. package/dist/chunks/{chunk-C2TAJTUO.js → chunk-TJOOHTJ6.js} +1 -1
  23. package/dist/chunks/{chunk-QR5XR5XL.js → chunk-TZLEHZVC.js} +8 -4
  24. package/dist/chunks/chunk-UFUSPK2A.js +227 -0
  25. package/dist/chunks/{chunk-XZ6PQBU6.js → chunk-VIQL7GZ4.js} +1 -1
  26. package/dist/chunks/{chunk-SWCULW6S.js → chunk-XSF4RQRP.js} +7 -6
  27. package/dist/cli/figure.js +20 -19
  28. package/dist/cli/fold.js +2 -2
  29. package/dist/figure.js +16 -15
  30. package/dist/figureData.js +15 -14
  31. package/dist/figureScene.js +10 -9
  32. package/dist/figureSettings.js +3 -3
  33. package/dist/gfa/graphTables.js +7 -3
  34. package/dist/index.js +52 -32
  35. package/dist/layout/forceCache.js +3 -3
  36. package/dist/layout/tubeMapLayout.js +4 -2
  37. package/dist/layout/walkRowDraw.js +2 -2
  38. package/dist/layout/walkRowLayout.js +6 -2
  39. package/dist/layout/walkRowLinks.js +12 -0
  40. package/dist/layout/walkRowRuns.js +20 -0
  41. package/dist/layout/walkRows.js +5 -2
  42. package/dist/layout/walkStrip.js +7 -5
  43. package/dist/layoutModes.js +6 -4
  44. package/dist/pipeline.js +2 -2
  45. package/dist/referenceStrip.js +2 -2
  46. package/dist/renderer/GeometryBuilder.js +1 -1
  47. package/dist/tubeMap/bundle.js +5 -3
  48. package/dist/tubeMap/coarsen.js +5 -3
  49. package/dist/tubeMap/deviations.js +5 -3
  50. package/dist/tubeMap/draw.js +5 -3
  51. package/dist/tubeMap/nodeColors.js +2 -2
  52. package/dist/types/gfa/graphTables.d.ts +10 -1
  53. package/dist/types/index.d.ts +5 -1
  54. package/dist/types/layout/walkRowLayout.d.ts +4 -0
  55. package/dist/types/layout/walkRowLinks.d.ts +32 -0
  56. package/dist/types/layout/walkRowRuns.d.ts +56 -0
  57. package/dist/types/layout/walkRows.d.ts +2 -1
  58. package/dist/types/version.d.ts +1 -1
  59. package/dist/version.js +1 -1
  60. package/dist/viewport.js +3 -3
  61. package/dist/walkEncoding.js +2 -2
  62. package/dist/walkHighlight.js +3 -3
  63. package/package.json +1 -1
  64. package/dist/chunks/chunk-5DHOFF4C.js +0 -322
@@ -0,0 +1,56 @@
1
+ import type { WalkRow, WalkRows, WalkRun } from './walkRows.js';
2
+ import type { GraphTables } from '../gfa/graphTables.js';
3
+ import type { Graph, StopChunk } from '../types.js';
4
+ export type WalkRowMeta = Omit<WalkRow, 'runs' | 'visits'>;
5
+ /**
6
+ * Each row's visits, row i's at `offsets[i]` up to `offsets[i + 1]`: the
7
+ * node as an index into `names`, its bp offset from the bar's start, its bp,
8
+ * and 1 where the reference walk visits it anywhere in the cut
9
+ */
10
+ export interface WalkVisitColumns {
11
+ offsets: Uint32Array;
12
+ node: Int32Array;
13
+ start: Float64Array;
14
+ bp: Float64Array;
15
+ onReference: Uint8Array;
16
+ names: ArrayLike<string>;
17
+ }
18
+ /**
19
+ * `walkRows` with each row's runs as typed arrays, which cross from a worker
20
+ * without an object per run. Row 0 is the reference; row i's runs are
21
+ * `offsets[i]` up to `offsets[i + 1]`.
22
+ */
23
+ export interface WalkRowRuns {
24
+ origin: number;
25
+ rows: WalkRowMeta[];
26
+ offsets: Uint32Array;
27
+ start: Float64Array;
28
+ bp: Float64Array;
29
+ referenceStart: Float64Array;
30
+ flags: Uint8Array;
31
+ chunk: Int32Array;
32
+ chunks: StopChunk[];
33
+ visits?: WalkVisitColumns;
34
+ }
35
+ export declare function referenceWalkName(graph: Pick<Graph, 'nodes' | 'paths' | 'referencePath'>): string | undefined;
36
+ /**
37
+ * The walk rows of a Graph, or of a cut's tables without the Graph of their
38
+ * steps, as `walkRows` reads them. Tables name their reference by
39
+ * `referencePath`, as loadGraph does.
40
+ *
41
+ * Each walk is cut at the nearest reference nodes IT visits on either side of
42
+ * the region, so a walk that skips one flanking node at a SNP is still
43
+ * measured between flanks rather than whole. A walk with one flank, whose
44
+ * contig ends inside the window, is the steps past that flank read in the
45
+ * reference's direction, a lower bound.
46
+ */
47
+ export declare function walkRowRuns(source: Graph | GraphTables, region?: {
48
+ start: number;
49
+ end: number;
50
+ }, o?: {
51
+ visits?: boolean;
52
+ referencePath?: string;
53
+ }): WalkRowRuns | undefined;
54
+ export declare function runAt(t: WalkRowRuns, k: number): WalkRun;
55
+ /** The rows as `WalkRows`, an object per run, and per visit where it has them */
56
+ export declare function walkRowsOf(t: WalkRowRuns, unit?: number): WalkRows;
@@ -1,5 +1,6 @@
1
1
  import type { GapCause } from '../gfa/walkStops.js';
2
2
  import type { Graph, StopChunk } from '../types.js';
3
+ export { referenceWalkName } from './walkRowRuns.js';
3
4
  export interface WalkRun {
4
5
  start: number;
5
6
  bp: number;
@@ -22,6 +23,7 @@ export interface WalkStop {
22
23
  export interface WalkVisit {
23
24
  node: string;
24
25
  start: number;
26
+ bp: number;
25
27
  onReference: boolean;
26
28
  }
27
29
  export interface WalkRow {
@@ -48,7 +50,6 @@ export declare function filterSamples<R extends {
48
50
  sample: string;
49
51
  label: string;
50
52
  }>(rows: R[], samples: string[] | undefined): R[];
51
- export declare function referenceWalkName(graph: Pick<Graph, 'nodes' | 'paths' | 'referencePath'>): string | undefined;
52
53
  export declare function walkRows(graph: Graph, region?: {
53
54
  start: number;
54
55
  end: number;
@@ -1 +1 @@
1
- export declare const version = "11.2.0";
1
+ export declare const version = "11.4.0";
package/dist/version.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./chunks/chunk-WAST7UVB.js";
3
+ } from "./chunks/chunk-QM7KEWWT.js";
4
4
  export {
5
5
  version
6
6
  };
package/dist/viewport.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  screenToLayout,
6
6
  viewportOf,
7
7
  zoomAbout
8
- } from "./chunks/chunk-AI5PTOSV.js";
9
- import "./chunks/chunk-KDU4EF66.js";
8
+ } from "./chunks/chunk-CE6ZIKJX.js";
9
+ import "./chunks/chunk-REOWLPH4.js";
10
10
  import "./chunks/chunk-3PZSBNLI.js";
11
11
  import "./chunks/chunk-CKUVEHSS.js";
12
12
  import "./chunks/chunk-OPPVSPEF.js";
@@ -14,7 +14,7 @@ import "./chunks/chunk-VPE4AYP7.js";
14
14
  import "./chunks/chunk-FFHJGWDK.js";
15
15
  import "./chunks/chunk-QYBZZI5H.js";
16
16
  import "./chunks/chunk-5I3K4R2G.js";
17
- import "./chunks/chunk-3XSRT7RQ.js";
17
+ import "./chunks/chunk-B5ARSBOH.js";
18
18
  import "./chunks/chunk-B5X2RLJG.js";
19
19
  import "./chunks/chunk-VX656OAZ.js";
20
20
  import "./chunks/chunk-DZR37KXT.js";
@@ -9,8 +9,8 @@ import {
9
9
  schemeColor,
10
10
  schemeCss,
11
11
  schemeRgb
12
- } from "./chunks/chunk-TABI4JEU.js";
13
- import "./chunks/chunk-SWCULW6S.js";
12
+ } from "./chunks/chunk-GM7M25NW.js";
13
+ import "./chunks/chunk-XSF4RQRP.js";
14
14
  import "./chunks/chunk-G2FD7S3C.js";
15
15
  import "./chunks/chunk-GQZVR5DW.js";
16
16
  import "./chunks/chunk-WA5WNP6V.js";
@@ -2,9 +2,9 @@ import {
2
2
  facetLifts,
3
3
  walkHighlight,
4
4
  walkLift
5
- } from "./chunks/chunk-DR24UTRS.js";
6
- import "./chunks/chunk-TABI4JEU.js";
7
- import "./chunks/chunk-SWCULW6S.js";
5
+ } from "./chunks/chunk-FRTYQQDI.js";
6
+ import "./chunks/chunk-GM7M25NW.js";
7
+ import "./chunks/chunk-XSF4RQRP.js";
8
8
  import "./chunks/chunk-G2FD7S3C.js";
9
9
  import "./chunks/chunk-GQZVR5DW.js";
10
10
  import "./chunks/chunk-WA5WNP6V.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/bandage-core",
3
- "version": "11.2.0",
3
+ "version": "11.4.0",
4
4
  "description": "Pangenome graph layout and drawing with no host: GFA in, the Bandage force-directed engine and reference-anchored layouts, a Canvas2D renderer, hit testing and labels out",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -1,322 +0,0 @@
1
- import {
2
- pathOrigin
3
- } from "./chunk-B5X2RLJG.js";
4
- import {
5
- gapParts
6
- } from "./chunk-EIY2SKD3.js";
7
- import {
8
- groupBy
9
- } from "./chunk-BSOZW3FC.js";
10
- import {
11
- panSNContig,
12
- panSNSample
13
- } from "./chunk-4XWZNPQ2.js";
14
-
15
- // src/layout/walkRows.ts
16
- function sampleOf(path) {
17
- return path.sample ?? panSNSample(path.name);
18
- }
19
- function labelOf(path) {
20
- return path.haplotype !== void 0 && path.sample !== void 0 ? `${path.sample}#${path.haplotype}` : sampleOf(path);
21
- }
22
- var NodeTable = class {
23
- constructor(graph) {
24
- this.index = /* @__PURE__ */ new Map();
25
- this.ids = [];
26
- this.lengths = [];
27
- this.onReference = new Uint8Array(0);
28
- this.referenceStart = new Float64Array(0);
29
- this.referenceEnd = new Float64Array(0);
30
- for (const node of graph.nodes) {
31
- this.lengths[this.indexOf(node.id)] = node.length;
32
- }
33
- }
34
- indexOf(id) {
35
- let i = this.index.get(id);
36
- if (i === void 0) {
37
- i = this.lengths.length;
38
- this.index.set(id, i);
39
- this.ids.push(id);
40
- this.lengths.push(0);
41
- }
42
- return i;
43
- }
44
- nodesOf(path) {
45
- const nodes = new Int32Array(path.nodeIds.length);
46
- path.nodeIds.forEach((id, k) => {
47
- nodes[k] = this.indexOf(id);
48
- });
49
- return nodes;
50
- }
51
- spanAt(steps, k) {
52
- const node = k >= 0 && k < steps.length ? steps[k] : -1;
53
- return node >= 0 && this.onReference[node] ? { start: this.referenceStart[node], end: this.referenceEnd[node] } : void 0;
54
- }
55
- };
56
- function stepsOf(pieces, table) {
57
- const out = [];
58
- const gaps = [];
59
- let end;
60
- let previous;
61
- for (const piece of pieces) {
62
- if (end !== void 0 && piece.start !== void 0 && piece.start > end) {
63
- gaps.push(gapParts(piece.start - end, previous?.after, piece.before));
64
- out.push(-gaps.length);
65
- }
66
- let bp = 0;
67
- for (const node of piece.nodes) {
68
- out.push(node);
69
- bp += table.lengths[node];
70
- }
71
- end = piece.start === void 0 ? void 0 : piece.start + bp;
72
- previous = piece;
73
- }
74
- return { steps: Float64Array.from(out), gaps };
75
- }
76
- function stepSpan(pieces, table, k) {
77
- let end;
78
- let at = 0;
79
- let found;
80
- for (const piece of pieces) {
81
- if (piece.start === void 0 || end !== void 0 && piece.start < end) {
82
- return void 0;
83
- }
84
- if (end !== void 0 && piece.start > end) {
85
- if (at++ === k) {
86
- found = { start: end, end: piece.start };
87
- }
88
- }
89
- let pos = piece.start;
90
- for (const node of piece.nodes) {
91
- const len = table.lengths[node];
92
- if (at++ === k) {
93
- found = { start: pos, end: pos + len };
94
- }
95
- pos += len;
96
- }
97
- end = pos;
98
- }
99
- return found;
100
- }
101
- function sliceBetween(steps, table, region, flanked = true) {
102
- if (!region || !flanked) {
103
- return { ids: steps, complete: true, from: -1, to: -1 };
104
- }
105
- const { onReference, referenceStart, referenceEnd } = table;
106
- let i0 = -1;
107
- let i1 = -1;
108
- let bestEnd = -Infinity;
109
- let bestStart = Infinity;
110
- for (let i = 0; i < steps.length; i++) {
111
- const node = steps[i];
112
- if (node >= 0 && onReference[node]) {
113
- const end2 = referenceEnd[node];
114
- const start = referenceStart[node];
115
- if (end2 <= region.start && end2 > bestEnd) {
116
- bestEnd = end2;
117
- i0 = i;
118
- }
119
- if (start >= region.end && start < bestStart) {
120
- bestStart = start;
121
- i1 = i;
122
- }
123
- }
124
- }
125
- if (i0 >= 0 && i1 >= 0) {
126
- const ids2 = steps.slice(Math.min(i0, i1) + 1, Math.max(i0, i1));
127
- return {
128
- ids: i0 < i1 ? ids2 : ids2.reverse(),
129
- complete: true,
130
- from: i0,
131
- to: i1
132
- };
133
- }
134
- const spanAt = (k) => table.spanAt(steps, k);
135
- const flank = i0 >= 0 ? i0 : i1;
136
- let near = -1;
137
- for (let d = 1; flank >= 0 && near < 0 && d < steps.length; d++) {
138
- near = [flank - d, flank + d].find((j) => spanAt(j) !== void 0) ?? -1;
139
- }
140
- if (near < 0) {
141
- return { ids: steps, complete: false, from: -1, to: -1 };
142
- }
143
- const forward = near > flank === spanAt(near).start > spanAt(flank).start;
144
- const after = forward === (flank === i0);
145
- const ids = after ? steps.slice(flank + 1) : steps.slice(0, flank).reverse();
146
- const last = ids.length > 0 ? ids.length - 1 : -1;
147
- const end = last < 0 ? spanAt(flank) : spanAt(after ? flank + 1 + last : 0);
148
- const stop = {
149
- contigEnds: end !== void 0,
150
- shortBp: !end ? 0 : Math.max(0, region.start - end.end, end.start - region.end)
151
- };
152
- return {
153
- ids,
154
- complete: false,
155
- from: flank,
156
- to: after ? steps.length : -1,
157
- stop
158
- };
159
- }
160
- function filterSamples(rows, samples) {
161
- return samples ? rows.filter((r) => samples.includes(r.sample)).sort(
162
- (a, b) => samples.indexOf(a.sample) - samples.indexOf(b.sample) || a.label.localeCompare(b.label)
163
- ) : rows;
164
- }
165
- function referenceWalkName(graph) {
166
- const names = (graph.paths ?? []).map((p) => pathOrigin(p.name).name);
167
- if (graph.referencePath !== void 0 && names.includes(graph.referencePath)) {
168
- return graph.referencePath;
169
- }
170
- const rankZero = new Set(
171
- graph.nodes.flatMap((n) => n.stable?.rank === 0 ? [n.stable.refName] : [])
172
- );
173
- return names.find((n) => rankZero.has(n)) ?? names[0];
174
- }
175
- function walkRows(graph, region, unit, o = {}) {
176
- const paths = graph.paths ?? [];
177
- const nameOf = (p) => pathOrigin(p.name).name;
178
- const referenceName = referenceWalkName(graph);
179
- const referencePieces = paths.filter((p) => nameOf(p) === referenceName).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
180
- const first = referencePieces[0];
181
- const others = paths.filter((p) => !referencePieces.includes(p));
182
- if (!first || others.length === 0) {
183
- return void 0;
184
- }
185
- const walks = groupBy(others, nameOf);
186
- const table = new NodeTable(graph);
187
- const referenceStart = first.start ?? 0;
188
- const cut = region && region.end > region.start ? region : void 0;
189
- const referenceNodes = referencePieces.map((piece) => table.nodesOf(piece));
190
- const nodeCount = table.lengths.length;
191
- table.onReference = new Uint8Array(nodeCount);
192
- table.referenceStart = new Float64Array(nodeCount);
193
- table.referenceEnd = new Float64Array(nodeCount);
194
- let reachesBefore = false;
195
- let reachesAfter = false;
196
- for (const [p, piece] of referencePieces.entries()) {
197
- let pos = piece.start ?? 0;
198
- for (const node of referenceNodes[p]) {
199
- const len = table.lengths[node];
200
- if (!table.onReference[node]) {
201
- table.onReference[node] = 1;
202
- table.referenceStart[node] = pos;
203
- table.referenceEnd[node] = pos + len;
204
- reachesBefore ||= cut !== void 0 && pos + len <= cut.start;
205
- reachesAfter ||= cut !== void 0 && pos >= cut.end;
206
- }
207
- pos += len;
208
- }
209
- }
210
- const flanked = cut === void 0 || reachesBefore && reachesAfter;
211
- const rowOf = (paths2, nodes) => {
212
- const path = paths2[0];
213
- const pieces = paths2.map((piece, p) => ({
214
- start: piece.start,
215
- nodes: nodes?.[p] ?? table.nodesOf(piece),
216
- before: piece.before,
217
- after: piece.after
218
- })).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
219
- const { steps, gaps } = stepsOf(pieces, table);
220
- const { ids, complete, from, to, stop } = sliceBetween(
221
- steps,
222
- table,
223
- cut,
224
- flanked
225
- );
226
- const contig = path.contig ?? panSNContig(pathOrigin(path.name).name);
227
- const axisSpan = stepSpan(pieces, table, from < 0 ? 0 : from);
228
- const axis = !axisSpan ? void 0 : from < 0 ? { contig, start: axisSpan.start, reversed: false } : from < to ? { contig, start: axisSpan.end, reversed: false } : { contig, start: axisSpan.start, reversed: true };
229
- const {
230
- ids: nodeIds,
231
- lengths,
232
- onReference,
233
- referenceStart: referenceStart2,
234
- referenceEnd
235
- } = table;
236
- const runs = [];
237
- const visits = o.visits ? [] : void 0;
238
- let last;
239
- let bp = 0;
240
- let offReferenceBp = 0;
241
- let gapBp = 0;
242
- let step = 0;
243
- const backwards = from >= 0 && from > to;
244
- for (const node of ids) {
245
- if (node < 0) {
246
- const parts = gaps[-node - 1];
247
- for (const { bp: partBp, ...why } of backwards ? [...parts].reverse() : parts) {
248
- last = {
249
- start: bp,
250
- bp: partBp,
251
- onReference: false,
252
- gap: true,
253
- ...why
254
- };
255
- runs.push(last);
256
- bp += partBp;
257
- gapBp += partBp;
258
- }
259
- step = 0;
260
- continue;
261
- }
262
- const len = lengths[node];
263
- const on = onReference[node] === 1;
264
- visits?.push({ node: nodeIds[node], start: bp, onReference: on });
265
- const at = last?.referenceStart;
266
- const forward = on && at !== void 0 && step >= 0 && at + last.bp === referenceStart2[node];
267
- const backward = on && at !== void 0 && step <= 0 && referenceEnd[node] === at;
268
- if (!on && last && !last.onReference && !last.gap) {
269
- last.bp += len;
270
- } else if (forward || backward) {
271
- last.bp += len;
272
- if (!forward) {
273
- last.referenceStart = referenceStart2[node];
274
- last.reversed = true;
275
- }
276
- step = forward ? 1 : -1;
277
- } else {
278
- last = {
279
- start: bp,
280
- bp: len,
281
- onReference: on,
282
- referenceStart: on ? referenceStart2[node] : void 0
283
- };
284
- runs.push(last);
285
- step = 0;
286
- }
287
- bp += len;
288
- if (!on) {
289
- offReferenceBp += len;
290
- }
291
- }
292
- return {
293
- name: path.name,
294
- label: labelOf(path),
295
- sample: sampleOf(path),
296
- haplotype: path.haplotype,
297
- bp,
298
- offReferenceBp,
299
- gapBp,
300
- complete,
301
- stop,
302
- runs,
303
- visits,
304
- axis
305
- };
306
- };
307
- const origin = cut ? cut.start : referenceStart;
308
- return {
309
- origin,
310
- unit,
311
- reference: rowOf(referencePieces, referenceNodes),
312
- rows: [...walks.values()].map((paths2) => rowOf(paths2)).sort(
313
- (a, b) => Number(b.complete) - Number(a.complete) || b.bp - a.bp || a.label.localeCompare(b.label)
314
- )
315
- };
316
- }
317
-
318
- export {
319
- filterSamples,
320
- referenceWalkName,
321
- walkRows
322
- };