@jbrowse/bandage-core 6.0.1 → 6.0.2

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 (162) hide show
  1. package/README.md +23 -7
  2. package/dist/alleleProjection/projectAlleles.js +10 -0
  3. package/dist/anchoredNodes.js +24 -0
  4. package/dist/bubbleSpreads.js +11 -0
  5. package/dist/bubbles/bubbleHalos.js +11 -0
  6. package/dist/bubbles/bubbleLine.js +14 -0
  7. package/dist/bubbles/bubblesFromGraph.js +10 -0
  8. package/dist/bubbles/classifyBubble.js +15 -0
  9. package/dist/bubbles/popBubble.js +9 -0
  10. package/dist/chunks/chunk-3C2LGJKY.js +108 -0
  11. package/dist/chunks/chunk-3PLYZLYV.js +513 -0
  12. package/dist/chunks/chunk-3S3YVOJ7.js +69 -0
  13. package/dist/chunks/chunk-3WHKR5TY.js +726 -0
  14. package/dist/chunks/chunk-47DYCZOK.js +115 -0
  15. package/dist/chunks/chunk-4S47XRYA.js +149 -0
  16. package/dist/chunks/chunk-527AI7CP.js +122 -0
  17. package/dist/chunks/chunk-57ZIXHZA.js +90 -0
  18. package/dist/chunks/chunk-5QT6NPSO.js +40 -0
  19. package/dist/chunks/chunk-6JEWNXCQ.js +90 -0
  20. package/dist/chunks/chunk-6Q6HFBJT.js +170 -0
  21. package/dist/chunks/chunk-6SBUFFTB.js +97 -0
  22. package/dist/chunks/chunk-6YRRNX2P.js +61 -0
  23. package/dist/chunks/chunk-72N5DJHZ.js +155 -0
  24. package/dist/chunks/chunk-73RSLGZT.js +73 -0
  25. package/dist/chunks/chunk-7CHJKABZ.js +82 -0
  26. package/dist/chunks/chunk-7XHHVYG7.js +13 -0
  27. package/dist/chunks/chunk-AB35TJST.js +67 -0
  28. package/dist/chunks/chunk-AE3UQZY3.js +43 -0
  29. package/dist/chunks/chunk-BJV2W4KZ.js +257 -0
  30. package/dist/chunks/chunk-BPLIXMH7.js +52 -0
  31. package/dist/chunks/chunk-BXEPA4KS.js +179 -0
  32. package/dist/chunks/chunk-C44YRP5F.js +85 -0
  33. package/dist/chunks/chunk-CDLPYR5O.js +135 -0
  34. package/dist/chunks/chunk-CPMHA4W5.js +6 -0
  35. package/dist/chunks/chunk-CR7EGAFE.js +241 -0
  36. package/dist/chunks/chunk-CZ54VG2H.js +431 -0
  37. package/dist/chunks/chunk-D3M7SBKL.js +210 -0
  38. package/dist/chunks/chunk-EJ5OZTCK.js +52 -0
  39. package/dist/chunks/chunk-ES2N6V56.js +83 -0
  40. package/dist/chunks/chunk-EZPBJPK6.js +54 -0
  41. package/dist/chunks/chunk-FYQWPEEY.js +65 -0
  42. package/dist/chunks/chunk-GQ2AOHU4.js +112 -0
  43. package/dist/chunks/chunk-HB6PDCOU.js +177 -0
  44. package/dist/chunks/chunk-HCANBJDD.js +326 -0
  45. package/dist/chunks/chunk-HIJVRRYE.js +174 -0
  46. package/dist/chunks/chunk-HNQPEMYE.js +297 -0
  47. package/dist/chunks/chunk-IGVV37VI.js +60 -0
  48. package/dist/chunks/chunk-IMW3AK27.js +102 -0
  49. package/dist/chunks/chunk-JKJWSY4V.js +32 -0
  50. package/dist/chunks/chunk-KCW7L3NV.js +6 -0
  51. package/dist/chunks/chunk-KQFOCDFY.js +73 -0
  52. package/dist/chunks/chunk-L3O7AWLI.js +52 -0
  53. package/dist/chunks/chunk-L5RYUPZI.js +53 -0
  54. package/dist/chunks/chunk-LOEA5IHZ.js +71 -0
  55. package/dist/chunks/chunk-LTUWJKHD.js +112 -0
  56. package/dist/chunks/chunk-LVZZH2NI.js +181 -0
  57. package/dist/chunks/chunk-MFKORG3F.js +44 -0
  58. package/dist/chunks/chunk-MHGHYHTL.js +205 -0
  59. package/dist/chunks/chunk-MI35EUIE.js +76 -0
  60. package/dist/chunks/chunk-MNUSQCLG.js +29 -0
  61. package/dist/chunks/chunk-NNODIW4U.js +26 -0
  62. package/dist/chunks/chunk-P7B3GDAY.js +232 -0
  63. package/dist/chunks/chunk-PBENCR5L.js +60 -0
  64. package/dist/chunks/chunk-PUG7LXDF.js +70 -0
  65. package/dist/chunks/chunk-Q3KCTA4N.js +202 -0
  66. package/dist/chunks/chunk-QCYM44UL.js +476 -0
  67. package/dist/chunks/chunk-QYBZZI5H.js +0 -0
  68. package/dist/chunks/chunk-RAKOB6IV.js +169 -0
  69. package/dist/chunks/chunk-RVS2QCOX.js +135 -0
  70. package/dist/chunks/chunk-SDGM243E.js +190 -0
  71. package/dist/chunks/chunk-ST2IBUAN.js +119 -0
  72. package/dist/chunks/chunk-SV27AJCC.js +101 -0
  73. package/dist/chunks/chunk-SZNZ2T6D.js +198 -0
  74. package/dist/chunks/chunk-TDQLINVI.js +16 -0
  75. package/dist/chunks/chunk-TEDQJPMI.js +131 -0
  76. package/dist/chunks/chunk-TZFWUT2C.js +66 -0
  77. package/dist/chunks/chunk-UVBGRJQX.js +50 -0
  78. package/dist/chunks/chunk-VHW7FDHU.js +42 -0
  79. package/dist/chunks/chunk-VKB57ZYE.js +218 -0
  80. package/dist/chunks/chunk-VZQ4FKLR.js +38 -0
  81. package/dist/chunks/chunk-WOO7QYKB.js +121 -0
  82. package/dist/chunks/chunk-WSIFAZU7.js +132 -0
  83. package/dist/chunks/chunk-X32PABB7.js +117 -0
  84. package/dist/chunks/chunk-YJQ7CT7F.js +23 -0
  85. package/dist/cli/figure.js +84 -17
  86. package/dist/colorSchemes.js +10 -0
  87. package/dist/deletionEdges.js +13 -0
  88. package/dist/el.js +8 -0
  89. package/dist/facetGrid.js +16 -0
  90. package/dist/figure.js +51 -0
  91. package/dist/gaf/parseGaf.js +12 -0
  92. package/dist/gbzCut.js +19 -0
  93. package/dist/gbzJoin.js +6 -0
  94. package/dist/gbzWindow.js +28 -0
  95. package/dist/genes/exonOutline.js +11 -0
  96. package/dist/genes/geneFiles.js +14 -0
  97. package/dist/genes/genePins.js +10 -0
  98. package/dist/gfa/gfaConverter.js +11 -0
  99. package/dist/gfa-core/gfaParser.js +8 -0
  100. package/dist/gfa-core/index.js +9 -0
  101. package/dist/graphLabels.js +24 -0
  102. package/dist/index.js +262 -1407
  103. package/dist/labelLayout.js +24 -0
  104. package/dist/layout/anchoredLayout.js +11 -0
  105. package/dist/layout/deletionRoutes.js +10 -0
  106. package/dist/layout/drawnScale.js +22 -0
  107. package/dist/layout/mergeRuns.js +15 -0
  108. package/dist/layout/orderedLayout.js +12 -0
  109. package/dist/layout/orientToReference.js +7 -0
  110. package/dist/layout/placeOffReference.js +9 -0
  111. package/dist/layout/referenceSeeds.js +11 -0
  112. package/dist/layout/rowSpacing.js +6 -0
  113. package/dist/layout/sampleRowLayout.js +11 -0
  114. package/dist/layout/trimToWindow.js +99 -0
  115. package/dist/layout/tubeMapLayout.js +28 -0
  116. package/dist/layout/walkRowDraw.js +65 -0
  117. package/dist/layout/walkRowLayout.js +13 -0
  118. package/dist/layout/walkRows.js +11 -0
  119. package/dist/layout/walkStrip.js +40 -0
  120. package/dist/layoutModes.js +35 -0
  121. package/dist/loadBandage.js +6 -0
  122. package/dist/nodeWidths.js +18 -0
  123. package/dist/overlayLabels.js +18 -0
  124. package/dist/pansn.js +18 -0
  125. package/dist/pathAnchoring.js +18 -0
  126. package/dist/pathColors.js +31 -0
  127. package/dist/pipeline.js +40 -0
  128. package/dist/reference.js +24 -0
  129. package/dist/referenceRampCss.js +29 -0
  130. package/dist/referenceSpan.js +11 -0
  131. package/dist/referenceStrip.js +35 -0
  132. package/dist/renderer/Canvas2DRenderer.js +9 -0
  133. package/dist/renderer/GeometryBuilder.js +42 -0
  134. package/dist/renderer/colorBits.js +8 -0
  135. package/dist/renderer/recordingCanvas.js +44 -0
  136. package/dist/renderer/svgCanvas.js +6 -0
  137. package/dist/renderer/types.js +0 -0
  138. package/dist/tubeMap/axis.js +25 -0
  139. package/dist/tubeMap/coarsen.js +361 -0
  140. package/dist/tubeMap/connectors.js +13 -0
  141. package/dist/tubeMap/deviations.js +85 -0
  142. package/dist/tubeMap/draw.js +15 -0
  143. package/dist/tubeMap/frame.js +9 -0
  144. package/dist/tubeMap/genes.js +20 -0
  145. package/dist/tubeMap/mismatches.js +6 -0
  146. package/dist/tubeMap/nodeColors.js +21 -0
  147. package/dist/tubeMap/reads.js +17 -0
  148. package/dist/tubeMap/warp.js +8 -0
  149. package/dist/types/version.d.ts +1 -1
  150. package/dist/types.js +0 -0
  151. package/dist/util/SpatialIndex.js +13 -0
  152. package/dist/util/edgeCurves.js +10 -0
  153. package/dist/util/geometry.js +39 -0
  154. package/dist/util/hitDetection.js +20 -0
  155. package/dist/util/wheelZoom.js +6 -0
  156. package/dist/version.js +6 -0
  157. package/dist/viewport.js +33 -0
  158. package/dist/walkEncoding.js +39 -0
  159. package/dist/walkHighlight.js +26 -0
  160. package/dist/walkKey.js +17 -0
  161. package/package.json +38 -5
  162. package/dist/chunks/chunk-EXSFRX2F.js +0 -7400
@@ -0,0 +1,198 @@
1
+ import {
2
+ pathOrigin
3
+ } from "./chunk-ST2IBUAN.js";
4
+ import {
5
+ panSNContig,
6
+ panSNSample
7
+ } from "./chunk-BPLIXMH7.js";
8
+
9
+ // src/layout/walkRows.ts
10
+ function sampleOf(path) {
11
+ return path.sample ?? panSNSample(path.name);
12
+ }
13
+ function labelOf(path) {
14
+ return path.haplotype !== void 0 && path.sample !== void 0 ? `${path.sample}#${path.haplotype}` : sampleOf(path);
15
+ }
16
+ function stepsOf(pieces, lengthOf) {
17
+ const steps = [];
18
+ let end;
19
+ for (const piece of pieces) {
20
+ if (end !== void 0 && piece.start !== void 0 && piece.start > end) {
21
+ steps.push(piece.start - end);
22
+ }
23
+ steps.push(...piece.nodeIds);
24
+ const bp = piece.nodeIds.reduce(
25
+ (sum, id) => sum + (lengthOf.get(id) ?? 0),
26
+ 0
27
+ );
28
+ end = piece.start === void 0 ? void 0 : piece.start + bp;
29
+ }
30
+ return steps;
31
+ }
32
+ function stepSpans(pieces, lengthOf) {
33
+ const spans = [];
34
+ let end;
35
+ for (const piece of pieces) {
36
+ if (piece.start === void 0 || end !== void 0 && piece.start < end) {
37
+ return void 0;
38
+ }
39
+ if (end !== void 0 && piece.start > end) {
40
+ spans.push({ start: end, end: piece.start });
41
+ }
42
+ let pos = piece.start;
43
+ for (const id of piece.nodeIds) {
44
+ const len = lengthOf.get(id) ?? 0;
45
+ spans.push({ start: pos, end: pos + len });
46
+ pos += len;
47
+ }
48
+ end = pos;
49
+ }
50
+ return spans;
51
+ }
52
+ function sliceBetween(steps, span, region, flanked = true) {
53
+ if (!region || !flanked) {
54
+ return { ids: steps, complete: true, from: -1, to: -1 };
55
+ }
56
+ let i0 = -1;
57
+ let i1 = -1;
58
+ let bestEnd = -Infinity;
59
+ let bestStart = Infinity;
60
+ steps.forEach((id, i) => {
61
+ const s = typeof id === "string" ? span.get(id) : void 0;
62
+ if (s) {
63
+ if (s.end <= region.start && s.end > bestEnd) {
64
+ bestEnd = s.end;
65
+ i0 = i;
66
+ }
67
+ if (s.start >= region.end && s.start < bestStart) {
68
+ bestStart = s.start;
69
+ i1 = i;
70
+ }
71
+ }
72
+ });
73
+ if (i0 < 0 || i1 < 0) {
74
+ return { ids: steps, complete: false, from: -1, to: -1 };
75
+ }
76
+ const ids = steps.slice(Math.min(i0, i1) + 1, Math.max(i0, i1));
77
+ return {
78
+ ids: i0 < i1 ? ids : ids.reverse(),
79
+ complete: true,
80
+ from: i0,
81
+ to: i1
82
+ };
83
+ }
84
+ function filterSamples(rows, samples) {
85
+ return samples ? rows.filter((r) => samples.includes(r.sample)).sort(
86
+ (a, b) => samples.indexOf(a.sample) - samples.indexOf(b.sample) || a.label.localeCompare(b.label)
87
+ ) : rows;
88
+ }
89
+ function walkRows(graph, region, unit) {
90
+ const paths = graph.paths ?? [];
91
+ const isReference = (p) => pathOrigin(p.name).name === graph.referencePath;
92
+ const referencePieces = paths.some(isReference) ? paths.filter(isReference).sort((a, b) => (a.start ?? 0) - (b.start ?? 0)) : paths.slice(0, 1);
93
+ const first = referencePieces[0];
94
+ const others = paths.filter((p) => !referencePieces.includes(p));
95
+ if (!first || others.length === 0) {
96
+ return void 0;
97
+ }
98
+ const walks = /* @__PURE__ */ new Map();
99
+ for (const path of others) {
100
+ walks.set(path.name, [...walks.get(path.name) ?? [], path]);
101
+ }
102
+ const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));
103
+ const referenceStart = first.start ?? 0;
104
+ const cut = region && region.end > region.start ? region : void 0;
105
+ const span = /* @__PURE__ */ new Map();
106
+ for (const piece of referencePieces) {
107
+ let pos = piece.start ?? 0;
108
+ for (const id of piece.nodeIds) {
109
+ const len = lengthOf.get(id) ?? 0;
110
+ if (!span.has(id)) {
111
+ span.set(id, { start: pos, end: pos + len });
112
+ }
113
+ pos += len;
114
+ }
115
+ }
116
+ const flanked = cut === void 0 || [...span.values()].some((s) => s.end <= cut.start) && [...span.values()].some((s) => s.start >= cut.end);
117
+ const rowOf = (pieces) => {
118
+ const path = pieces[0];
119
+ const ordered = [...pieces].sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
120
+ const { ids, complete, from, to } = sliceBetween(
121
+ stepsOf(ordered, lengthOf),
122
+ span,
123
+ cut,
124
+ flanked
125
+ );
126
+ const spans = stepSpans(ordered, lengthOf);
127
+ const contig = path.contig ?? panSNContig(pathOrigin(path.name).name);
128
+ const axis = !spans?.length ? void 0 : from < 0 ? { contig, start: spans[0].start, reversed: false } : from < to ? { contig, start: spans[from].end, reversed: false } : { contig, start: spans[from].start, reversed: true };
129
+ const runs = [];
130
+ let bp = 0;
131
+ let offReferenceBp = 0;
132
+ let gapBp = 0;
133
+ let step = 0;
134
+ for (const id of ids) {
135
+ if (typeof id === "number") {
136
+ runs.push({ start: bp, bp: id, onReference: false, gap: true });
137
+ bp += id;
138
+ gapBp += id;
139
+ step = 0;
140
+ continue;
141
+ }
142
+ const len = lengthOf.get(id) ?? 0;
143
+ const s = span.get(id);
144
+ const last = runs.at(-1);
145
+ const at = last?.referenceStart;
146
+ const forward = s && at !== void 0 && step >= 0 && at + last.bp === s.start;
147
+ const backward = s && at !== void 0 && step <= 0 && s.end === at;
148
+ if (!s && last && !last.onReference && !last.gap) {
149
+ last.bp += len;
150
+ } else if (forward || backward) {
151
+ last.bp += len;
152
+ if (!forward) {
153
+ last.referenceStart = s.start;
154
+ last.reversed = true;
155
+ }
156
+ step = forward ? 1 : -1;
157
+ } else {
158
+ runs.push({
159
+ start: bp,
160
+ bp: len,
161
+ onReference: s !== void 0,
162
+ referenceStart: s?.start
163
+ });
164
+ step = 0;
165
+ }
166
+ bp += len;
167
+ if (!s) {
168
+ offReferenceBp += len;
169
+ }
170
+ }
171
+ return {
172
+ name: path.name,
173
+ label: labelOf(path),
174
+ sample: sampleOf(path),
175
+ haplotype: path.haplotype,
176
+ bp,
177
+ offReferenceBp,
178
+ gapBp,
179
+ complete,
180
+ runs,
181
+ axis
182
+ };
183
+ };
184
+ const origin = cut ? cut.start : referenceStart;
185
+ return {
186
+ origin,
187
+ unit,
188
+ reference: rowOf(referencePieces),
189
+ rows: [...walks.values()].map(rowOf).sort(
190
+ (a, b) => Number(b.complete) - Number(a.complete) || b.bp - a.bp || a.label.localeCompare(b.label)
191
+ )
192
+ };
193
+ }
194
+
195
+ export {
196
+ filterSamples,
197
+ walkRows
198
+ };
@@ -0,0 +1,16 @@
1
+ // src/util/wheelZoom.ts
2
+ var ZOOM_PER_NOTCH = 1.1;
3
+ var NOTCH_PX = 100;
4
+ var LINE_PX = 40;
5
+ var PAGE_PX = 800;
6
+ var PINCH_GAIN = 10;
7
+ var MAX_NOTCHES_PER_EVENT = 2;
8
+ function wheelZoomFactor(e) {
9
+ const px = e.deltaY * (e.deltaMode === 1 ? LINE_PX : e.deltaMode === 2 ? PAGE_PX : 1);
10
+ const notches = (e.ctrlKey ? PINCH_GAIN : 1) * px / NOTCH_PX;
11
+ return ZOOM_PER_NOTCH ** -Math.max(-MAX_NOTCHES_PER_EVENT, Math.min(MAX_NOTCHES_PER_EVENT, notches));
12
+ }
13
+
14
+ export {
15
+ wheelZoomFactor
16
+ };
@@ -0,0 +1,131 @@
1
+ import {
2
+ parseCs
3
+ } from "./chunk-C44YRP5F.js";
4
+
5
+ // src/tubeMap/reads.ts
6
+ function canonicalStrand(node) {
7
+ return node.id.endsWith("-") ? "-" : "+";
8
+ }
9
+ function stepName(node, strand) {
10
+ return strand === canonicalStrand(node) ? node.id : `-${node.id}`;
11
+ }
12
+ function stepStarts(lengths, total) {
13
+ const starts = lengths.map(() => void 0);
14
+ let head = 0;
15
+ let i = 0;
16
+ for (; i < lengths.length && lengths[i] !== void 0; i++) {
17
+ starts[i] = head;
18
+ head += lengths[i];
19
+ }
20
+ let tail = total;
21
+ for (let j = lengths.length - 1; j > i && lengths[j] !== void 0; j--) {
22
+ tail -= lengths[j];
23
+ starts[j] = tail;
24
+ }
25
+ return starts;
26
+ }
27
+ function mismatchesByStep(record, lengths) {
28
+ const byStep = record.path.map(() => []);
29
+ if (record.cs === void 0) {
30
+ return byStep;
31
+ }
32
+ const starts = stepStarts(lengths, record.pathLength);
33
+ const stepAt = (pos2, atEnd = false) => {
34
+ for (let s = 0; s < starts.length; s++) {
35
+ const start = starts[s];
36
+ const length = lengths[s];
37
+ if (start !== void 0 && length !== void 0 && start <= pos2 && (pos2 < start + length || atEnd && pos2 === start + length)) {
38
+ return { s, local: pos2 - start, room: start + length - pos2 };
39
+ }
40
+ }
41
+ return void 0;
42
+ };
43
+ const add = (s, mismatch) => {
44
+ const list = byStep[s];
45
+ const last = list.at(-1);
46
+ if (mismatch.type === "substitution" && last?.type === "substitution" && last.pos + last.seq.length === mismatch.pos) {
47
+ last.seq += mismatch.seq;
48
+ } else {
49
+ list.push(mismatch);
50
+ }
51
+ };
52
+ let pos = record.pathStart;
53
+ for (const op of parseCs(record.cs)) {
54
+ if (op.op === "match") {
55
+ pos += op.length;
56
+ } else if (op.op === "substitution") {
57
+ const at = stepAt(pos);
58
+ if (at) {
59
+ add(at.s, { type: "substitution", pos: at.local, seq: op.seq });
60
+ }
61
+ pos += 1;
62
+ } else if (op.op === "insertion") {
63
+ const at = stepAt(pos, pos === record.pathEnd);
64
+ if (at) {
65
+ add(at.s, { type: "insertion", pos: at.local, seq: op.seq });
66
+ }
67
+ } else {
68
+ let left = op.length;
69
+ while (left > 0) {
70
+ const at = stepAt(pos);
71
+ const take = at ? Math.min(left, at.room) : left;
72
+ if (at) {
73
+ add(at.s, { type: "deletion", pos: at.local, length: take });
74
+ }
75
+ pos += take;
76
+ left -= take;
77
+ }
78
+ }
79
+ }
80
+ return byStep;
81
+ }
82
+ function tubeMapReads(graph, records, firstId) {
83
+ const nodeByName = new Map(graph.nodes.map((n) => [n.name, n]));
84
+ const reads = [];
85
+ for (const record of records) {
86
+ const nodes = record.path.map((step) => nodeByName.get(step.name));
87
+ const kept = nodes.flatMap((node, i) => node ? [i] : []);
88
+ const first = kept[0];
89
+ const last = kept.at(-1);
90
+ if (first !== void 0 && last !== void 0) {
91
+ const mismatches = mismatchesByStep(
92
+ record,
93
+ nodes.map((n) => n?.length)
94
+ );
95
+ const names = kept.map((i) => stepName(nodes[i], record.path[i].strand));
96
+ const lastLength = nodes[last].length;
97
+ reads.push({
98
+ id: firstId + reads.length,
99
+ name: record.name,
100
+ type: "read",
101
+ sourceTrackID: 1,
102
+ sequence: names,
103
+ sequenceNew: kept.map((i, k) => ({
104
+ nodeName: names[k],
105
+ mismatches: mismatches[i]
106
+ })),
107
+ firstNodeOffset: first === 0 ? record.pathStart : 0,
108
+ finalNodeCoverLength: last === record.path.length - 1 ? lastLength - (record.pathLength - record.pathEnd) : lastLength,
109
+ mapping_quality: record.mappingQuality === 255 ? 0 : record.mappingQuality,
110
+ is_secondary: record.secondary,
111
+ is_reverse: record.strand === "-"
112
+ });
113
+ }
114
+ }
115
+ return reads;
116
+ }
117
+ var FORWARD_READ_COLORS = ["#6baed6", "#4292c6", "#2171b5", "#08519c"];
118
+ var REVERSE_READ_COLORS = ["#fb6a4a", "#ef3b2c", "#cb181d", "#a50f15"];
119
+ function readColor(read) {
120
+ const colors = read.is_reverse ? REVERSE_READ_COLORS : FORWARD_READ_COLORS;
121
+ return colors[read.id % colors.length];
122
+ }
123
+
124
+ export {
125
+ canonicalStrand,
126
+ stepName,
127
+ tubeMapReads,
128
+ FORWARD_READ_COLORS,
129
+ REVERSE_READ_COLORS,
130
+ readColor
131
+ };
@@ -0,0 +1,66 @@
1
+ import {
2
+ projectAlleles
3
+ } from "./chunk-RVS2QCOX.js";
4
+ import {
5
+ buildNeighbors
6
+ } from "./chunk-ES2N6V56.js";
7
+
8
+ // src/layout/placeOffReference.ts
9
+ var MIN_DELETION_BP = 1;
10
+ var MIN_ALLELE_SPAN_FRACTION = 0.015;
11
+ function placeOffReference({
12
+ graph,
13
+ span,
14
+ rowY,
15
+ positions
16
+ }) {
17
+ const minSpan = span * MIN_ALLELE_SPAN_FRACTION;
18
+ const alleles = projectAlleles(graph);
19
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
20
+ const alleleDeletions = [];
21
+ for (const allele of alleles) {
22
+ const skipped = allele.refSpan - allele.pathLength;
23
+ if (skipped >= MIN_DELETION_BP) {
24
+ alleleDeletions.push({ nodeIds: allele.nodeIds, bp: skipped });
25
+ }
26
+ const drawn = Math.max(allele.refSpan, minSpan);
27
+ const scale = allele.pathLength > 0 ? drawn / allele.pathLength : 0;
28
+ allele.nodeIds.forEach((nodeId, i) => {
29
+ const node = byId.get(nodeId);
30
+ if (node) {
31
+ const offset = allele.nodeOffsets[i];
32
+ const even = drawn / allele.nodeIds.length;
33
+ const at = (bp) => allele.start + bp * scale;
34
+ const y = rowY(node);
35
+ positions[nodeId] = scale ? [
36
+ { x: at(offset), y },
37
+ { x: at(offset + node.length), y }
38
+ ] : [
39
+ { x: allele.start + i * even, y },
40
+ { x: allele.start + (i + 1) * even, y }
41
+ ];
42
+ }
43
+ });
44
+ }
45
+ const neighbors = buildNeighbors(graph);
46
+ const queue = Object.keys(positions);
47
+ for (const fromId of queue) {
48
+ const fromEnd = positions[fromId].at(-1).x;
49
+ for (const nextId of neighbors.get(fromId) ?? []) {
50
+ const next = byId.get(nextId);
51
+ if (next && !(nextId in positions)) {
52
+ const y = rowY(next);
53
+ positions[nextId] = [
54
+ { x: fromEnd, y },
55
+ { x: fromEnd + minSpan, y }
56
+ ];
57
+ queue.push(nextId);
58
+ }
59
+ }
60
+ }
61
+ return alleleDeletions;
62
+ }
63
+
64
+ export {
65
+ placeOffReference
66
+ };
@@ -0,0 +1,50 @@
1
+ import {
2
+ MEAN_NODE_LENGTH,
3
+ PROPORTIONAL_LENGTH
4
+ } from "./chunk-6JEWNXCQ.js";
5
+
6
+ // src/bubbleSpreads.ts
7
+ var BUBBLE_SPREADS = [
8
+ {
9
+ value: "auto",
10
+ label: "Proportional",
11
+ description: "Bandage's own scale: a node draws proportional to its length, so a 1 bp allele is a speck.",
12
+ law: PROPORTIONAL_LENGTH,
13
+ minNodeFactor: 0
14
+ },
15
+ {
16
+ value: "open",
17
+ label: "Open bubbles",
18
+ description: "Give every allele a drawn length, so a bubble reads as two arms rather than a knot.",
19
+ law: PROPORTIONAL_LENGTH,
20
+ minNodeFactor: 2.5
21
+ },
22
+ {
23
+ value: "wide",
24
+ label: "Wide bubbles",
25
+ description: "As open, spread further. Best on a window of a dozen bubbles.",
26
+ law: PROPORTIONAL_LENGTH,
27
+ minNodeFactor: 10
28
+ },
29
+ {
30
+ value: "compress",
31
+ label: "Compress lengths",
32
+ description: "Pull the longest and shortest nodes towards the graph\u2019s mean, so a cut spanning kb and bp fits one pane.",
33
+ law: { power: 0.5, effect: 0.5 },
34
+ minNodeFactor: 0
35
+ }
36
+ ];
37
+ var BUBBLE_SPREAD_VALUES = BUBBLE_SPREADS.map((s) => s.value);
38
+ function spreadFor(spread) {
39
+ const entry = BUBBLE_SPREADS.find((s) => s.value === spread);
40
+ return {
41
+ law: entry?.law ?? PROPORTIONAL_LENGTH,
42
+ minNodeLength: (entry?.minNodeFactor ?? 0) * MEAN_NODE_LENGTH
43
+ };
44
+ }
45
+
46
+ export {
47
+ BUBBLE_SPREADS,
48
+ BUBBLE_SPREAD_VALUES,
49
+ spreadFor
50
+ };
@@ -0,0 +1,42 @@
1
+ import {
2
+ trimOrigins
3
+ } from "./chunk-ST2IBUAN.js";
4
+
5
+ // src/bubbles/popBubble.ts
6
+ function bubbleSubgraph(graph, segmentIds) {
7
+ const keep = new Set(segmentIds);
8
+ const nodes = graph.nodes.filter((n) => keep.has(n.name));
9
+ const ids = new Set(nodes.map((n) => n.id));
10
+ const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));
11
+ const kept = /* @__PURE__ */ new Map();
12
+ const paths = graph.paths?.flatMap((p) => {
13
+ const first = p.nodeIds.findIndex((id) => ids.has(id));
14
+ if (first < 0) {
15
+ return [];
16
+ }
17
+ const nodeIds = p.nodeIds.filter((id) => ids.has(id));
18
+ kept.set(p.name, { first, nodeIds });
19
+ const before = p.nodeIds.slice(0, first).reduce((sum, id) => sum + (lengthOf.get(id) ?? 0), 0);
20
+ return [
21
+ {
22
+ ...p,
23
+ nodeIds,
24
+ ...p.start === void 0 ? {} : { start: p.start + before }
25
+ }
26
+ ];
27
+ });
28
+ return {
29
+ name: graph.name,
30
+ nodes,
31
+ edges: graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to)),
32
+ ...paths?.length ? { paths } : {},
33
+ anchorPaths: trimOrigins(graph, kept),
34
+ pathVisits: graph.pathVisits,
35
+ anchoredBy: graph.anchoredBy,
36
+ referencePath: graph.referencePath
37
+ };
38
+ }
39
+
40
+ export {
41
+ bubbleSubgraph
42
+ };