@jbrowse/bandage-core 11.5.0 → 11.6.1

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 (138) hide show
  1. package/dist/alleleProjection/projectAlleles.js +1 -1
  2. package/dist/bubbles/bubbleHalos.js +9 -6
  3. package/dist/bubbles/classifyBubble.js +8 -5
  4. package/dist/bubbles/popBubble.js +3 -3
  5. package/dist/bubbles/superbubbles.js +11 -11
  6. package/dist/chunks/{chunk-FFHJGWDK.js → chunk-2C5SATRZ.js} +5 -5
  7. package/dist/chunks/{chunk-4XWZNPQ2.js → chunk-2JL2JVZ2.js} +1 -1
  8. package/dist/chunks/{chunk-BZFOFC4D.js → chunk-2VMKQKVO.js} +17 -7
  9. package/dist/chunks/{chunk-HN3WHMPJ.js → chunk-2XEAITWM.js} +15 -5
  10. package/dist/chunks/{chunk-7BTO7MZS.js → chunk-376YFQOY.js} +2 -2
  11. package/dist/chunks/{chunk-K5LDBMLX.js → chunk-3FWNQNF7.js} +1 -1
  12. package/dist/chunks/{chunk-B5X2RLJG.js → chunk-3YBP46PB.js} +27 -2
  13. package/dist/chunks/{chunk-EJRJAAN7.js → chunk-4DMSPNYV.js} +47 -27
  14. package/dist/chunks/{chunk-A32ZKSHN.js → chunk-4WXFQOYV.js} +5 -5
  15. package/dist/chunks/{chunk-OMUPUB4J.js → chunk-56L6R6D2.js} +2 -2
  16. package/dist/chunks/{chunk-C44YRP5F.js → chunk-5OJZV6YT.js} +3 -2
  17. package/dist/chunks/{chunk-234NFZS4.js → chunk-5ORP7EFJ.js} +1 -1
  18. package/dist/chunks/{chunk-J3JODFDF.js → chunk-5WB7O7IT.js} +3 -3
  19. package/dist/chunks/{chunk-3VCKBSML.js → chunk-6YRSOL4K.js} +2 -2
  20. package/dist/chunks/{chunk-WG5D2H7X.js → chunk-7OTWJQGA.js} +10 -10
  21. package/dist/chunks/{chunk-77EGQQJU.js → chunk-BFUS3ENH.js} +2 -2
  22. package/dist/chunks/{chunk-TGUFT6KK.js → chunk-BLUEFYIR.js} +4 -1
  23. package/dist/chunks/{chunk-3BCVMZUT.js → chunk-BVWMVWLJ.js} +10 -10
  24. package/dist/chunks/{chunk-3GP3KT5L.js → chunk-BW2NMXRV.js} +5 -5
  25. package/dist/chunks/{chunk-2E25TX4G.js → chunk-C6E6HXP5.js} +4 -4
  26. package/dist/chunks/{chunk-5I3K4R2G.js → chunk-CFXXFHRK.js} +2 -1
  27. package/dist/chunks/{chunk-JMABOQWL.js → chunk-CO6RGQAD.js} +1 -6
  28. package/dist/chunks/{chunk-64FCX424.js → chunk-D3E7AXBB.js} +40 -9
  29. package/dist/chunks/{chunk-CGMSKIEO.js → chunk-DV5B5UU7.js} +55 -8
  30. package/dist/chunks/{chunk-G6UIYQZR.js → chunk-EQDQ7P4Y.js} +3 -2
  31. package/dist/chunks/{chunk-VQ7474EH.js → chunk-EVXXFMZ7.js} +8 -7
  32. package/dist/chunks/{chunk-AKLSY4GD.js → chunk-F3KQQDKP.js} +1 -1
  33. package/dist/chunks/{chunk-6EOB6ANX.js → chunk-GZ36HNPJ.js} +1 -1
  34. package/dist/chunks/{chunk-3U3C4PRK.js → chunk-HV35LDYH.js} +3 -3
  35. package/dist/chunks/{chunk-JOWKKQAL.js → chunk-JGHZ3N34.js} +14 -9
  36. package/dist/chunks/{chunk-D4ZFRBB4.js → chunk-JGQQAUVL.js} +3 -3
  37. package/dist/chunks/{chunk-PSCSZSVK.js → chunk-KA4F3N55.js} +4 -4
  38. package/dist/chunks/{chunk-SOMZGDVS.js → chunk-KJDERUQF.js} +1 -1
  39. package/dist/chunks/{chunk-E4ZM4OOJ.js → chunk-KZMSSPS6.js} +2 -2
  40. package/dist/chunks/{chunk-IOWLTUEB.js → chunk-MEVTV4FI.js} +1 -1
  41. package/dist/chunks/{chunk-PNMJFFNB.js → chunk-MHZTTLBU.js} +1 -1
  42. package/dist/chunks/{chunk-TRGKMLXT.js → chunk-MXLYBDOX.js} +14 -13
  43. package/dist/chunks/{chunk-RK3HRRCW.js → chunk-NXBW6KY6.js} +6 -7
  44. package/dist/chunks/{chunk-WC6HX6GJ.js → chunk-OUM54ZSQ.js} +2 -2
  45. package/dist/chunks/{chunk-WA5WNP6V.js → chunk-OYCQVJYY.js} +1 -1
  46. package/dist/chunks/{chunk-FWSERUJV.js → chunk-P5PBJONQ.js} +1 -1
  47. package/dist/chunks/{chunk-JOLLU34X.js → chunk-PQIFYQVI.js} +1 -1
  48. package/dist/chunks/{chunk-EGBBIXTG.js → chunk-QCOVHLJO.js} +1 -1
  49. package/dist/chunks/{chunk-5F4D35U5.js → chunk-QD35GH4C.js} +3 -3
  50. package/dist/chunks/{chunk-XKZ56L5A.js → chunk-RLCYVZ4B.js} +1 -1
  51. package/dist/chunks/{chunk-PQBALYSO.js → chunk-ROLACYCO.js} +16 -16
  52. package/dist/chunks/{chunk-A7H753BA.js → chunk-SDI6BVG7.js} +5 -6
  53. package/dist/chunks/{chunk-A4JDEUAI.js → chunk-SNF2MIEF.js} +1 -1
  54. package/dist/chunks/{chunk-NMWQUFPF.js → chunk-SVVFWTG4.js} +2 -2
  55. package/dist/chunks/{chunk-PFRQBCGC.js → chunk-T3H5ELLA.js} +4 -4
  56. package/dist/chunks/{chunk-WLR4KJVI.js → chunk-TXTSE44S.js} +1 -1
  57. package/dist/chunks/{chunk-UBQSRCWR.js → chunk-VACK24HF.js} +43 -3
  58. package/dist/chunks/{chunk-HSVFCA2J.js → chunk-VO6FKNZE.js} +1 -1
  59. package/dist/chunks/{chunk-NJGYLYU7.js → chunk-W2YAW36J.js} +1 -1
  60. package/dist/chunks/{chunk-VD4MLYEK.js → chunk-WI6SUU5B.js} +2 -2
  61. package/dist/chunks/{chunk-GJU6BJJA.js → chunk-XR2HMGAS.js} +1 -1
  62. package/dist/chunks/{chunk-KOJKFNCW.js → chunk-XXOBCANT.js} +26 -12
  63. package/dist/chunks/{chunk-7EDGWT67.js → chunk-YEYQFNFQ.js} +1 -1
  64. package/dist/chunks/{chunk-UFUSPK2A.js → chunk-YYIU7P73.js} +4 -1
  65. package/dist/chunks/{chunk-CRCD3ODN.js → chunk-ZANALBSX.js} +11 -3
  66. package/dist/cli/figure.js +51 -46
  67. package/dist/cli/fold.js +11 -11
  68. package/dist/deletionEdges.js +5 -2
  69. package/dist/facetGrid.js +2 -2
  70. package/dist/figure.js +35 -35
  71. package/dist/figureData.js +37 -37
  72. package/dist/figureScene.js +25 -25
  73. package/dist/figureSettings.js +11 -11
  74. package/dist/foldVariants.js +2 -2
  75. package/dist/gaf/parseGaf.js +1 -1
  76. package/dist/gbzCut.js +4 -4
  77. package/dist/gbzWindow.js +3 -3
  78. package/dist/genes/backboneGenes.js +4 -4
  79. package/dist/genes/geneFiles.js +1 -1
  80. package/dist/genes/genePins.js +3 -3
  81. package/dist/gfa/gfaConverter.js +4 -4
  82. package/dist/gfa/graphTables.js +2 -2
  83. package/dist/gfa-core/gfaParser.js +1 -1
  84. package/dist/gfa-core/index.js +1 -1
  85. package/dist/graphLabels.js +7 -4
  86. package/dist/index.js +62 -62
  87. package/dist/labelLayout.js +11 -8
  88. package/dist/layout/anchoredLayout.js +1 -1
  89. package/dist/layout/forceCache.js +11 -11
  90. package/dist/layout/mergeRuns.js +2 -2
  91. package/dist/layout/placeOffReference.js +1 -1
  92. package/dist/layout/sampleRowLayout.js +2 -2
  93. package/dist/layout/trimToWindow.js +2 -2
  94. package/dist/layout/tubeMapLayout.js +14 -14
  95. package/dist/layout/walkRowDraw.js +12 -12
  96. package/dist/layout/walkRowLayout.js +7 -7
  97. package/dist/layout/walkRowLinks.js +1 -1
  98. package/dist/layout/walkRowRuns.js +4 -4
  99. package/dist/layout/walkRows.js +5 -5
  100. package/dist/layout/walkStrip.js +17 -17
  101. package/dist/layoutEngines.js +1 -1
  102. package/dist/layoutModes.js +17 -17
  103. package/dist/locus.js +1 -1
  104. package/dist/nodeWidths.js +5 -3
  105. package/dist/pansn.js +1 -1
  106. package/dist/pathAnchoring.js +4 -2
  107. package/dist/pathColors.js +8 -8
  108. package/dist/pipeline.js +10 -10
  109. package/dist/reference.js +2 -2
  110. package/dist/referenceStrip.js +12 -12
  111. package/dist/renderer/Canvas2DRenderer.js +1 -1
  112. package/dist/renderer/GeometryBuilder.js +11 -11
  113. package/dist/tubeMap/axis.js +8 -5
  114. package/dist/tubeMap/bundle.js +15 -15
  115. package/dist/tubeMap/coarsen.js +15 -15
  116. package/dist/tubeMap/deviations.js +18 -18
  117. package/dist/tubeMap/draw.js +10 -8
  118. package/dist/tubeMap/genes.js +9 -6
  119. package/dist/tubeMap/nodeColors.js +12 -12
  120. package/dist/tubeMap/reads.js +4 -4
  121. package/dist/types/figureData.d.ts +12 -0
  122. package/dist/types/gaf/parseGaf.d.ts +1 -1
  123. package/dist/types/nodeWidths.d.ts +2 -1
  124. package/dist/types/pathAnchoring.d.ts +2 -0
  125. package/dist/types/renderer/Canvas2DRenderer.d.ts +2 -0
  126. package/dist/types/tubeMap/reads.d.ts +0 -1
  127. package/dist/types/util/geometry.d.ts +7 -1
  128. package/dist/types/version.d.ts +1 -1
  129. package/dist/util/SpatialIndex.js +7 -4
  130. package/dist/util/edgeCurves.js +6 -3
  131. package/dist/util/geometry.js +1 -1
  132. package/dist/util/hitDetection.js +8 -5
  133. package/dist/version.js +1 -1
  134. package/dist/viewport.js +11 -11
  135. package/dist/walkEncoding.js +12 -12
  136. package/dist/walkHighlight.js +13 -13
  137. package/dist/walkKey.js +8 -5
  138. package/package.json +1 -1
@@ -4,41 +4,41 @@ import {
4
4
  import {
5
5
  facetLifts,
6
6
  walkLift
7
- } from "./chunk-VQ7474EH.js";
7
+ } from "./chunk-EVXXFMZ7.js";
8
8
  import {
9
9
  buildGeometry,
10
10
  computeReferenceRamp
11
- } from "./chunk-JOWKKQAL.js";
11
+ } from "./chunk-JGHZ3N34.js";
12
12
  import {
13
13
  walkKey
14
- } from "./chunk-D4ZFRBB4.js";
14
+ } from "./chunk-JGQQAUVL.js";
15
15
  import {
16
16
  walkRowsExtent
17
- } from "./chunk-FWSERUJV.js";
17
+ } from "./chunk-P5PBJONQ.js";
18
18
  import {
19
19
  pathLegend,
20
20
  walkLabelsOf
21
- } from "./chunk-3GP3KT5L.js";
21
+ } from "./chunk-BW2NMXRV.js";
22
22
  import {
23
23
  FIGURE_DEFAULTS
24
- } from "./chunk-K5LDBMLX.js";
24
+ } from "./chunk-3FWNQNF7.js";
25
25
  import {
26
26
  drawingBounds
27
- } from "./chunk-WG5D2H7X.js";
27
+ } from "./chunk-7OTWJQGA.js";
28
28
  import {
29
29
  referenceLabel
30
- } from "./chunk-234NFZS4.js";
30
+ } from "./chunk-5ORP7EFJ.js";
31
31
  import {
32
32
  resolveColorScheme
33
33
  } from "./chunk-JKJWSY4V.js";
34
34
  import {
35
35
  deletionDrawing,
36
36
  deletionEdges
37
- } from "./chunk-CGMSKIEO.js";
37
+ } from "./chunk-DV5B5UU7.js";
38
38
  import {
39
39
  facetCells,
40
40
  facetSettingOf
41
- } from "./chunk-TGUFT6KK.js";
41
+ } from "./chunk-BLUEFYIR.js";
42
42
 
43
43
  // src/figureScene.ts
44
44
  function figureScene(graph, layout, o) {
@@ -1,12 +1,12 @@
1
- import {
2
- pathOrigin
3
- } from "./chunk-B5X2RLJG.js";
4
1
  import {
5
2
  groupDigits
6
- } from "./chunk-PFRQBCGC.js";
3
+ } from "./chunk-T3H5ELLA.js";
4
+ import {
5
+ pathOrigin
6
+ } from "./chunk-3YBP46PB.js";
7
7
  import {
8
8
  isGenericSample
9
- } from "./chunk-4XWZNPQ2.js";
9
+ } from "./chunk-2JL2JVZ2.js";
10
10
 
11
11
  // src/pathColors.ts
12
12
  function nameHue(name) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  coversGraph
3
- } from "./chunk-E4ZM4OOJ.js";
3
+ } from "./chunk-KZMSSPS6.js";
4
4
  import {
5
5
  bubblesFromGraph,
6
6
  derivedBubble,
@@ -10,13 +10,13 @@ import {
10
10
  } from "./chunk-RFG42VIO.js";
11
11
  import {
12
12
  bubbleSegmentIds
13
- } from "./chunk-A4JDEUAI.js";
13
+ } from "./chunk-SNF2MIEF.js";
14
14
  import {
15
15
  bubbleSubgraph
16
- } from "./chunk-PNMJFFNB.js";
16
+ } from "./chunk-MHZTTLBU.js";
17
17
  import {
18
18
  strandSides
19
- } from "./chunk-UBQSRCWR.js";
19
+ } from "./chunk-VACK24HF.js";
20
20
  import {
21
21
  pushTo
22
22
  } from "./chunk-BSOZW3FC.js";
@@ -57,7 +57,8 @@ function parseGFA(file) {
57
57
  };
58
58
  for (const rawLine of file.split("\n")) {
59
59
  const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
60
- const type = line.split(" ", 1)[0];
60
+ const tab = line.indexOf(" ");
61
+ const type = tab === -1 ? line : line.slice(0, tab);
61
62
  if (type === "H") {
62
63
  const [, ...rest] = line.split(" ");
63
64
  graph.header.push(parseTags(rest));
@@ -18,13 +18,8 @@ function isLayoutEngineKind(value) {
18
18
  return LAYOUT_ENGINE_VALUES.includes(value);
19
19
  }
20
20
  var layoutEngine = async (request) => {
21
- if (request.options.engine === "stress") {
22
- const start2 = performance.now();
23
- const result2 = stressLayout(request);
24
- return { result: result2, duration: performance.now() - start2 };
25
- }
26
21
  const start = performance.now();
27
- const result = await fmmmLayout(request);
22
+ const result = request.options.engine === "stress" ? stressLayout(request) : await fmmmLayout(request);
28
23
  return { result, duration: performance.now() - start };
29
24
  };
30
25
 
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  tableNodeIds,
3
3
  tablePath
4
- } from "./chunk-NJGYLYU7.js";
5
- import {
6
- pathOrigin
7
- } from "./chunk-B5X2RLJG.js";
4
+ } from "./chunk-W2YAW36J.js";
8
5
  import {
9
6
  gapParts
10
7
  } from "./chunk-EIY2SKD3.js";
8
+ import {
9
+ pathOrigin
10
+ } from "./chunk-3YBP46PB.js";
11
11
  import {
12
12
  groupBy
13
13
  } from "./chunk-BSOZW3FC.js";
14
14
  import {
15
15
  panSNContig,
16
16
  panSNSample
17
- } from "./chunk-4XWZNPQ2.js";
17
+ } from "./chunk-2JL2JVZ2.js";
18
18
 
19
19
  // src/layout/walkRowRuns.ts
20
20
  var RUN_ON_REFERENCE = 1;
@@ -179,6 +179,7 @@ function walkRowRuns(source, region, o = {}) {
179
179
  const walks = groupBy(others, nameOf);
180
180
  const spanStart = new Float64Array(names.length).fill(Number.NaN);
181
181
  const spanEnd = new Float64Array(names.length);
182
+ const revisits = /* @__PURE__ */ new Map();
182
183
  let reachesBefore = false;
183
184
  let reachesAfter = false;
184
185
  const cut = region && region.end > region.start ? region : void 0;
@@ -187,7 +188,14 @@ function walkRowRuns(source, region, o = {}) {
187
188
  for (let s = from[piece], stop = to[piece]; s < stop; s++) {
188
189
  const node = all[s];
189
190
  const len = lengthOf(node);
190
- if (Number.isNaN(spanStart[node])) {
191
+ if (!Number.isNaN(spanStart[node])) {
192
+ const starts = revisits.get(node);
193
+ if (starts) {
194
+ starts.push(pos);
195
+ } else {
196
+ revisits.set(node, [spanStart[node], pos]);
197
+ }
198
+ } else {
191
199
  spanStart[node] = pos;
192
200
  spanEnd[node] = pos + len;
193
201
  if (cut) {
@@ -345,6 +353,27 @@ function walkRowRuns(source, region, o = {}) {
345
353
  let last = -1;
346
354
  let lastFlags = 0;
347
355
  let lastRef = Number.NaN;
356
+ let cursor = Number.NaN;
357
+ const placeOf = (id) => {
358
+ const starts = revisits.get(id);
359
+ if (!starts || Number.isNaN(cursor)) {
360
+ return spanStart[id];
361
+ }
362
+ const len = lengthOf(id);
363
+ let best = starts[0];
364
+ let bestGap = Infinity;
365
+ for (const start2 of starts) {
366
+ const gap = Math.min(
367
+ Math.abs(start2 - cursor),
368
+ Math.abs(start2 + len - cursor)
369
+ );
370
+ if (gap < bestGap) {
371
+ best = start2;
372
+ bestGap = gap;
373
+ }
374
+ }
375
+ return best;
376
+ };
348
377
  const [, runBp, runRef, runFlags] = runs.values;
349
378
  for (let k = lo; k < hi; k++) {
350
379
  const index = backward ? hi - 1 - (k - lo) : k;
@@ -369,12 +398,12 @@ function walkRowRuns(source, region, o = {}) {
369
398
  continue;
370
399
  }
371
400
  const len = lengthOf(id);
372
- const at = spanStart[id];
401
+ const at = placeOf(id);
373
402
  const on = !Number.isNaN(at);
374
403
  visits?.push(id, bp2, len, on ? 1 : 0);
375
404
  const placed = last >= 0 && !Number.isNaN(lastRef);
376
405
  const forward = on && placed && step >= 0 && lastRef + (runBp[last] ?? 0) === at;
377
- const back = on && placed && step <= 0 && spanEnd[id] === lastRef;
406
+ const back = on && placed && step <= 0 && at + len === lastRef;
378
407
  if (!on && last >= 0 && !(lastFlags & (RUN_ON_REFERENCE | RUN_GAP))) {
379
408
  runBp[last] += len;
380
409
  } else if (forward || back) {
@@ -394,7 +423,9 @@ function walkRowRuns(source, region, o = {}) {
394
423
  step = 0;
395
424
  }
396
425
  bp2 += len;
397
- if (!on) {
426
+ if (on) {
427
+ cursor = step < 0 ? at : at + len;
428
+ } else {
398
429
  offReferenceBp += len;
399
430
  }
400
431
  }
@@ -1,9 +1,12 @@
1
+ import {
2
+ referenceVisitStarts
3
+ } from "./chunk-3YBP46PB.js";
1
4
  import {
2
5
  computeEdgeCurves,
3
6
  edgeJoinOf,
4
7
  routedEdgeCurves,
5
8
  strandSides
6
- } from "./chunk-UBQSRCWR.js";
9
+ } from "./chunk-VACK24HF.js";
7
10
  import {
8
11
  groupBy
9
12
  } from "./chunk-BSOZW3FC.js";
@@ -11,6 +14,9 @@ import {
11
14
  firstNodeAtOrAfter,
12
15
  isBackbone
13
16
  } from "./chunk-RJWPJCIB.js";
17
+ import {
18
+ partitionPoint
19
+ } from "./chunk-HOAIOEI7.js";
14
20
 
15
21
  // src/deletionEdges.ts
16
22
  var MIN_DELETION_BP = 1;
@@ -70,22 +76,63 @@ function skipsBetween(edge, from, to, forwards) {
70
76
  const arrivesLeft = toStrand === (to.stable.strand ?? "+");
71
77
  return forwards ? leavesRight && arrivesLeft : !leavesRight && !arrivesLeft;
72
78
  }
79
+ function skippedSpan(edge, from, to, startsOf) {
80
+ let best;
81
+ for (const a of startsOf(from)) {
82
+ for (const b of startsOf(to)) {
83
+ const forwards = a <= b;
84
+ const span = forwards ? { start: a + from.length, end: b } : { start: b + to.length, end: a };
85
+ if (skipsBetween(edge, from, to, forwards) && (!best || Math.abs(span.end - span.start) < Math.abs(best.end - best.start))) {
86
+ best = span;
87
+ }
88
+ }
89
+ }
90
+ return best;
91
+ }
92
+ var COPY_SWITCH_SHARE = 0.01;
93
+ function repeatCopies(backbone, startsOf) {
94
+ const bySequence = /* @__PURE__ */ new Map();
95
+ for (const [refName, nodes] of backbone) {
96
+ const copies = nodes.flatMap((node) => {
97
+ const starts = startsOf(node);
98
+ return starts.slice(1).map((next, i) => ({
99
+ at: starts[i],
100
+ copy: next - starts[i]
101
+ }));
102
+ });
103
+ if (copies.length) {
104
+ bySequence.set(
105
+ refName,
106
+ copies.sort((a, b) => a.at - b.at)
107
+ );
108
+ }
109
+ }
110
+ return bySequence;
111
+ }
112
+ function switchesCopy(copies, start, bp) {
113
+ if (!copies) {
114
+ return false;
115
+ }
116
+ const i = partitionPoint(copies.length, (k) => copies[k].at < start);
117
+ const near = [copies[i - 1], copies[i]].filter((c) => c !== void 0).sort((a, b) => Math.abs(a.at - start) - Math.abs(b.at - start))[0];
118
+ return near !== void 0 && Math.abs(near.at - start) <= near.copy && Math.abs(bp - near.copy) <= near.copy * COPY_SWITCH_SHARE;
119
+ }
73
120
  function deletionEdges(graph) {
74
121
  const byId = new Map(graph.nodes.map((n) => [n.id, n]));
75
122
  const backbone = backboneBySequence(graph);
123
+ const startsOf = referenceVisitStarts(graph);
124
+ const copies = repeatCopies(backbone, startsOf);
76
125
  const found = [];
77
126
  for (let edgeIndex = 0; edgeIndex < graph.edges.length; edgeIndex++) {
78
127
  const edge = graph.edges[edgeIndex];
79
128
  const from = byId.get(edge.from);
80
129
  const to = byId.get(edge.to);
81
130
  if (from !== void 0 && to !== void 0 && isBackbone(from) && isBackbone(to) && from.stable.refName === to.stable.refName) {
82
- const forwards = from.stable.start <= to.stable.start;
83
- const [left, right] = forwards ? [from, to] : [to, from];
84
- const start = left.stable.start + left.length;
85
- const end = right.stable.start;
86
- const bp = end - start;
87
- if (bp >= MIN_DELETION_BP && skipsBetween(edge, from, to, forwards)) {
88
- const refName = left.stable.refName;
131
+ const span = skippedSpan(edge, from, to, startsOf);
132
+ const refName = from.stable.refName;
133
+ const bp = span ? span.end - span.start : 0;
134
+ if (span && bp >= MIN_DELETION_BP && !switchesCopy(copies.get(refName), span.start, bp)) {
135
+ const { start, end } = span;
89
136
  found.push({
90
137
  edgeIndex,
91
138
  from: edge.from,
@@ -136,13 +136,14 @@ function mergeOverlappingByName(genes) {
136
136
  }
137
137
  return out;
138
138
  }
139
+ var BED_HEADER = /^(#|track\s|browser\s)/;
139
140
  function genesFromBed(text) {
140
141
  const rows = [];
141
142
  for (const line of text.split("\n")) {
142
143
  const cols = line.replace(/\r$/, "").split(" ");
143
144
  const start = Number(cols[1]);
144
145
  const end = Number(cols[2]);
145
- if (/^(#|track|browser)/.test(line) || cols.length < 3 || !Number.isInteger(start) || !(end > start)) {
146
+ if (BED_HEADER.test(line) || cols.length < 3 || !Number.isInteger(start) || !(end > start)) {
146
147
  continue;
147
148
  }
148
149
  const refName = cols[0];
@@ -165,7 +166,7 @@ function genesFromBed(text) {
165
166
  return mergeOverlappingByName(rows);
166
167
  }
167
168
  function sniffedFormat(text) {
168
- const first = text.split("\n", 1e3).find((l) => l.trim() !== "" && !/^(#|track|browser)/.test(l));
169
+ const first = text.split("\n", 1e3).find((l) => l.trim() !== "" && !BED_HEADER.test(l));
169
170
  const cols = first?.split(" ") ?? [];
170
171
  return /^\d+$/.test(cols[1] ?? "") && /^\d+$/.test(cols[2] ?? "") ? "bed" : "gff3";
171
172
  }
@@ -1,24 +1,25 @@
1
1
  import {
2
2
  encodedColor,
3
3
  resolveEncoding
4
- } from "./chunk-HN3WHMPJ.js";
4
+ } from "./chunk-2XEAITWM.js";
5
5
  import {
6
6
  rampFraction
7
- } from "./chunk-JOWKKQAL.js";
8
- import {
9
- pathOrigin
10
- } from "./chunk-B5X2RLJG.js";
7
+ } from "./chunk-JGHZ3N34.js";
11
8
  import {
12
9
  gapParts
13
10
  } from "./chunk-EIY2SKD3.js";
11
+ import {
12
+ pathOrigin
13
+ } from "./chunk-3YBP46PB.js";
14
14
  import {
15
15
  panSNContig
16
- } from "./chunk-4XWZNPQ2.js";
16
+ } from "./chunk-2JL2JVZ2.js";
17
17
 
18
18
  // src/walkHighlight.ts
19
19
  var isReference = (graph, name) => !!graph.referencePath && pathOrigin(name).name === graph.referencePath;
20
20
  function piecesOf(graph, name) {
21
- return (graph.paths ?? []).filter((p) => p.name === name).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
21
+ const origin = pathOrigin(name).name;
22
+ return (graph.paths ?? []).filter((p) => pathOrigin(p.name).name === origin).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
22
23
  }
23
24
  var nodesById = (graph) => new Map(graph.nodes.map((n) => [n.id, n]));
24
25
  function graphIndex(graph) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  engineKey,
3
3
  forceLayout
4
- } from "./chunk-WG5D2H7X.js";
4
+ } from "./chunk-7OTWJQGA.js";
5
5
 
6
6
  // src/layout/forceCache.ts
7
7
  var DEFAULT_SIZE = 4;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tubeSpan
3
- } from "./chunk-HSVFCA2J.js";
3
+ } from "./chunk-VO6FKNZE.js";
4
4
 
5
5
  // src/tubeMap/genes.ts
6
6
  function tubeMapGenes(byRefName, genes) {
@@ -6,13 +6,13 @@ import {
6
6
  } from "./chunk-MYDHU2UV.js";
7
7
  import {
8
8
  readColor
9
- } from "./chunk-A7H753BA.js";
9
+ } from "./chunk-SDI6BVG7.js";
10
10
  import {
11
11
  referenceWalkName
12
- } from "./chunk-64FCX424.js";
12
+ } from "./chunk-D3E7AXBB.js";
13
13
  import {
14
14
  pathOrigin
15
- } from "./chunk-B5X2RLJG.js";
15
+ } from "./chunk-3YBP46PB.js";
16
16
  import {
17
17
  pushTo
18
18
  } from "./chunk-BSOZW3FC.js";
@@ -10,17 +10,18 @@ import {
10
10
  } from "./chunk-GQZVR5DW.js";
11
11
  import {
12
12
  baseEdgeCurves
13
- } from "./chunk-WA5WNP6V.js";
13
+ } from "./chunk-OYCQVJYY.js";
14
14
  import {
15
15
  PATH_LIGHTNESS,
16
16
  PATH_SATURATION,
17
17
  nameHue,
18
18
  pathHueAt
19
- } from "./chunk-3GP3KT5L.js";
19
+ } from "./chunk-BW2NMXRV.js";
20
20
  import {
21
21
  meanDepth,
22
- nodeWidthPx
23
- } from "./chunk-CRCD3ODN.js";
22
+ nodeWidthPx,
23
+ walkLaneWidthPx
24
+ } from "./chunk-ZANALBSX.js";
24
25
  import {
25
26
  referenceMidpoints
26
27
  } from "./chunk-VX656OAZ.js";
@@ -31,7 +32,7 @@ import {
31
32
  strandSides,
32
33
  translateCurves,
33
34
  yToXOf
34
- } from "./chunk-UBQSRCWR.js";
35
+ } from "./chunk-VACK24HF.js";
35
36
  import {
36
37
  pushTo
37
38
  } from "./chunk-BSOZW3FC.js";
@@ -51,7 +52,6 @@ var LIFT_BACKDROP_CSS = abgrToCssRgba(
51
52
  );
52
53
  var DELETION_DASH_PX = 11;
53
54
  var MIN_PATH_STRIPE_PX = 1.2;
54
- var MIN_WALK_LANE_PX = 4;
55
55
  var MIN_SCALE_FOR_OFFSET = 1e-6;
56
56
  var ARROW_LENGTH_BASE_PX = 7;
57
57
  var ARROW_LENGTH_PER_EDGE_PX = 3;
@@ -518,7 +518,12 @@ function buildGeometry(options) {
518
518
  const inView = (curves) => !viewportBounds || isBezierInBounds(curves, viewportBounds);
519
519
  const stroke = (curves, thickness, color) => {
520
520
  if (isDeletion) {
521
- for (const dash of dashCurves(curves, DELETION_DASH_PX / scale)) {
521
+ for (const dash of dashCurves(
522
+ curves,
523
+ DELETION_DASH_PX / scale,
524
+ yToX,
525
+ viewportBounds
526
+ )) {
522
527
  edgeCurves.push({ curves: dash, thickness, color });
523
528
  }
524
529
  } else {
@@ -546,7 +551,7 @@ function buildGeometry(options) {
546
551
  if (laneWalks) {
547
552
  const fromNode = nodeById.get(edge.from);
548
553
  const width = fromNode ? nodeWidthPx(fromNode, contigThickness, nodeWidth, depthNorm) : contigThickness;
549
- const laneWidth = Math.max(width / laneWalks.length, MIN_WALK_LANE_PX);
554
+ const laneWidth = walkLaneWidthPx(width, laneWalks.length);
550
555
  const normals = pointNormalsOf(fromSegments, yToX);
551
556
  const { nx, ny } = (leavesStart(
552
557
  edge,
@@ -638,7 +643,7 @@ function buildGeometry(options) {
638
643
  const drawable = segments.length >= 2;
639
644
  const lanes = highlight?.walks.length && !faded && !slots?.length ? highlight.walks : void 0;
640
645
  if (drawable && lanes) {
641
- const laneWidth = Math.max(width / lanes.length, MIN_WALK_LANE_PX);
646
+ const laneWidth = walkLaneWidthPx(width, lanes.length);
642
647
  const normals = pointNormalsOf(segments, yToX);
643
648
  lanes.forEach((walk, lane) => {
644
649
  const laneColor = walk.colors.get(nodeId);
@@ -5,13 +5,13 @@ import {
5
5
  import {
6
6
  formatBp,
7
7
  groupDigits
8
- } from "./chunk-PFRQBCGC.js";
8
+ } from "./chunk-T3H5ELLA.js";
9
9
 
10
10
  // src/walkKey.ts
11
11
  function rangeText(contig, start, end) {
12
12
  const s = Math.round(start);
13
13
  const e = Math.round(end);
14
- return `${contig ? `${contig}:` : ""}${groupDigits(s)}-${groupDigits(e)} (${formatBp(e - s)})`;
14
+ return `${contig ? `${contig}:` : ""}${groupDigits(s + 1)}-${groupDigits(e)} (${formatBp(e - s)})`;
15
15
  }
16
16
  function walkKey(walk, reference) {
17
17
  const { field } = walk.encoding;
@@ -42,7 +42,7 @@ function walkPosition(walk, nodeId, length) {
42
42
  const start = Math.round(
43
43
  range.start + progress * (range.end - range.start) - length / 2
44
44
  );
45
- return `${range.contig}:${groupDigits(start)}-${groupDigits(start + length)}`;
45
+ return `${range.contig}:${groupDigits(start + 1)}-${groupDigits(start + length)}`;
46
46
  }
47
47
 
48
48
  export {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  nodesUnderBox
3
- } from "./chunk-OMUPUB4J.js";
3
+ } from "./chunk-56L6R6D2.js";
4
4
  import {
5
5
  graphLabels,
6
6
  rowLabelBox
7
- } from "./chunk-PFRQBCGC.js";
7
+ } from "./chunk-T3H5ELLA.js";
8
8
  import {
9
9
  LABEL_CHAR_PX,
10
10
  LABEL_PAD,
@@ -25,7 +25,7 @@ function geneCoverageNote(pin) {
25
25
  if (pin.covered >= 0.98) {
26
26
  return void 0;
27
27
  }
28
- const [per, unit] = length >= 1e6 ? [1e6, "Mb"] : length >= 1e3 ? [1e3, "kb"] : [1, "bp"];
28
+ const [per, unit] = length >= 999500 ? [1e6, "Mb"] : length >= 1e3 ? [1e3, "kb"] : [1, "bp"];
29
29
  const amount = (bp) => +(bp / per).toFixed(per === 1 ? 0 : 1);
30
30
  return `${amount(pin.covered * length)} of ${amount(length)} ${unit}`;
31
31
  }
@@ -114,7 +114,7 @@ function layoutLabels(m) {
114
114
  frame,
115
115
  take
116
116
  );
117
- const ticks = m.bubbleHalos.filter((h) => h.tick && !h.whole).map((h) => ({ item: h, ...above(h, 2) })).filter((t) => t.x >= 0 && t.x <= width && t.y >= 0 && t.y <= height);
117
+ const ticks = m.bubbleHalos.filter((h) => h.tick).map((h) => ({ item: h, ...above(h, 2) })).filter((t) => t.x >= 0 && t.x <= width && t.y >= 0 && t.y <= height);
118
118
  const genes = placeLabels(
119
119
  geneLabelCandidates(
120
120
  m.genePins,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ownStrand
3
- } from "./chunk-UBQSRCWR.js";
3
+ } from "./chunk-VACK24HF.js";
4
4
  import {
5
5
  groupBy
6
6
  } from "./chunk-BSOZW3FC.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  bubbleSegmentIds,
3
3
  classifyBubble
4
- } from "./chunk-A4JDEUAI.js";
4
+ } from "./chunk-SNF2MIEF.js";
5
5
  import {
6
6
  svgPath
7
- } from "./chunk-UBQSRCWR.js";
7
+ } from "./chunk-VACK24HF.js";
8
8
  import {
9
9
  isBackbone
10
10
  } from "./chunk-RJWPJCIB.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  walkRowRuns,
3
3
  walkRowsOf
4
- } from "./chunk-64FCX424.js";
4
+ } from "./chunk-D3E7AXBB.js";
5
5
 
6
6
  // src/layout/walkRows.ts
7
7
  function filterSamples(rows, samples) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  trimOrigins
3
- } from "./chunk-B5X2RLJG.js";
3
+ } from "./chunk-3YBP46PB.js";
4
4
 
5
5
  // src/bubbles/popBubble.ts
6
6
  function bubbleSubgraph(graph, segmentIds) {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-H2H4Y3TV.js";
4
4
  import {
5
5
  REFERENCE_RAMP_ALT_CSS
6
- } from "./chunk-JOWKKQAL.js";
6
+ } from "./chunk-JGHZ3N34.js";
7
7
  import {
8
8
  RAMP_GRADIENT_CSS,
9
9
  RAMP_GRADIENT_STOPS,
@@ -22,7 +22,7 @@ import {
22
22
  } from "./chunk-CPMHA4W5.js";
23
23
  import {
24
24
  panSNContig
25
- } from "./chunk-4XWZNPQ2.js";
25
+ } from "./chunk-2JL2JVZ2.js";
26
26
 
27
27
  // src/layout/walkRowDraw.ts
28
28
  var ON_REFERENCE = "#2f8fd6";
@@ -49,10 +49,10 @@ function units(bp, unit) {
49
49
  }
50
50
  var near = ({ refName, start }) => `${panSNContig(refName)}:${start < 1e6 ? `${Math.round(start / 1e3)} kb` : `${(start / 1e6).toFixed(1)} Mb`}`;
51
51
  function gapsText(gapBp, runs) {
52
- const gaps = (runs ?? []).filter((r) => r.gap);
53
52
  if (gapBp <= 0) {
54
53
  return "";
55
54
  }
55
+ const gaps = (runs ?? []).filter((r) => r.gap);
56
56
  if (!gaps.some((g) => g.cause)) {
57
57
  return ` \xB7 ${kb(gapBp)} ${OUTSIDE_TEXT}`;
58
58
  }
@@ -477,14 +477,15 @@ function walkRowsTree(bars, frame, o = {}) {
477
477
  })
478
478
  ) : [];
479
479
  const { call } = row;
480
- const text = walkRowReadout(
481
- row,
482
- i === 0 ? void 0 : reference,
483
- unit,
484
- call
485
- );
486
- const at = readoutPlacement(text, along(row.bp), frame.width);
487
- const readouts = frame.readouts ?? true;
480
+ const readout = frame.readouts ?? true ? {
481
+ text: walkRowReadout(
482
+ row,
483
+ i === 0 ? void 0 : reference,
484
+ unit,
485
+ call
486
+ )
487
+ } : void 0;
488
+ const at = readout && readoutPlacement(readout.text, along(row.bp), frame.width);
488
489
  return el(
489
490
  "g",
490
491
  {
@@ -504,7 +505,7 @@ function walkRowsTree(bars, frame, o = {}) {
504
505
  height: barPx + 2 * overhang,
505
506
  fill: callTickInk(call)
506
507
  }),
507
- readouts && el(
508
+ readout && at && el(
508
509
  "text",
509
510
  {
510
511
  x: at.x,
@@ -517,7 +518,7 @@ function walkRowsTree(bars, frame, o = {}) {
517
518
  "paint-order": "stroke",
518
519
  "text-anchor": at.anchor
519
520
  },
520
- text
521
+ readout.text
521
522
  )
522
523
  );
523
524
  };