@jbrowse/bandage-core 6.0.1 → 6.0.3

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-2CVHXFK7.js +530 -0
  11. package/dist/chunks/chunk-3S3YVOJ7.js +69 -0
  12. package/dist/chunks/chunk-47DYCZOK.js +115 -0
  13. package/dist/chunks/chunk-4EMPBO7S.js +117 -0
  14. package/dist/chunks/chunk-4S47XRYA.js +149 -0
  15. package/dist/chunks/chunk-5XQDMQXU.js +431 -0
  16. package/dist/chunks/chunk-6JEWNXCQ.js +90 -0
  17. package/dist/chunks/chunk-6SBUFFTB.js +97 -0
  18. package/dist/chunks/chunk-6SXMCK6I.js +476 -0
  19. package/dist/chunks/chunk-72N5DJHZ.js +155 -0
  20. package/dist/chunks/chunk-73RSLGZT.js +73 -0
  21. package/dist/chunks/chunk-7XHHVYG7.js +13 -0
  22. package/dist/chunks/chunk-AB35TJST.js +67 -0
  23. package/dist/chunks/chunk-BPLIXMH7.js +52 -0
  24. package/dist/chunks/chunk-BUBZ32IC.js +101 -0
  25. package/dist/chunks/chunk-BXEPA4KS.js +179 -0
  26. package/dist/chunks/chunk-C44YRP5F.js +85 -0
  27. package/dist/chunks/chunk-CDLPYR5O.js +135 -0
  28. package/dist/chunks/chunk-CJ2EE4AF.js +40 -0
  29. package/dist/chunks/chunk-CPMHA4W5.js +6 -0
  30. package/dist/chunks/chunk-CR7EGAFE.js +241 -0
  31. package/dist/chunks/chunk-CS3E4ETM.js +202 -0
  32. package/dist/chunks/chunk-CTSBC2O6.js +90 -0
  33. package/dist/chunks/chunk-D3M7SBKL.js +210 -0
  34. package/dist/chunks/chunk-DKOB2OPC.js +177 -0
  35. package/dist/chunks/chunk-EJ5OZTCK.js +52 -0
  36. package/dist/chunks/chunk-EK4HGYO7.js +174 -0
  37. package/dist/chunks/chunk-EPZORFTI.js +23 -0
  38. package/dist/chunks/chunk-ES2N6V56.js +83 -0
  39. package/dist/chunks/chunk-EZPBJPK6.js +54 -0
  40. package/dist/chunks/chunk-FYQWPEEY.js +65 -0
  41. package/dist/chunks/chunk-GGQRADFS.js +170 -0
  42. package/dist/chunks/chunk-GOY6REMT.js +43 -0
  43. package/dist/chunks/chunk-GQ2AOHU4.js +112 -0
  44. package/dist/chunks/chunk-HNQPEMYE.js +297 -0
  45. package/dist/chunks/chunk-IGVV37VI.js +60 -0
  46. package/dist/chunks/chunk-IO2PCPZI.js +218 -0
  47. package/dist/chunks/chunk-ISEI2FH3.js +108 -0
  48. package/dist/chunks/chunk-JKJWSY4V.js +32 -0
  49. package/dist/chunks/chunk-KQFOCDFY.js +73 -0
  50. package/dist/chunks/chunk-L3O7AWLI.js +52 -0
  51. package/dist/chunks/chunk-LLJUG2H7.js +6 -0
  52. package/dist/chunks/chunk-LOEA5IHZ.js +71 -0
  53. package/dist/chunks/chunk-LTUWJKHD.js +112 -0
  54. package/dist/chunks/chunk-MFKORG3F.js +44 -0
  55. package/dist/chunks/chunk-MI35EUIE.js +76 -0
  56. package/dist/chunks/chunk-MNUSQCLG.js +29 -0
  57. package/dist/chunks/chunk-MQJUG2D2.js +53 -0
  58. package/dist/chunks/chunk-MREQ7GIA.js +181 -0
  59. package/dist/chunks/chunk-N62KBLFC.js +326 -0
  60. package/dist/chunks/chunk-NNODIW4U.js +26 -0
  61. package/dist/chunks/chunk-PBENCR5L.js +60 -0
  62. package/dist/chunks/chunk-PCZ4PTYC.js +726 -0
  63. package/dist/chunks/chunk-PUG7LXDF.js +70 -0
  64. package/dist/chunks/chunk-QYBZZI5H.js +0 -0
  65. package/dist/chunks/chunk-R6ZUK4Y3.js +232 -0
  66. package/dist/chunks/chunk-RAKOB6IV.js +169 -0
  67. package/dist/chunks/chunk-ROF2R3RF.js +205 -0
  68. package/dist/chunks/chunk-RVS2QCOX.js +135 -0
  69. package/dist/chunks/chunk-ST2IBUAN.js +119 -0
  70. package/dist/chunks/chunk-SZNZ2T6D.js +198 -0
  71. package/dist/chunks/chunk-T43W7NKK.js +122 -0
  72. package/dist/chunks/chunk-TAMCZHLW.js +190 -0
  73. package/dist/chunks/chunk-TDQLINVI.js +16 -0
  74. package/dist/chunks/chunk-TEDQJPMI.js +131 -0
  75. package/dist/chunks/chunk-TZFWUT2C.js +66 -0
  76. package/dist/chunks/chunk-UVBGRJQX.js +50 -0
  77. package/dist/chunks/chunk-VHW7FDHU.js +42 -0
  78. package/dist/chunks/chunk-VZQ4FKLR.js +38 -0
  79. package/dist/chunks/chunk-WFX3MAKA.js +102 -0
  80. package/dist/chunks/chunk-WOO7QYKB.js +121 -0
  81. package/dist/chunks/chunk-WSIFAZU7.js +132 -0
  82. package/dist/chunks/chunk-X5L37W4J.js +82 -0
  83. package/dist/chunks/chunk-Y3IOTZJA.js +61 -0
  84. package/dist/chunks/chunk-YMSSF2RK.js +257 -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,190 @@
1
+ import {
2
+ ownStrand,
3
+ strandSides
4
+ } from "./chunk-2CVHXFK7.js";
5
+ import {
6
+ isBackbone
7
+ } from "./chunk-FYQWPEEY.js";
8
+
9
+ // src/layout/mergeRuns.ts
10
+ function flip(strand) {
11
+ return strand === "+" ? "-" : "+";
12
+ }
13
+ function mergeRuns(graph, alone = /* @__PURE__ */ new Set()) {
14
+ const sides = graph.edges.map(strandSides);
15
+ const at = /* @__PURE__ */ new Map();
16
+ const attach = (id, side, ei) => {
17
+ const key = `${id}|${side}`;
18
+ const list = at.get(key);
19
+ if (list) {
20
+ list.push(ei);
21
+ } else {
22
+ at.set(key, [ei]);
23
+ }
24
+ };
25
+ graph.edges.forEach((edge, ei) => {
26
+ attach(edge.from, sides[ei].from, ei);
27
+ attach(edge.to, sides[ei].to, ei);
28
+ });
29
+ const joinAfter = (a) => {
30
+ const out = at.get(`${a}|end`);
31
+ if (out?.length !== 1) {
32
+ return void 0;
33
+ }
34
+ const ei = out[0];
35
+ const edge = graph.edges[ei];
36
+ return edge.from === a && edge.to !== a && !alone.has(a) && !alone.has(edge.to) && sides[ei].from === "end" && sides[ei].to === "start" && at.get(`${edge.to}|start`)?.length === 1 ? ei : void 0;
37
+ };
38
+ const joined = /* @__PURE__ */ new Set();
39
+ const runOf = /* @__PURE__ */ new Map();
40
+ const runs = /* @__PURE__ */ new Map();
41
+ for (const node of graph.nodes) {
42
+ const into = at.get(`${node.id}|start`);
43
+ const pred = into?.length === 1 ? graph.edges[into[0]].from : void 0;
44
+ if (runOf.has(node.id) || pred !== void 0 && joinAfter(pred) === into[0]) {
45
+ continue;
46
+ }
47
+ const run = [node.id];
48
+ for (; ; ) {
49
+ const ei = joinAfter(run.at(-1));
50
+ const next = ei === void 0 ? void 0 : graph.edges[ei].to;
51
+ if (next === void 0 || runOf.has(next)) {
52
+ break;
53
+ }
54
+ joined.add(ei);
55
+ run.push(next);
56
+ }
57
+ for (const id of run) {
58
+ runOf.set(id, node.id);
59
+ }
60
+ if (run.length > 1) {
61
+ runs.set(node.id, run);
62
+ }
63
+ }
64
+ for (const node of graph.nodes) {
65
+ if (!runOf.has(node.id)) {
66
+ runOf.set(node.id, node.id);
67
+ }
68
+ }
69
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
70
+ const nodes = [];
71
+ for (const node of graph.nodes) {
72
+ if (runOf.get(node.id) !== node.id) {
73
+ continue;
74
+ }
75
+ const run = runs.get(node.id);
76
+ if (!run) {
77
+ nodes.push(node);
78
+ continue;
79
+ }
80
+ const members = run.map((id) => byId.get(id));
81
+ const backbone = members.filter(isBackbone);
82
+ const first = backbone.length ? backbone.reduce((a, b) => a.stable.start <= b.stable.start ? a : b) : members[0];
83
+ nodes.push({
84
+ id: node.id,
85
+ name: node.name,
86
+ length: members.reduce((sum, n) => sum + n.length, 0),
87
+ depth: node.depth,
88
+ stable: first.stable
89
+ });
90
+ }
91
+ const seen = /* @__PURE__ */ new Set();
92
+ const edges = [];
93
+ graph.edges.forEach((edge, ei) => {
94
+ const from = runOf.get(edge.from);
95
+ const to = runOf.get(edge.to);
96
+ const side = sides[ei];
97
+ const key = `${from}|${side.from}>${to}|${side.to}`;
98
+ if (joined.has(ei) || seen.has(key)) {
99
+ return;
100
+ }
101
+ seen.add(key);
102
+ edges.push({
103
+ from,
104
+ to,
105
+ ...side.from === "start" ? { fromStrand: flip(ownStrand(from)) } : {},
106
+ ...side.to === "end" ? { toStrand: flip(ownStrand(to)) } : {}
107
+ });
108
+ });
109
+ return {
110
+ graph: { ...graph, nodes, edges, paths: void 0, pathVisits: void 0 },
111
+ runs
112
+ };
113
+ }
114
+ function splitRuns(positions, runs, weightOf) {
115
+ const out = { ...positions };
116
+ for (const [id, members] of runs) {
117
+ const line = positions[id];
118
+ if (!line?.length) {
119
+ continue;
120
+ }
121
+ delete out[id];
122
+ const arc = arcPrefix(line);
123
+ const total = arc.at(-1);
124
+ const weights = members.map((m) => Math.max(weightOf(m), 0));
125
+ const weightSum = weights.reduce((a, b) => a + b, 0) || members.length;
126
+ let from = 0;
127
+ members.forEach((member, k) => {
128
+ const share = weightSum ? weights[k] / weightSum * total : total / members.length;
129
+ const to = k === members.length - 1 ? total : from + share;
130
+ out[member] = slice(line, arc, from, to);
131
+ from = to;
132
+ });
133
+ }
134
+ return out;
135
+ }
136
+ function polylineSlice(line, from, to) {
137
+ if (line.length === 0) {
138
+ return [];
139
+ }
140
+ const arc = arcPrefix(line);
141
+ const total = arc.at(-1);
142
+ return slice(line, arc, from * total, to * total);
143
+ }
144
+ function polylineMidpoint(line) {
145
+ const arc = arcPrefix(line);
146
+ return pointAt(line, arc, arc.at(-1) / 2);
147
+ }
148
+ function arcPrefix(line) {
149
+ const arc = [0];
150
+ for (let i = 1; i < line.length; i++) {
151
+ arc.push(
152
+ arc[i - 1] + Math.hypot(line[i].x - line[i - 1].x, line[i].y - line[i - 1].y)
153
+ );
154
+ }
155
+ return arc;
156
+ }
157
+ function pointAt(line, arc, s) {
158
+ if (s <= 0) {
159
+ return { ...line[0] };
160
+ }
161
+ let i = 1;
162
+ while (i < arc.length && arc[i] < s) {
163
+ i++;
164
+ }
165
+ if (i >= arc.length) {
166
+ return { ...line.at(-1) };
167
+ }
168
+ const span = arc[i] - arc[i - 1];
169
+ const t = span > 0 ? (s - arc[i - 1]) / span : 0;
170
+ const a = line[i - 1];
171
+ const b = line[i];
172
+ return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
173
+ }
174
+ function slice(line, arc, from, to) {
175
+ const points = [pointAt(line, arc, from)];
176
+ for (let i = 0; i < line.length; i++) {
177
+ if (arc[i] > from && arc[i] < to) {
178
+ points.push({ ...line[i] });
179
+ }
180
+ }
181
+ points.push(pointAt(line, arc, to));
182
+ return points;
183
+ }
184
+
185
+ export {
186
+ mergeRuns,
187
+ splitRuns,
188
+ polylineSlice,
189
+ polylineMidpoint
190
+ };
@@ -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
+ };
@@ -0,0 +1,38 @@
1
+ import {
2
+ referenceKnots,
3
+ warpX
4
+ } from "./chunk-KQFOCDFY.js";
5
+
6
+ // src/tubeMap/frame.ts
7
+ var MIN_TUBE_Y_SCALE = 0.05;
8
+ var NODE_BOX_PAD = 9;
9
+ function squeeze(drawing, usableHeight) {
10
+ const { minY, maxY } = drawing.layout.bounds;
11
+ const h = maxY - minY;
12
+ return drawing.columns && h > 0 ? Math.max(MIN_TUBE_Y_SCALE, Math.min(1, usableHeight / h)) : 1;
13
+ }
14
+ function tubeMapFrame(drawing, view) {
15
+ const { scaleX, translateX, translateY } = view;
16
+ const yScale = view.scaleY * squeeze(drawing, view.usableHeight);
17
+ const y = (ty) => (ty - drawing.yOffset) * yScale + translateY;
18
+ const { columns } = drawing;
19
+ if (columns) {
20
+ const knots = referenceKnots(columns, (bp) => bp * scaleX + translateX);
21
+ return { x: (tx) => warpX(knots, tx), y, yScale };
22
+ }
23
+ return { x: (tx) => tx * scaleX + translateX, y, yScale };
24
+ }
25
+ function tubeMapNodeAt(drawing, { x, y }, sx, sy) {
26
+ let hit = null;
27
+ drawing.layout.nodes.forEach((node) => {
28
+ if (node.order >= 0 && x(node.x - NODE_BOX_PAD) <= sx && sx <= x(node.x + node.pixelWidth + NODE_BOX_PAD) && y(node.y - NODE_BOX_PAD) <= sy && sy <= y(node.y + node.contentHeight + NODE_BOX_PAD)) {
29
+ hit = node.name;
30
+ }
31
+ });
32
+ return hit;
33
+ }
34
+
35
+ export {
36
+ tubeMapFrame,
37
+ tubeMapNodeAt
38
+ };
@@ -0,0 +1,102 @@
1
+ import {
2
+ REFERENCE_RAMP_ALT_COLOR,
3
+ REFERENCE_RAMP_MAX_HUE,
4
+ hslToRgb
5
+ } from "./chunk-PCZ4PTYC.js";
6
+
7
+ // src/walkEncoding.ts
8
+ import { packAbgr } from "@jbrowse/core/util/colorBits";
9
+ var WALK_FIELDS = [
10
+ { value: "progress", label: "Progress along the walk" },
11
+ { value: "walk", label: "One colour for the walk" },
12
+ { value: "reference", label: "Reference position" }
13
+ ];
14
+ var WALK_SCHEMES = [
15
+ { value: "grey", label: "Grey to black", ends: ["#a3a3a3", "#151515"] },
16
+ { value: "blue", label: "Cyan to navy", ends: ["#6ee0f0", "#0b2c7a"] },
17
+ { value: "red", label: "Yellow to red", ends: ["#ffd24a", "#b3121b"] },
18
+ { value: "purple", label: "Pink to plum", ends: ["#f5a3d8", "#5e1a6e"] },
19
+ { value: "green", label: "Lime to forest", ends: ["#b6e36c", "#0b5d3b"] },
20
+ { value: "rainbow", label: "Rainbow" }
21
+ ];
22
+ var FAMILIES = ["blue", "red", "purple", "green"];
23
+ var isField = (v) => WALK_FIELDS.some((f) => f.value === v);
24
+ var isScheme = (v) => WALK_SCHEMES.some((s) => s.value === v);
25
+ function resolveEncoding(layer, reference, picked, alone = true) {
26
+ const { field: askedField, scheme: askedScheme } = layer.color ?? {};
27
+ const field = isField(askedField) ? askedField : alone ? "progress" : "walk";
28
+ const family = reference ? "grey" : FAMILIES[picked % FAMILIES.length];
29
+ const scheme = isScheme(askedScheme) ? askedScheme === "rainbow" && field !== "reference" ? family : askedScheme : family;
30
+ return { field, scheme };
31
+ }
32
+ var BASE_T = 0.5;
33
+ var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
34
+ var toGamma = (c) => c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055;
35
+ function oklab(hex) {
36
+ const [r, g, b] = [1, 3, 5].map(
37
+ (i) => toLinear(Number.parseInt(hex.slice(i, i + 2), 16) / 255)
38
+ );
39
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
40
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
41
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
42
+ return [
43
+ 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
44
+ 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
45
+ 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s
46
+ ];
47
+ }
48
+ function oklabToRgb([L, a, b]) {
49
+ const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;
50
+ const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;
51
+ const s = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;
52
+ return [
53
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
54
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
55
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
56
+ ].map((c) => toGamma(Math.max(0, Math.min(1, c))) * 255);
57
+ }
58
+ function schemeRgb(scheme, t) {
59
+ const x = Math.max(0, Math.min(1, t));
60
+ const family = WALK_SCHEMES.find((s) => s.value === scheme);
61
+ if (!family || !("ends" in family)) {
62
+ return hslToRgb(x * REFERENCE_RAMP_MAX_HUE, 0.7, 0.5).map((c) => c * 255);
63
+ }
64
+ const from = oklab(family.ends[0]);
65
+ const to = oklab(family.ends[1]);
66
+ return oklabToRgb(from.map((v, i) => v + (to[i] - v) * x));
67
+ }
68
+ function schemeCss(scheme, t) {
69
+ const [r, g, b] = schemeRgb(scheme, t).map(Math.round);
70
+ return `rgb(${r}, ${g}, ${b})`;
71
+ }
72
+ function schemeColor(scheme, t) {
73
+ const [r, g, b] = schemeRgb(scheme, t).map(Math.round);
74
+ return packAbgr(r, g, b, 255);
75
+ }
76
+ function encodedColor({ field, scheme }, t) {
77
+ return field === "walk" ? schemeColor(scheme, BASE_T) : t === void 0 ? NO_VALUE_COLOR : schemeColor(scheme, t);
78
+ }
79
+ var NO_VALUE_COLOR = REFERENCE_RAMP_ALT_COLOR;
80
+ function encodingStops({ field, scheme }) {
81
+ return field === "walk" ? [{ offset: 0, color: schemeCss(scheme, BASE_T) }] : Array.from({ length: 7 }, (_, i) => ({
82
+ offset: i / 6,
83
+ color: schemeCss(scheme, i / 6)
84
+ }));
85
+ }
86
+ function encodingSwatchCss(encoding) {
87
+ const stops = encodingStops(encoding);
88
+ return stops.length === 1 ? stops[0].color : `linear-gradient(to right, ${stops.map((s) => `${s.color} ${s.offset * 100}%`).join(", ")})`;
89
+ }
90
+
91
+ export {
92
+ WALK_FIELDS,
93
+ WALK_SCHEMES,
94
+ resolveEncoding,
95
+ schemeRgb,
96
+ schemeCss,
97
+ schemeColor,
98
+ encodedColor,
99
+ NO_VALUE_COLOR,
100
+ encodingStops,
101
+ encodingSwatchCss
102
+ };