@jbrowse/bandage-core 10.2.2 → 10.2.4

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 (140) hide show
  1. package/README.md +8 -7
  2. package/dist/bubbles/bubbleHalos.js +7 -3
  3. package/dist/bubbles/bubblesFromGraph.js +4 -2
  4. package/dist/bubbles/classifyBubble.js +10 -5
  5. package/dist/bubbles/superbubbles.js +10 -6
  6. package/dist/chunks/{chunk-N6FECAXP.js → chunk-24WITXQY.js} +17 -8
  7. package/dist/chunks/{chunk-EYK7DJZV.js → chunk-2CHS5LMM.js} +1 -1
  8. package/dist/chunks/{chunk-XTCNEKO5.js → chunk-2QLLQJ72.js} +15 -13
  9. package/dist/chunks/{chunk-TWRLC3KK.js → chunk-3XSM4OZU.js} +1 -1
  10. package/dist/chunks/{chunk-WEDZ76AK.js → chunk-4DRQTBBE.js} +1 -1
  11. package/dist/chunks/{chunk-2LQ5BWT7.js → chunk-4ETPXDO6.js} +1 -1
  12. package/dist/chunks/{chunk-FP4H7SFT.js → chunk-4HWM3FNK.js} +2 -2
  13. package/dist/chunks/{chunk-C7MZJSPT.js → chunk-54POIBVC.js} +2 -8
  14. package/dist/chunks/{chunk-PKFMP65V.js → chunk-5GMFEPWR.js} +1 -1
  15. package/dist/chunks/{chunk-CDLPYR5O.js → chunk-5I3K4R2G.js} +7 -6
  16. package/dist/chunks/{chunk-2CVHXFK7.js → chunk-7SRWJLSC.js} +19 -22
  17. package/dist/chunks/{chunk-SBMJNRTV.js → chunk-A4PFFC4Q.js} +37 -27
  18. package/dist/chunks/{chunk-FNGIQF43.js → chunk-ABUIN5AK.js} +6 -14
  19. package/dist/chunks/{chunk-IW6CYVX2.js → chunk-AR4BUBMU.js} +6 -1
  20. package/dist/chunks/{chunk-IUDJKOLB.js → chunk-B6IW3IRE.js} +15 -33
  21. package/dist/chunks/{chunk-JUIJI7RC.js → chunk-BAETMD3J.js} +9 -4
  22. package/dist/chunks/{chunk-L5WF4ZPS.js → chunk-BS4UZ44I.js} +1 -1
  23. package/dist/chunks/{chunk-HNQPEMYE.js → chunk-CM6LO6OC.js} +0 -1
  24. package/dist/chunks/{chunk-CLOP7UVD.js → chunk-CQHUZHET.js} +11 -8
  25. package/dist/chunks/{chunk-R456ME6J.js → chunk-CU6P5RUG.js} +17 -6
  26. package/dist/chunks/chunk-D5D36ZF6.js +107 -0
  27. package/dist/chunks/{chunk-AFP3NWSL.js → chunk-DY3JCAMX.js} +1 -1
  28. package/dist/chunks/{chunk-NRV7R36Q.js → chunk-EFQLEGWM.js} +3 -3
  29. package/dist/chunks/{chunk-BXEPA4KS.js → chunk-G6UIYQZR.js} +5 -2
  30. package/dist/chunks/{chunk-ASSNZXCF.js → chunk-GINYTQ43.js} +44 -103
  31. package/dist/chunks/{chunk-NNODIW4U.js → chunk-H2H4Y3TV.js} +1 -0
  32. package/dist/chunks/{chunk-MVFDSFV2.js → chunk-HNCXR2VS.js} +1 -1
  33. package/dist/chunks/chunk-JA2HJIYS.js +71 -0
  34. package/dist/chunks/{chunk-PBENCR5L.js → chunk-JBCZIBFC.js} +0 -2
  35. package/dist/chunks/{chunk-5BGP5Z64.js → chunk-JLSJMCDJ.js} +1 -1
  36. package/dist/chunks/{chunk-DT2GGH4D.js → chunk-JMABOQWL.js} +2 -6
  37. package/dist/chunks/{chunk-3S3YVOJ7.js → chunk-JSUCGZ6K.js} +1 -1
  38. package/dist/chunks/{chunk-MLSWIMZO.js → chunk-KBEP7VYK.js} +2 -2
  39. package/dist/chunks/{chunk-DRG4236Y.js → chunk-KC7T5RWG.js} +2 -20
  40. package/dist/chunks/{chunk-TAMCZHLW.js → chunk-N73TI3VG.js} +2 -2
  41. package/dist/chunks/chunk-O4EGE27I.js +10 -0
  42. package/dist/chunks/{chunk-3ZZSX5HN.js → chunk-PTABFYQ7.js} +10 -6
  43. package/dist/chunks/{chunk-WBCOREDZ.js → chunk-QLWI2PZ3.js} +16 -7
  44. package/dist/chunks/chunk-RBCE2OQH.js +32 -0
  45. package/dist/chunks/{chunk-BUBZ32IC.js → chunk-RPRHR56C.js} +4 -8
  46. package/dist/chunks/{chunk-47DYCZOK.js → chunk-RUCH6ZFL.js} +4 -0
  47. package/dist/chunks/{chunk-GNTTI6LA.js → chunk-T2PCSAFY.js} +1 -1
  48. package/dist/chunks/{chunk-XKWD2RY3.js → chunk-URZ3CH2R.js} +3 -10
  49. package/dist/chunks/{chunk-ALDGONEI.js → chunk-VQC7KELB.js} +1 -1
  50. package/dist/chunks/{chunk-FLFBYSJO.js → chunk-VQWHMWLF.js} +5 -1
  51. package/dist/chunks/{chunk-4R6QNG23.js → chunk-WL6ZKUVC.js} +3 -3
  52. package/dist/chunks/{chunk-CRTD2SBP.js → chunk-WZNPX7Q6.js} +6 -2
  53. package/dist/chunks/{chunk-TICYLD5F.js → chunk-XAWLIU54.js} +35 -78
  54. package/dist/chunks/{chunk-DK5P2YOL.js → chunk-XI3ZUTWF.js} +2 -2
  55. package/dist/chunks/{chunk-ZIUKZUPJ.js → chunk-XL472HHD.js} +1 -1
  56. package/dist/chunks/{chunk-BPRXQ2SS.js → chunk-XMW266WS.js} +1 -1
  57. package/dist/chunks/{chunk-WFB5TXRA.js → chunk-ZY2AFL4Y.js} +13 -31
  58. package/dist/cli/decodeText.js +6 -0
  59. package/dist/cli/figure.js +59 -60
  60. package/dist/cli/fold.js +13 -13
  61. package/dist/deletionEdges.js +6 -4
  62. package/dist/el.js +3 -1
  63. package/dist/figure.js +33 -31
  64. package/dist/figureData.js +32 -27
  65. package/dist/figureScene.js +43 -0
  66. package/dist/figureSettings.js +8 -8
  67. package/dist/foldVariants.js +2 -2
  68. package/dist/gbzCut.js +1 -1
  69. package/dist/genes/exonOutline.js +2 -2
  70. package/dist/genes/geneFiles.js +1 -1
  71. package/dist/genes/genePins.js +3 -3
  72. package/dist/gfa/gfaConverter.js +2 -2
  73. package/dist/gfa-core/gfaParser.js +1 -1
  74. package/dist/gfa-core/index.js +1 -1
  75. package/dist/graphLabels.js +4 -4
  76. package/dist/index.js +72 -73
  77. package/dist/labelLayout.js +8 -8
  78. package/dist/layout/forceCache.js +8 -8
  79. package/dist/layout/mergeRuns.js +2 -2
  80. package/dist/layout/orderedLayout.js +1 -3
  81. package/dist/layout/tubeMapLayout.js +6 -6
  82. package/dist/layout/walkRowDraw.js +11 -11
  83. package/dist/layout/walkRowLayout.js +3 -1
  84. package/dist/layout/walkStrip.js +14 -12
  85. package/dist/layoutEngines.js +1 -2
  86. package/dist/layoutModes.js +9 -9
  87. package/dist/nodeWidths.js +1 -3
  88. package/dist/pathColors.js +5 -5
  89. package/dist/pipeline.js +7 -7
  90. package/dist/referenceRampCss.js +9 -9
  91. package/dist/referenceStrip.js +9 -9
  92. package/dist/renderer/Canvas2DRenderer.js +2 -2
  93. package/dist/renderer/GeometryBuilder.js +8 -8
  94. package/dist/renderer/canvas.js +1 -1
  95. package/dist/renderer/svgCanvas.js +1 -1
  96. package/dist/tubeMap/axis.js +5 -5
  97. package/dist/tubeMap/bundle.js +7 -7
  98. package/dist/tubeMap/coarsen.js +6 -6
  99. package/dist/tubeMap/deviations.js +5 -5
  100. package/dist/tubeMap/draw.js +1 -1
  101. package/dist/tubeMap/genes.js +6 -6
  102. package/dist/tubeMap/nodeColors.js +9 -9
  103. package/dist/types/bubbles/bubbleHalos.d.ts +2 -8
  104. package/dist/types/bubbles/bubblesFromGraph.d.ts +1 -0
  105. package/dist/types/bubbles/classifyBubble.d.ts +0 -1
  106. package/dist/types/cli/decodeText.d.ts +1 -0
  107. package/dist/types/cli/figure.d.ts +4 -15
  108. package/dist/types/deletionEdges.d.ts +3 -5
  109. package/dist/types/el.d.ts +1 -0
  110. package/dist/types/figureData.d.ts +7 -26
  111. package/dist/types/figureScene.d.ts +31 -0
  112. package/dist/types/genes/geneFiles.d.ts +2 -1
  113. package/dist/types/index.d.ts +1 -1
  114. package/dist/types/labelLayout.d.ts +1 -5
  115. package/dist/types/layout/deletionRoutes.d.ts +1 -1
  116. package/dist/types/layout/orderedLayout.d.ts +0 -6
  117. package/dist/types/layout/walkRowLayout.d.ts +1 -0
  118. package/dist/types/nodeWidths.d.ts +0 -1
  119. package/dist/types/renderer/Canvas2DRenderer.d.ts +1 -0
  120. package/dist/types/renderer/canvas.d.ts +2 -2
  121. package/dist/types/tubeMap/draw.d.ts +1 -0
  122. package/dist/types/util/geometry.d.ts +3 -3
  123. package/dist/types/version.d.ts +1 -1
  124. package/dist/util/SpatialIndex.js +4 -4
  125. package/dist/util/edgeCurves.js +3 -3
  126. package/dist/util/geometry.js +3 -3
  127. package/dist/util/hitDetection.js +5 -5
  128. package/dist/version.js +1 -1
  129. package/dist/viewport.js +8 -8
  130. package/dist/walkEncoding.js +9 -9
  131. package/dist/walkHighlight.js +10 -10
  132. package/dist/walkKey.js +5 -5
  133. package/package.json +3 -6
  134. package/dist/chunks/bandage-layout-3AR6BCUD.js +0 -4694
  135. package/dist/chunks/chunk-4BYTEJGW.js +0 -44
  136. package/dist/chunks/chunk-7XHHVYG7.js +0 -13
  137. package/dist/chunks/chunk-EHUBJDDB.js +0 -135
  138. package/dist/loadBandage.js +0 -6
  139. package/dist/types/bandage/bandage-layout.d.ts +0 -14
  140. package/dist/types/loadBandage.d.ts +0 -3
package/README.md CHANGED
@@ -10,8 +10,10 @@ npm install @jbrowse/bandage-core
10
10
 
11
11
  - GFA and rGFA text in (`loadGraph`), or the same graph as typed arrays a worker
12
12
  can transfer (`GraphTables`)
13
- - Layouts: Bandage's FMMM engine as WASM (`loadBandage`, `forceLayout`),
14
- ordered, anchored, sample rows, walk rows, tube map
13
+ - Layouts: Bandage's FMMM engine as WASM from
14
+ [@jbrowse/graph-fmmm-layout](https://github.com/GMOD/graph-fmmm-layout)
15
+ (`loadBandage`, `forceLayout`), ordered, anchored, sample rows, walk rows,
16
+ tube map
15
17
  - A Canvas2D renderer (`buildGeometry`, `Canvas2DRenderer`), hit testing and
16
18
  label placement
17
19
  - Bubbles, deletion edges, path colors, gbz-base windows cut to GFA
@@ -42,13 +44,10 @@ the worked example.
42
44
  pnpm install
43
45
  pnpm test # unit tests
44
46
  pnpm build # dist/ with declarations
45
- pnpm test:wasm # the committed layout engine still loads
46
47
  ```
47
48
 
48
- The Bandage layout engine is OGDF's FMMM compiled to WASM and committed at
49
- `src/bandage/bandage-layout.js`; [src/bandage/README.md](src/bandage/README.md)
50
- says how to rebuild it from `src/bandage/native` and the vendored `vendor/ogdf`.
51
- A weekly workflow proves the committed artifact still reproduces.
49
+ The FMMM engine and its wasm build live in
50
+ [graph-fmmm-layout](https://github.com/GMOD/graph-fmmm-layout).
52
51
 
53
52
  CI also packs the core and runs
54
53
  [BandageJS](https://github.com/cmdcolin/BandageJS) and
@@ -66,6 +65,8 @@ publishes to npm with trusted publishing.
66
65
  JBrowse 2 plugin that browses these graphs by locus
67
66
  - [BandageJS](https://github.com/cmdcolin/BandageJS) - standalone page for GFA
68
67
  and gbz-base graphs
68
+ - [@jbrowse/graph-fmmm-layout](https://github.com/GMOD/graph-fmmm-layout) -
69
+ Bandage's FMMM layout as wasm
69
70
  - [@jbrowse/graph-stress-layout](https://github.com/GMOD/graph-stress-layout) -
70
71
  stress layout that keeps the reference straight
71
72
  - [@gmod/gbz-base](https://github.com/GMOD/gbz-base-js) - range-request reader
@@ -3,10 +3,14 @@ import {
3
3
  WHOLE_FRACTION,
4
4
  bubbleHalos,
5
5
  coversGraph
6
- } from "../chunks/chunk-EHUBJDDB.js";
7
- import "../chunks/chunk-XKWD2RY3.js";
6
+ } from "../chunks/chunk-JA2HJIYS.js";
7
+ import "../chunks/chunk-URZ3CH2R.js";
8
8
  import "../chunks/chunk-FX4RDMDN.js";
9
- import "../chunks/chunk-2CVHXFK7.js";
9
+ import "../chunks/chunk-PTABFYQ7.js";
10
+ import "../chunks/chunk-AB35TJST.js";
11
+ import "../chunks/chunk-N73TI3VG.js";
12
+ import "../chunks/chunk-24WITXQY.js";
13
+ import "../chunks/chunk-7SRWJLSC.js";
10
14
  import "../chunks/chunk-CPMHA4W5.js";
11
15
  import "../chunks/chunk-FYQWPEEY.js";
12
16
  export {
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  bubblesFromGraph,
3
+ relax,
3
4
  walkIndexOf,
4
5
  walkRoutes
5
- } from "../chunks/chunk-CLOP7UVD.js";
6
+ } from "../chunks/chunk-CQHUZHET.js";
6
7
  import "../chunks/chunk-FX4RDMDN.js";
7
- import "../chunks/chunk-HNQPEMYE.js";
8
+ import "../chunks/chunk-CM6LO6OC.js";
8
9
  import "../chunks/chunk-CPMHA4W5.js";
9
10
  import "../chunks/chunk-FYQWPEEY.js";
10
11
  export {
11
12
  bubblesFromGraph,
13
+ relax,
12
14
  walkIndexOf,
13
15
  walkRoutes
14
16
  };
@@ -2,14 +2,19 @@ import {
2
2
  BUBBLE_KIND_COLORS,
3
3
  BUBBLE_KIND_NAMES,
4
4
  bubbleSegmentIds,
5
- classifyBubble,
6
- formatBp
7
- } from "../chunks/chunk-XKWD2RY3.js";
5
+ classifyBubble
6
+ } from "../chunks/chunk-URZ3CH2R.js";
8
7
  import "../chunks/chunk-FX4RDMDN.js";
8
+ import "../chunks/chunk-PTABFYQ7.js";
9
+ import "../chunks/chunk-AB35TJST.js";
10
+ import "../chunks/chunk-N73TI3VG.js";
11
+ import "../chunks/chunk-24WITXQY.js";
12
+ import "../chunks/chunk-7SRWJLSC.js";
13
+ import "../chunks/chunk-CPMHA4W5.js";
14
+ import "../chunks/chunk-FYQWPEEY.js";
9
15
  export {
10
16
  BUBBLE_KIND_COLORS,
11
17
  BUBBLE_KIND_NAMES,
12
18
  bubbleSegmentIds,
13
- classifyBubble,
14
- formatBp
19
+ classifyBubble
15
20
  };
@@ -1,17 +1,21 @@
1
1
  import {
2
2
  graphBubbles,
3
3
  superbubblesFromGraph
4
- } from "../chunks/chunk-FNGIQF43.js";
5
- import "../chunks/chunk-CLOP7UVD.js";
4
+ } from "../chunks/chunk-ABUIN5AK.js";
5
+ import "../chunks/chunk-CQHUZHET.js";
6
6
  import "../chunks/chunk-T6V4KI2L.js";
7
- import "../chunks/chunk-EHUBJDDB.js";
8
- import "../chunks/chunk-XKWD2RY3.js";
7
+ import "../chunks/chunk-JA2HJIYS.js";
8
+ import "../chunks/chunk-URZ3CH2R.js";
9
9
  import "../chunks/chunk-FX4RDMDN.js";
10
- import "../chunks/chunk-HNQPEMYE.js";
10
+ import "../chunks/chunk-CM6LO6OC.js";
11
11
  import "../chunks/chunk-M6LK4GII.js";
12
12
  import "../chunks/chunk-RAEABQNW.js";
13
13
  import "../chunks/chunk-BPLIXMH7.js";
14
- import "../chunks/chunk-2CVHXFK7.js";
14
+ import "../chunks/chunk-PTABFYQ7.js";
15
+ import "../chunks/chunk-AB35TJST.js";
16
+ import "../chunks/chunk-N73TI3VG.js";
17
+ import "../chunks/chunk-24WITXQY.js";
18
+ import "../chunks/chunk-7SRWJLSC.js";
15
19
  import "../chunks/chunk-CPMHA4W5.js";
16
20
  import "../chunks/chunk-FYQWPEEY.js";
17
21
  export {
@@ -3,7 +3,7 @@ import {
3
3
  edgeJoinOf,
4
4
  routedEdgeCurves,
5
5
  strandSides
6
- } from "./chunk-2CVHXFK7.js";
6
+ } from "./chunk-7SRWJLSC.js";
7
7
  import {
8
8
  firstNodeAtOrAfter,
9
9
  isBackbone
@@ -15,8 +15,18 @@ function bypassedPoints(nodePositions, bypassed) {
15
15
  return bypassed.flatMap((id) => nodePositions[id] ?? []);
16
16
  }
17
17
  function deletionArcCurves(nodePositions, deletion, axis, route, stranded = false) {
18
- const from = nodePositions[deletion.from];
19
- const to = nodePositions[deletion.to];
18
+ return edgeCurvesOf(
19
+ nodePositions,
20
+ deletion,
21
+ axis,
22
+ deletion.bypassed,
23
+ route,
24
+ stranded
25
+ );
26
+ }
27
+ function edgeCurvesOf(nodePositions, edge, axis, bypassed, route, stranded) {
28
+ const from = nodePositions[edge.from];
29
+ const to = nodePositions[edge.to];
20
30
  if (!from?.length || !to?.length) {
21
31
  return void 0;
22
32
  }
@@ -24,15 +34,13 @@ function deletionArcCurves(nodePositions, deletion, axis, route, stranded = fals
24
34
  from,
25
35
  to,
26
36
  route,
27
- stranded ? strandSides(deletion) : void 0
37
+ stranded ? strandSides(edge) : void 0
28
38
  ) : computeEdgeCurves(
29
39
  from,
30
40
  to,
31
- edgeJoinOf(deletion, stranded),
32
- 0,
33
- 0,
41
+ edgeJoinOf(edge, stranded),
34
42
  axis,
35
- bypassedPoints(nodePositions, deletion.bypassed)
43
+ bypassed ? bypassedPoints(nodePositions, bypassed) : []
36
44
  );
37
45
  }
38
46
  function backboneBySequence(graph) {
@@ -161,6 +169,7 @@ function deletionDrawing(graph, deletions, show = true) {
161
169
  export {
162
170
  bypassedPoints,
163
171
  deletionArcCurves,
172
+ edgeCurvesOf,
164
173
  deletionEdges,
165
174
  closableDeletions,
166
175
  deletionDrawing
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "10.2.2";
2
+ var version = "10.2.4";
3
3
 
4
4
  export {
5
5
  version
@@ -1,3 +1,6 @@
1
+ import {
2
+ orientToReference
3
+ } from "./chunk-PUG7LXDF.js";
1
4
  import {
2
5
  seededNodes
3
6
  } from "./chunk-IGVV37VI.js";
@@ -9,18 +12,15 @@ import {
9
12
  takeRoutes,
10
13
  withDeletionRoutes
11
14
  } from "./chunk-VPE4AYP7.js";
12
- import {
13
- orientToReference
14
- } from "./chunk-PUG7LXDF.js";
15
15
  import {
16
16
  convertGFAToGraph
17
- } from "./chunk-IW6CYVX2.js";
17
+ } from "./chunk-AR4BUBMU.js";
18
+ import {
19
+ parseGFA
20
+ } from "./chunk-5I3K4R2G.js";
18
21
  import {
19
22
  graphFromTables
20
23
  } from "./chunk-PSMKPSO4.js";
21
- import {
22
- parseGFA
23
- } from "./chunk-CDLPYR5O.js";
24
24
  import {
25
25
  anchorGraph
26
26
  } from "./chunk-M6LK4GII.js";
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  mergeRuns,
32
32
  splitRuns
33
- } from "./chunk-TAMCZHLW.js";
33
+ } from "./chunk-N73TI3VG.js";
34
34
  import {
35
35
  spreadFor
36
36
  } from "./chunk-UVBGRJQX.js";
@@ -40,9 +40,9 @@ import {
40
40
  layoutScaling
41
41
  } from "./chunk-6JEWNXCQ.js";
42
42
  import {
43
- closableDeletions,
43
+ deletionDrawing,
44
44
  deletionEdges
45
- } from "./chunk-N6FECAXP.js";
45
+ } from "./chunk-24WITXQY.js";
46
46
  import {
47
47
  isBackbone
48
48
  } from "./chunk-FYQWPEEY.js";
@@ -118,9 +118,11 @@ function engineKey(graph, settings) {
118
118
  }
119
119
  async function forceLayout(graph, settings, engine) {
120
120
  const spread = spreadFor(settings.bubbleSpread);
121
- const found = deletionEdges(graph);
122
- const dropped = settings.showDeletionEdges === false ? closableDeletions(graph, found) : /* @__PURE__ */ new Set();
123
- const deletions = found.filter((d) => !dropped.has(d.edgeIndex));
121
+ const { shown: deletions, hidden: dropped } = deletionDrawing(
122
+ graph,
123
+ deletionEdges(graph),
124
+ settings.showDeletionEdges !== false
125
+ );
124
126
  const routed = withDeletionRoutes(graph, deletions, dropped);
125
127
  const merged = mergeRuns(routed.graph, routed.ids);
126
128
  const runs = {
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BPLIXMH7.js";
7
7
  import {
8
8
  groupDigits
9
- } from "./chunk-3ZZSX5HN.js";
9
+ } from "./chunk-PTABFYQ7.js";
10
10
 
11
11
  // src/pathColors.ts
12
12
  function nameHue(name) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tubeSpan
3
- } from "./chunk-BPRXQ2SS.js";
3
+ } from "./chunk-XMW266WS.js";
4
4
 
5
5
  // src/tubeMap/genes.ts
6
6
  function tubeMapGenes(byRefName, genes) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  formatBp,
3
3
  groupDigits
4
- } from "./chunk-3ZZSX5HN.js";
4
+ } from "./chunk-PTABFYQ7.js";
5
5
 
6
6
  // src/walkKey.ts
7
7
  function rangeText(contig, start, end) {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  EdgeSpatialIndex,
3
3
  SpatialIndex
4
- } from "./chunk-MLSWIMZO.js";
4
+ } from "./chunk-KBEP7VYK.js";
5
5
  import {
6
6
  pathRibbonOffsets,
7
7
  translateCurves,
8
8
  yToXOf
9
- } from "./chunk-2CVHXFK7.js";
9
+ } from "./chunk-7SRWJLSC.js";
10
10
 
11
11
  // src/util/hitDetection.ts
12
12
  function distanceToSegment(px, py, x1, y1, x2, y2) {
@@ -47,16 +47,9 @@ function walkRowLayout(graph, region) {
47
47
  const nodePositions = backbonePositions(
48
48
  overWindow.length > 0 ? overWindow : backbone
49
49
  );
50
- const rowLabels = [
51
- { label: walks.reference.label, y: 0 },
52
- ...walks.rows.map((row, i) => ({
53
- label: row.label,
54
- y: (i + 1) * ROW_HEIGHT_PX
55
- }))
56
- ];
57
50
  return {
58
51
  nodePositions,
59
- rowLabels,
52
+ rowLabels: walkRowLabels(walks),
60
53
  referenceAxis: true,
61
54
  pixelRows: true,
62
55
  extent: walkRowsExtent(walks)
@@ -64,6 +57,7 @@ function walkRowLayout(graph, region) {
64
57
  }
65
58
 
66
59
  export {
60
+ READOUT_ROOM,
67
61
  walkRowsExtent,
68
62
  walkRowLabels,
69
63
  walkRowLayout
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pathSteps
3
- } from "./chunk-DK5P2YOL.js";
3
+ } from "./chunk-XI3ZUTWF.js";
4
4
  import {
5
5
  pathOrigin
6
6
  } from "./chunk-M6LK4GII.js";
@@ -57,10 +57,11 @@ 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
- if (line.startsWith("H")) {
60
+ const type = line.split(" ", 1)[0];
61
+ if (type === "H") {
61
62
  const [, ...rest] = line.split(" ");
62
63
  graph.header.push(parseTags(rest));
63
- } else if (line.startsWith("S")) {
64
+ } else if (type === "S") {
64
65
  const [, name, ...rest] = line.split(" ");
65
66
  let len;
66
67
  let seq;
@@ -82,7 +83,7 @@ function parseGFA(file) {
82
83
  len = +tags.LN;
83
84
  }
84
85
  graph.nodes.push({ id: name, length: len, sequence: seq, tags });
85
- } else if (line.startsWith("E")) {
86
+ } else if (type === "E") {
86
87
  const [, , source, target, , , , , cigar, ...rest] = line.split(" ");
87
88
  if (source && target) {
88
89
  graph.links.push({
@@ -94,7 +95,7 @@ function parseGFA(file) {
94
95
  tags: parseTags(rest)
95
96
  });
96
97
  }
97
- } else if (line.startsWith("L")) {
98
+ } else if (type === "L") {
98
99
  const [, source, strand1, target, strand2, cigar, ...rest] = line.split(" ");
99
100
  if (source && target && strand2) {
100
101
  graph.links.push({
@@ -106,7 +107,7 @@ function parseGFA(file) {
106
107
  tags: parseTags(rest)
107
108
  });
108
109
  }
109
- } else if (line.startsWith("W")) {
110
+ } else if (type === "W") {
110
111
  const [, sample, hap, contig, start, end, body, ...rest] = line.split(" ");
111
112
  if (sample && hap && contig && start && end && body) {
112
113
  graph.walks.push({
@@ -119,7 +120,7 @@ function parseGFA(file) {
119
120
  tags: parseTags(rest)
120
121
  });
121
122
  }
122
- } else if (line.startsWith("P")) {
123
+ } else if (type === "P") {
123
124
  const [, name, path, ...rest] = line.split(" ");
124
125
  if (name && path) {
125
126
  graph.paths.push({ name, path, rest });
@@ -206,15 +206,16 @@ function bowAround(p1x, p1y, p2x, p2y, toward, maxBow) {
206
206
  function yToXOf({ scaleX, scaleY }) {
207
207
  return scaleY / scaleX;
208
208
  }
209
- var PATH_RIBBON_SPACING = 3;
209
+ var PATH_RIBBON_SPACING_PX = 3;
210
210
  function drawnDirection(a, b, yToX) {
211
211
  const dx = b.x - a.x;
212
212
  const dy = (b.y - a.y) * yToX;
213
213
  const len = Math.hypot(dx, dy);
214
214
  return len === 0 ? void 0 : { x: dx / len, y: dy / len };
215
215
  }
216
- function pathRibbonOffsets(fromSegments, toSegments, count, axis, spacing = PATH_RIBBON_SPACING) {
216
+ function pathRibbonOffsets(fromSegments, toSegments, count, axis) {
217
217
  const yToX = yToXOf(axis);
218
+ const spacing = PATH_RIBBON_SPACING_PX / Math.max(axis.scaleX, 1e-6);
218
219
  const dir = drawnDirection(
219
220
  fromSegments[fromSegments.length - 1],
220
221
  toSegments[0],
@@ -270,15 +271,15 @@ function edgeJoinOf(edge, stranded = false) {
270
271
  const sides = strandSides(edge);
271
272
  return self === false ? sides : sides.from === sides.to ? sides.from : true;
272
273
  }
273
- function hairpinCurves(attach, reach, offsetX, offsetY) {
274
+ function hairpinCurves(attach, reach) {
274
275
  const { at, inward } = attach;
275
276
  const dx = inward ? at.x - inward.x : 1;
276
277
  const dy = inward ? at.y - inward.y : 0;
277
278
  const len = Math.hypot(dx, dy) || 1;
278
279
  const ux = dx / len;
279
280
  const uy = dy / len;
280
- const px = at.x + offsetX;
281
- const py = at.y + offsetY;
281
+ const px = at.x;
282
+ const py = at.y;
282
283
  const nearX = px + ux * reach / 3;
283
284
  const nearY = py + uy * reach / 3;
284
285
  const apexX = px + ux * reach;
@@ -308,7 +309,7 @@ function hairpinCurves(attach, reach, offsetX, offsetY) {
308
309
  }
309
310
  ];
310
311
  }
311
- function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axis, bypassed = [], maxBowIn) {
312
+ function computeEdgeCurves(fromSegments, toSegments, join, axis, bypassed = [], maxBowIn) {
312
313
  const scale = axis.scaleX;
313
314
  const yToX = yToXOf(axis);
314
315
  const maxBow = maxBowIn ?? (axis.pixelRows ? MAX_ROW_BOW_PX : void 0);
@@ -321,8 +322,6 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
321
322
  scaleYOf(fromSegments, yToX),
322
323
  scaleYOf(toSegments, yToX),
323
324
  join,
324
- offsetX,
325
- offsetY * yToX,
326
325
  { scaleX: scale, scaleY: scale },
327
326
  scaleYOf(bypassed, yToX),
328
327
  // the cap is a y measure and the body works in x units, so it converts
@@ -335,9 +334,7 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
335
334
  if (typeof join === "string") {
336
335
  return hairpinCurves(
337
336
  attachment(fromSegments, join),
338
- selfLoopReach(fromSegments, scale),
339
- offsetX,
340
- offsetY
337
+ selfLoopReach(fromSegments, scale)
341
338
  );
342
339
  }
343
340
  const loop = join === true;
@@ -346,10 +343,10 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
346
343
  const toAttach = attachment(toSegments, sides.to);
347
344
  const fromEnd = fromAttach.at;
348
345
  const toStart = toAttach.at;
349
- const p1x = fromEnd.x + offsetX;
350
- const p1y = fromEnd.y + offsetY;
351
- const p2x = toStart.x + offsetX;
352
- const p2y = toStart.y + offsetY;
346
+ const p1x = fromEnd.x;
347
+ const p1y = fromEnd.y;
348
+ const p2x = toStart.x;
349
+ const p2y = toStart.y;
353
350
  if (loop) {
354
351
  let segDirX = 1;
355
352
  let segDirY = 0;
@@ -365,8 +362,8 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
365
362
  const ext = selfLoopReach(fromSegments, scale);
366
363
  const perpX = -segDirY;
367
364
  const perpY = segDirX;
368
- const midX = (fromEnd.x + toStart.x) / 2 + offsetX + perpX * ext;
369
- const midY = (fromEnd.y + toStart.y) / 2 + offsetY + perpY * ext;
365
+ const midX = (fromEnd.x + toStart.x) / 2 + perpX * ext;
366
+ const midY = (fromEnd.y + toStart.y) / 2 + perpY * ext;
370
367
  const cp1x = p1x + segDirX * ext;
371
368
  const cp1y = p1y + segDirY * ext;
372
369
  const cp2x = p2x - segDirX * ext;
@@ -441,10 +438,10 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
441
438
  {
442
439
  x0: p1x,
443
440
  y0: p1y,
444
- cx0: cx1 + offsetX + bulgeX - spreadX,
445
- cy0: cy1 + offsetY + bulgeY - spreadY,
446
- cx1: cx2 + offsetX + bulgeX + spreadX,
447
- cy1: cy2 + offsetY + bulgeY + spreadY,
441
+ cx0: cx1 + bulgeX - spreadX,
442
+ cy0: cy1 + bulgeY - spreadY,
443
+ cx1: cx2 + bulgeX + spreadX,
444
+ cy1: cy2 + bulgeY + spreadY,
448
445
  x1: p2x,
449
446
  y1: p2y
450
447
  }
@@ -521,7 +518,7 @@ export {
521
518
  strandSides,
522
519
  bowAround,
523
520
  yToXOf,
524
- PATH_RIBBON_SPACING,
521
+ PATH_RIBBON_SPACING_PX,
525
522
  pathRibbonOffsets,
526
523
  selfLinkOf,
527
524
  edgeJoinOf,
@@ -5,17 +5,17 @@ import {
5
5
  } from "./chunk-G2FD7S3C.js";
6
6
  import {
7
7
  baseEdgeCurves
8
- } from "./chunk-WFB5TXRA.js";
8
+ } from "./chunk-ZY2AFL4Y.js";
9
9
  import {
10
10
  PATH_LIGHTNESS,
11
11
  PATH_SATURATION,
12
12
  nameHue,
13
13
  pathHueAt
14
- } from "./chunk-TWRLC3KK.js";
14
+ } from "./chunk-3XSM4OZU.js";
15
15
  import {
16
16
  meanDepth,
17
17
  nodeWidthPx
18
- } from "./chunk-PBENCR5L.js";
18
+ } from "./chunk-JBCZIBFC.js";
19
19
  import {
20
20
  referenceMidpoints
21
21
  } from "./chunk-ES2N6V56.js";
@@ -25,7 +25,7 @@ import {
25
25
  strandSides,
26
26
  translateCurves,
27
27
  yToXOf
28
- } from "./chunk-2CVHXFK7.js";
28
+ } from "./chunk-7SRWJLSC.js";
29
29
 
30
30
  // src/renderer/GeometryBuilder.ts
31
31
  var EDGE_DEFAULT_COLOR = packAbgr(119, 119, 119, 217);
@@ -551,25 +551,24 @@ function buildGeometry(options) {
551
551
  const edgeColor = !highlight || onWalk ? plainEdgeColor : fadeAbgr(plainEdgeColor, FADED_ALPHA);
552
552
  const toNode = nodeById.get(edge.to);
553
553
  const intoHalfWidth = (toNode ? nodeWidthPx(toNode, contigThickness, nodeWidth, depthNorm) : contigThickness) / 2;
554
- const buildSingleEdge = (offsetX, offsetY, color, arrowColor) => {
555
- const curves = offsetX === 0 && offsetY === 0 ? baseCurves : translateCurves(baseCurves, offsetX, offsetY);
556
- if (viewportBounds && !isBezierInBounds(curves, viewportBounds)) {
557
- return;
558
- }
554
+ const inView = (curves) => !viewportBounds || isBezierInBounds(curves, viewportBounds);
555
+ const stroke = (curves, thickness, color) => {
559
556
  if (isDeletion) {
560
557
  for (const dash of dashCurves(curves, DELETION_DASH_PX / scale)) {
561
- edgeCurves.push({ curves: dash, thickness: edgeThickness, color });
558
+ edgeCurves.push({ curves: dash, thickness, color });
562
559
  }
563
560
  } else {
564
- edgeCurves.push({ curves, thickness: edgeThickness, color });
561
+ edgeCurves.push({ curves, thickness, color });
565
562
  }
566
- const head = showArrows && arrowColor !== void 0 ? arrowheadFor({
563
+ };
564
+ const arrowOn = (curves) => {
565
+ const head = showArrows ? arrowheadFor({
567
566
  curves,
568
567
  edgeHalfWidth: connectorThickness / 2,
569
568
  nodeHalfWidth: intoHalfWidth,
570
569
  scale,
571
570
  yToX,
572
- color: arrowColor,
571
+ color: edgeColor,
573
572
  fromSegments,
574
573
  toSegments
575
574
  }) : void 0;
@@ -602,17 +601,22 @@ function buildGeometry(options) {
602
601
  }
603
602
  const offset = (lane - (laneWalks.length - 1) / 2) * laneWidth * worldPerScreenPx;
604
603
  const curves = offset === 0 ? baseCurves : translateCurves(baseCurves, nx * offset, ny * offset / yToX);
605
- if (viewportBounds && !isBezierInBounds(curves, viewportBounds)) {
606
- return;
604
+ if (inView(curves)) {
605
+ stroke(
606
+ curves,
607
+ laneWidth / 2,
608
+ walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor
609
+ );
607
610
  }
608
- edgeCurves.push({
609
- curves,
610
- thickness: laneWidth / 2,
611
- color: walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor
612
- });
613
611
  });
612
+ if (edgeCurves.length > edgeCurveStart) {
613
+ arrowOn(baseCurves);
614
+ }
614
615
  } else if (!ribbons) {
615
- buildSingleEdge(0, 0, edgeColor, edgeColor);
616
+ if (inView(baseCurves)) {
617
+ stroke(baseCurves, edgeThickness, edgeColor);
618
+ arrowOn(baseCurves);
619
+ }
616
620
  } else {
617
621
  const offsets = pathRibbonOffsets(
618
622
  fromSegments,
@@ -622,14 +626,20 @@ function buildGeometry(options) {
622
626
  );
623
627
  const arrowRibbon = Math.floor((numPaths - 1) / 2);
624
628
  for (let pathIdx = 0; pathIdx < numPaths; pathIdx++) {
625
- const offset = offsets[pathIdx];
629
+ const { x, y } = offsets[pathIdx];
630
+ const curves = x === 0 && y === 0 ? baseCurves : translateCurves(baseCurves, x, y);
631
+ if (!inView(curves)) {
632
+ continue;
633
+ }
626
634
  const ribbonColor = pathColorByName(edge.pathIds[pathIdx]);
627
- buildSingleEdge(
628
- offset.x,
629
- offset.y,
630
- highlight && (highlight.walks.length ? !highlight.names.has(edge.pathIds[pathIdx]) : !onWalk) ? fadeAbgr(ribbonColor, FADED_ALPHA) : ribbonColor,
631
- pathIdx === arrowRibbon ? edgeColor : void 0
635
+ stroke(
636
+ curves,
637
+ edgeThickness,
638
+ highlight && (highlight.walks.length ? !highlight.names.has(edge.pathIds[pathIdx]) : !onWalk) ? fadeAbgr(ribbonColor, FADED_ALPHA) : ribbonColor
632
639
  );
640
+ if (pathIdx === arrowRibbon) {
641
+ arrowOn(curves);
642
+ }
633
643
  }
634
644
  }
635
645
  const edgeCurveCount = edgeCurves.length - edgeCurveStart;
@@ -1,23 +1,21 @@
1
1
  import {
2
2
  bubblesFromGraph,
3
+ relax,
3
4
  walkIndexOf,
4
5
  walkRoutes
5
- } from "./chunk-CLOP7UVD.js";
6
+ } from "./chunk-CQHUZHET.js";
6
7
  import {
7
8
  bubbleSubgraph
8
9
  } from "./chunk-T6V4KI2L.js";
9
10
  import {
10
11
  coversGraph
11
- } from "./chunk-EHUBJDDB.js";
12
+ } from "./chunk-JA2HJIYS.js";
12
13
  import {
13
14
  bubbleSegmentIds
14
- } from "./chunk-XKWD2RY3.js";
15
- import {
16
- SATURATED_PATH_COUNT
17
- } from "./chunk-FX4RDMDN.js";
15
+ } from "./chunk-URZ3CH2R.js";
18
16
  import {
19
17
  strandSides
20
- } from "./chunk-2CVHXFK7.js";
18
+ } from "./chunk-7SRWJLSC.js";
21
19
  import {
22
20
  isBackbone
23
21
  } from "./chunk-FYQWPEEY.js";
@@ -196,13 +194,7 @@ function routesThrough(nodes, offset, next, f) {
196
194
  }
197
195
  for (let p = offset[k]; p < offset[k + 1]; p++) {
198
196
  const u = next[p] >> 1;
199
- const add = u === sink ? 0 : nodes[u].length;
200
- const prev = best.get(u);
201
- best.set(u, {
202
- min: Math.min(prev?.min ?? Infinity, cur.min + add),
203
- max: Math.max(prev?.max ?? -Infinity, cur.max + add),
204
- n: Math.min(SATURATED_PATH_COUNT, cur.n + (prev?.n ?? 0))
205
- });
197
+ relax(best, u, cur, u === sink ? 0 : nodes[u].length);
206
198
  }
207
199
  }
208
200
  return best.get(sink) ?? { min: 0, max: 0, n: 0 };