jbrowse-plugin-graphgenomeviewer 6.2.0 → 6.3.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.
- package/README.md +4 -3
- package/dist/chunks/ChooseWalksDialog-L6QKOT7M.js +2 -0
- package/dist/chunks/ChooseWalksDialog-L6QKOT7M.js.map +7 -0
- package/dist/chunks/{GbzBaseSyntenyAdapter-TLI5IUU7.js → GbzBaseSyntenyAdapter-KVJKGGQ4.js} +2 -2
- package/dist/chunks/{GbzBaseSyntenyAdapter-TLI5IUU7.js.map → GbzBaseSyntenyAdapter-KVJKGGQ4.js.map} +1 -1
- package/dist/chunks/{GraphGenomeView-5OPCROMQ.js → GraphGenomeView-VIKLXNQD.js} +2 -2
- package/dist/chunks/{GraphGenomeView-5OPCROMQ.js.map → GraphGenomeView-VIKLXNQD.js.map} +1 -1
- package/dist/chunks/GraphTrackSettingsDialog-MRMSH2FO.js +4 -0
- package/dist/chunks/{GraphTrackSettingsDialog-FGLLUIEE.js.map → GraphTrackSettingsDialog-MRMSH2FO.js.map} +1 -1
- package/dist/chunks/HighlightColorDialog-SABW5OMB.js +2 -0
- package/dist/chunks/HighlightColorDialog-SABW5OMB.js.map +7 -0
- package/dist/chunks/LinearGraphDisplay-AHCKWNFJ.js +2 -0
- package/dist/chunks/{LinearGraphDisplay-NBJHGOYX.js.map → LinearGraphDisplay-AHCKWNFJ.js.map} +1 -1
- package/dist/chunks/{MinigraphBubbleAdapter-LQUIL3MD.js → MinigraphBubbleAdapter-CAXB5FGR.js} +2 -2
- package/dist/chunks/{RgfaTabixAdapter-3BFNY4SB.js → RgfaTabixAdapter-GYRNCGT2.js} +2 -2
- package/dist/chunks/{bandage-layout-3AR6BCUD-I6CCWYSR.js → bandage-layout-3AR6BCUD-PYYNJEGI.js} +1 -1
- package/dist/chunks/{bandage-layout-3AR6BCUD-I6CCWYSR.js.map → bandage-layout-3AR6BCUD-PYYNJEGI.js.map} +1 -1
- package/dist/chunks/{chunk-O5EHYU3Y.js → chunk-2SIR336R.js} +2 -2
- package/dist/chunks/chunk-2SL675KP.js +3 -0
- package/dist/chunks/{chunk-NGQRKSHY.js.map → chunk-2SL675KP.js.map} +3 -3
- package/dist/chunks/chunk-A6GKF63C.js +2 -0
- package/dist/chunks/{chunk-ZKLOV6MW.js.map → chunk-A6GKF63C.js.map} +2 -2
- package/dist/chunks/chunk-B7GF3TC3.js +2 -0
- package/dist/chunks/chunk-B7GF3TC3.js.map +7 -0
- package/dist/chunks/chunk-B7KMMGFB.js +2 -0
- package/dist/chunks/chunk-B7KMMGFB.js.map +7 -0
- package/dist/chunks/{chunk-X24J6VF4.js → chunk-DILFGQIL.js} +1 -1
- package/dist/chunks/{chunk-X24J6VF4.js.map → chunk-DILFGQIL.js.map} +1 -1
- package/dist/chunks/{chunk-7MWOPEIC.js → chunk-EHV7EUMI.js} +1 -1
- package/dist/chunks/{chunk-7MWOPEIC.js.map → chunk-EHV7EUMI.js.map} +1 -1
- package/dist/chunks/chunk-GMSOU6VO.js +2 -0
- package/dist/chunks/chunk-GMSOU6VO.js.map +7 -0
- package/dist/chunks/{chunk-EKMGHBWM.js → chunk-KRXALLQG.js} +1 -1
- package/dist/chunks/{chunk-EKMGHBWM.js.map → chunk-KRXALLQG.js.map} +1 -1
- package/dist/chunks/{chunk-F7V6ZPKD.js → chunk-MYJYGSOH.js} +1 -1
- package/dist/chunks/{chunk-F7V6ZPKD.js.map → chunk-MYJYGSOH.js.map} +1 -1
- package/dist/chunks/chunk-WTOQRUK2.js +2 -0
- package/dist/chunks/chunk-WTOQRUK2.js.map +7 -0
- package/dist/chunks/{chunk-JYZAMHIP.js → chunk-WUGRVNUJ.js} +2 -2
- package/dist/chunks/{chunk-JYZAMHIP.js.map → chunk-WUGRVNUJ.js.map} +1 -1
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +6 -6
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
- package/package.json +2 -3
- package/src/GbzBaseSyntenyAdapter/configSchema.ts +1 -1
- package/src/GraphGenomeView/components/ChooseWalksDialog.tsx +6 -7
- package/src/GraphGenomeView/components/HighlightColorDialog.tsx +117 -0
- package/src/GraphGenomeView/components/TubeMapOverlay.tsx +1 -1
- package/src/GraphGenomeView/model.test.ts +107 -31
- package/src/GraphGenomeView/pane/fitViews.ts +8 -5
- package/src/GraphGenomeView/pane/graphViews.ts +11 -1
- package/src/GraphGenomeView/pane/hostViews.ts +1 -1
- package/src/GraphGenomeView/pane/keepInView.ts +62 -0
- package/src/GraphGenomeView/pane/launchActions.ts +159 -184
- package/src/GraphGenomeView/pane/loadActions.ts +3 -0
- package/src/GraphGenomeView/pane/paneBase.ts +9 -3
- package/src/GraphGenomeView/pane/renderingActions.ts +11 -1
- package/src/GraphGenomeView/pane/settingActions.ts +38 -0
- package/src/GraphGenomeView/renderPipeline.test.ts +4 -1
- package/src/GraphGenomeView/renderer/GraphRenderer.ts +2 -2
- package/src/GraphGenomeView/viewModel.ts +1 -1
- package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +12 -5
- package/src/LinearGraphDisplay/configSchema.ts +8 -0
- package/src/LinearGraphDisplay/model.ts +39 -33
- package/src/hoverSync/GraphNodeHighlight.tsx +3 -3
- package/src/version.ts +1 -1
- package/dist/chunks/ChooseWalksDialog-GVQLSGHX.js +0 -2
- package/dist/chunks/ChooseWalksDialog-GVQLSGHX.js.map +0 -7
- package/dist/chunks/GraphTrackSettingsDialog-FGLLUIEE.js +0 -4
- package/dist/chunks/LinearGraphDisplay-NBJHGOYX.js +0 -2
- package/dist/chunks/chunk-LZUNK4MQ.js +0 -2
- package/dist/chunks/chunk-LZUNK4MQ.js.map +0 -7
- package/dist/chunks/chunk-NGQRKSHY.js +0 -3
- package/dist/chunks/chunk-XWGKHQYO.js +0 -2
- package/dist/chunks/chunk-XWGKHQYO.js.map +0 -7
- package/dist/chunks/chunk-ZKLOV6MW.js +0 -2
- /package/dist/chunks/{MinigraphBubbleAdapter-LQUIL3MD.js.map → MinigraphBubbleAdapter-CAXB5FGR.js.map} +0 -0
- /package/dist/chunks/{RgfaTabixAdapter-3BFNY4SB.js.map → RgfaTabixAdapter-GYRNCGT2.js.map} +0 -0
- /package/dist/chunks/{chunk-O5EHYU3Y.js.map → chunk-2SIR336R.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["global-externals:@mui/material/SvgIcon", "global-externals:mobx", "global-externals:@jbrowse/core/util/groupKeys", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/utils/createSvgIcon.mjs", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-6ZNQJ5ZD.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-NNODIW4U.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-3S3YVOJ7.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-MLSWIMZO.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-FP4H7SFT.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-GJMC3PGM.js", "../../src/launchFromGraph/contributors.ts", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/CompareArrows.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/HighlightAlt.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/LineStyle.mjs", "../../src/launchFromGraph/graphMenuItems.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-TEDQJPMI.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-RVS2QCOX.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-TZFWUT2C.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-LOEA5IHZ.js", "../../node_modules/.pnpm/@jbrowse+tubemap-core@0.2.1/node_modules/@jbrowse/tubemap-core/src/types.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@0.2.1/node_modules/@jbrowse/tubemap-core/src/panSN.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@0.2.1/node_modules/@jbrowse/tubemap-core/src/layout.ts", "../../node_modules/.pnpm/@jbrowse+tubemap-core@0.2.1/node_modules/@jbrowse/tubemap-core/src/geometry.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-W2I4DOL4.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-L3O7AWLI.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-HNQPEMYE.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-SZNZ2T6D.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-MP7LXLWV.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-ZJQ6H3AR.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XV4P5KEQ.js", "../../src/GraphGenomeView/walkRowGroups.ts", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-WOO7QYKB.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-V3MD3IZB.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-O2ANJQVH.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4BYTEJGW.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-2WNBVB55.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-2LQ5BWT7.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-DRA7733Q.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-GQ2AOHU4.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-733L2TS6.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KCRL5JB2.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-OWFPAIJI.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-W253V6RR.js", "../../node_modules/.pnpm/@jbrowse+bandage-core@8.0.1/node_modules/@jbrowse/bandage-core/dist/tubeMap/deviations.js", "../../src/GraphGenomeView/repeats/walkCalls.ts", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Settings.mjs"],
|
|
4
|
+
"sourcesContent": ["module.exports = JBrowseExports[\"@mui/material/SvgIcon\"];", "module.exports = JBrowseExports[\"mobx\"];", "module.exports = JBrowseExports[\"@jbrowse/core/util/groupKeys\"];", "'use client';\n\nexport { createSvgIcon as default } from '@mui/material/SvgIcon';", "import {\n REFERENCE_RAMP_MAX_HUE\n} from \"./chunk-HBEKUQO4.js\";\n\n// src/referenceRampCss.ts\nfunction rampHueCss(hue) {\n return `hsl(${hue}, 70%, 50%)`;\n}\nfunction rampHue(bp, domain) {\n const frac = (bp - domain.start) / (domain.end - domain.start);\n return Math.max(0, Math.min(1, frac)) * REFERENCE_RAMP_MAX_HUE;\n}\nvar HUE_STOP_DEG = 30;\nfunction rampStops({ start, bp, reversed }, domain) {\n const low = rampHue(start, domain);\n const high = rampHue(start + bp, domain);\n if (high - low < 1) {\n return [(low + high) / 2];\n }\n const n = Math.ceil((high - low) / HUE_STOP_DEG);\n return Array.from(\n { length: n + 1 },\n (_, i) => rampHue(start + bp * (reversed ? n - i : i) / n, domain)\n );\n}\nvar RAMP_GRADIENT_STOPS = Array.from({ length: 7 }, (_, i) => ({\n offset: i / 6,\n color: rampHueCss(i / 6 * REFERENCE_RAMP_MAX_HUE)\n}));\nvar RAMP_GRADIENT_CSS = `linear-gradient(to right, ${RAMP_GRADIENT_STOPS.map(\n (s) => `${s.color} ${s.offset * 100}%`\n).join(\", \")})`;\n\nexport {\n rampHueCss,\n rampHue,\n rampStops,\n RAMP_GRADIENT_STOPS,\n RAMP_GRADIENT_CSS\n};\n", "// src/el.ts\nfunction el(tag, attrs = {}, ...children) {\n return {\n tag,\n attrs,\n children: children.filter((c) => !!c || c === \"\")\n };\n}\nfunction escapeText(s) {\n return s.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n}\nfunction escapeAttr(s) {\n return escapeText(s).replaceAll('\"', \""\");\n}\nfunction serializeEl(node) {\n if (typeof node === \"string\") {\n return escapeText(node);\n }\n const attrs = Object.entries(node.attrs).filter(([, v]) => v !== void 0).map(([k, v]) => ` ${k}=\"${escapeAttr(String(v))}\"`).join(\"\");\n return `<${node.tag}${attrs}>${node.children.map(serializeEl).join(\"\")}</${node.tag}>`;\n}\n\nexport {\n el,\n serializeEl\n};\n", "import {\n el\n} from \"./chunk-NNODIW4U.js\";\n\n// src/genes/exonOutline.ts\nvar EXON_COLOR = \"#daa520\";\nvar EXON_GAP_PX = 1;\nvar EXON_LINE_PX = 2;\nvar MIN_LANE_PX = 4;\nfunction exonStretches(pins, halfWidthPx, lift, pathOf = (d) => d) {\n const inkPx = (nodeId) => {\n const own = halfWidthPx(nodeId) * 2;\n return lift?.nodeIds.has(nodeId) ? Math.max(own, lift.walks.length * MIN_LANE_PX) : own;\n };\n return pins.flatMap(\n (pin) => pin.exonsByNode.map(({ nodeId, d }) => ({\n key: `${pin.gene.name}-${pin.gene.start}-${nodeId}`,\n d: pathOf(d),\n inner: inkPx(nodeId) + 2 * EXON_GAP_PX\n }))\n );\n}\nfunction exonOutlineTree(stretches, o) {\n if (stretches.length === 0) {\n return void 0;\n }\n const stroke = (s, color, width) => el(\"path\", {\n d: s.d,\n fill: \"none\",\n stroke: color,\n \"stroke-width\": width,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"vector-effect\": o.transform ? \"non-scaling-stroke\" : void 0\n });\n return el(\n \"g\",\n {},\n el(\n \"mask\",\n {\n id: o.id,\n maskUnits: \"userSpaceOnUse\",\n x: 0,\n y: 0,\n width: o.width,\n height: o.height\n },\n el(\n \"g\",\n { transform: o.transform },\n ...stretches.map((s) => stroke(s, \"#fff\", s.inner + 2 * EXON_LINE_PX)),\n ...stretches.map((s) => stroke(s, \"#000\", s.inner))\n )\n ),\n el(\"rect\", {\n width: o.width,\n height: o.height,\n fill: EXON_COLOR,\n mask: `url(#${o.id})`\n })\n );\n}\n\nexport {\n EXON_COLOR,\n exonStretches,\n exonOutlineTree\n};\n", "import {\n baseEdgeCurves\n} from \"./chunk-WFB5TXRA.js\";\nimport {\n curveBounds,\n pathRibbonOffsets\n} from \"./chunk-2CVHXFK7.js\";\n\n// src/util/SpatialIndex.ts\nvar FALLBACK_CELL_SIZE = 50;\nfunction meanExtentCellSize(extentTotal, count) {\n return count > 0 ? Math.max(1, extentTotal / count) : FALLBACK_CELL_SIZE;\n}\nfunction rowPitchOf(boxes) {\n const distinct = /* @__PURE__ */ new Set();\n let min = Infinity;\n let max = -Infinity;\n for (const box of boxes) {\n distinct.add(box.minY);\n min = Math.min(min, box.minY);\n max = Math.max(max, box.minY);\n }\n return distinct.size > 1 ? (max - min) / (distinct.size - 1) : void 0;\n}\nfunction cellSizeFrom(boxes, extentX, extentY) {\n const x = meanExtentCellSize(extentX, boxes.length);\n return {\n x,\n y: extentY > 0 ? meanExtentCellSize(extentY, boxes.length) : rowPitchOf(boxes) ?? x\n };\n}\nfunction resolveCellSize(given, boxes, extentX, extentY) {\n return given === void 0 ? cellSizeFrom(boxes, extentX, extentY) : typeof given === \"number\" ? { x: given, y: given } : given;\n}\nfunction getOrCreateCell(cells, cx, cy) {\n let row = cells.get(cx);\n if (!row) {\n row = /* @__PURE__ */ new Map();\n cells.set(cx, row);\n }\n let cell = row.get(cy);\n if (!cell) {\n cell = [];\n row.set(cy, cell);\n }\n return cell;\n}\nfunction addToGrid(cells, cellSize, minX, minY, maxX, maxY, entry) {\n const cx0 = Math.floor(minX / cellSize.x);\n const cx1 = Math.floor(maxX / cellSize.x);\n const cy0 = Math.floor(minY / cellSize.y);\n const cy1 = Math.floor(maxY / cellSize.y);\n for (let cx = cx0; cx <= cx1; cx++) {\n for (let cy = cy0; cy <= cy1; cy++) {\n getOrCreateCell(cells, cx, cy).push(entry);\n }\n }\n}\nfunction queryGrid(cells, cellSize, x, y, radiusX, radiusY) {\n const cx0 = Math.floor((x - radiusX) / cellSize.x);\n const cx1 = Math.floor((x + radiusX) / cellSize.x);\n const cy0 = Math.floor((y - radiusY) / cellSize.y);\n const cy1 = Math.floor((y + radiusY) / cellSize.y);\n const results = [];\n const seen = /* @__PURE__ */ new Set();\n for (let cx = cx0; cx <= cx1; cx++) {\n const row = cells.get(cx);\n if (row) {\n for (let cy = cy0; cy <= cy1; cy++) {\n const cell = row.get(cy);\n if (cell) {\n for (const entry of cell) {\n if (!seen.has(entry)) {\n seen.add(entry);\n results.push(entry);\n }\n }\n }\n }\n }\n }\n return results;\n}\nvar SpatialIndex = class {\n constructor(nodePositions, cellSize) {\n this.cells = /* @__PURE__ */ new Map();\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (const [nodeId, segments] of Object.entries(nodePositions)) {\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n const next = segments[i + 1];\n const minX = Math.min(seg.x, next.x);\n const minY = Math.min(seg.y, next.y);\n const maxX = Math.max(seg.x, next.x);\n const maxY = Math.max(seg.y, next.y);\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ entry: { nodeId, segmentIdx: i }, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(\n this.cells,\n this.cellSize,\n b.minX,\n b.minY,\n b.maxX,\n b.maxY,\n b.entry\n );\n }\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\nvar EdgeSpatialIndex = class {\n constructor(nodePositions, graph, drawPaths, axis, cellSize, deletions, version = 0, routes, stranded = false) {\n this.cells = /* @__PURE__ */ new Map();\n this.edgeCurves = baseEdgeCurves(\n nodePositions,\n graph,\n axis,\n deletions,\n version,\n routes,\n stranded\n );\n const boxes = [];\n let extentX = 0;\n let extentY = 0;\n for (let ei = 0; ei < graph.edges.length; ei++) {\n const edge = graph.edges[ei];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n const curves = this.edgeCurves.get(ei);\n if (fromSegments?.length && toSegments?.length && curves) {\n let { minX, minY, maxX, maxY } = curveBounds(curves);\n const numPaths = edge.pathIds?.length ?? 0;\n if (drawPaths && numPaths > 0) {\n let padX = 0;\n let padY = 0;\n for (const o of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n padX = Math.max(padX, Math.abs(o.x));\n padY = Math.max(padY, Math.abs(o.y));\n }\n minX -= padX;\n minY -= padY;\n maxX += padX;\n maxY += padY;\n }\n extentX += maxX - minX;\n extentY += maxY - minY;\n boxes.push({ ei, minX, minY, maxX, maxY });\n }\n }\n this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);\n for (const b of boxes) {\n addToGrid(this.cells, this.cellSize, b.minX, b.minY, b.maxX, b.maxY, b.ei);\n }\n }\n getCurves(ei) {\n return this.edgeCurves.get(ei);\n }\n query(x, y, radiusX, radiusY = radiusX) {\n return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);\n }\n};\n\nexport {\n SpatialIndex,\n EdgeSpatialIndex\n};\n", "import {\n EdgeSpatialIndex,\n SpatialIndex\n} from \"./chunk-MLSWIMZO.js\";\nimport {\n pathRibbonOffsets,\n translateCurves,\n yToXOf\n} from \"./chunk-2CVHXFK7.js\";\n\n// src/util/hitDetection.ts\nfunction distanceToSegment(px, py, x1, y1, x2, y2) {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return Math.hypot(px - x1, py - y1);\n }\n const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / lenSq));\n return Math.hypot(px - (x1 + t * dx), py - (y1 + t * dy));\n}\nfunction distanceToCubicBezier(px, py, x1, y1, cx1, cy1, cx2, cy2, x2, y2) {\n let minDist = Infinity;\n const samples = 20;\n let lastX = x1;\n let lastY = y1;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const u = 1 - t;\n const bx = u * u * u * x1 + 3 * u * u * t * cx1 + 3 * u * t * t * cx2 + t * t * t * x2;\n const by = u * u * u * y1 + 3 * u * u * t * cy1 + 3 * u * t * t * cy2 + t * t * t * y2;\n minDist = Math.min(minDist, distanceToSegment(px, py, lastX, lastY, bx, by));\n lastX = bx;\n lastY = by;\n }\n return minDist;\n}\nfunction distanceToBezierCurve(px, py, c) {\n return distanceToCubicBezier(\n px,\n py,\n c.x0,\n c.y0,\n c.cx0,\n c.cy0,\n c.cx1,\n c.cy1,\n c.x1,\n c.y1\n );\n}\nfunction distanceToEdgeCurves(px, py, curves, yToX = 1) {\n let minDist = Infinity;\n for (const c of curves) {\n const d = distanceToBezierCurve(\n px,\n py,\n yToX === 1 ? c : {\n x0: c.x0,\n y0: c.y0 * yToX,\n cx0: c.cx0,\n cy0: c.cy0 * yToX,\n cx1: c.cx1,\n cy1: c.cy1 * yToX,\n x1: c.x1,\n y1: c.y1 * yToX\n }\n );\n if (d < minDist) {\n minDist = d;\n }\n }\n return minDist;\n}\nvar nodeCache = /* @__PURE__ */ new WeakMap();\nfunction getSpatialIndex(nodePositions, version) {\n const cached = nodeCache.get(nodePositions);\n if (cached?.version === version) {\n return cached.index;\n }\n const index = new SpatialIndex(nodePositions);\n nodeCache.set(nodePositions, { version, index });\n return index;\n}\nvar edgeCache = /* @__PURE__ */ new WeakMap();\nfunction getEdgeSpatialIndex(nodePositions, graph, drawPaths, axis, version, deletions, routes, stranded = false) {\n const cached = edgeCache.get(nodePositions);\n if (cached?.graph === graph && cached.drawPaths === drawPaths && cached.scaleX === axis.scaleX && cached.scaleY === axis.scaleY && cached.version === version && cached.deletions === deletions && cached.routes === routes && cached.stranded === stranded) {\n return cached.index;\n }\n const index = new EdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n void 0,\n deletions,\n version,\n routes,\n stranded\n );\n edgeCache.set(nodePositions, {\n graph,\n drawPaths,\n scaleX: axis.scaleX,\n scaleY: axis.scaleY,\n version,\n index,\n deletions,\n routes,\n stranded\n });\n return index;\n}\nvar MIN_NODE_REACH_PX = 5;\nfunction findHoveredNode(nodePositions, graphX, graphY, axis, version = 0, ink) {\n const yToX = yToXOf(axis);\n const index = getSpatialIndex(nodePositions, version);\n const reach = (px) => Math.max(MIN_NODE_REACH_PX, px) / axis.scaleX;\n const queryReach = reach(ink?.maxHalfWidthPx ?? 0);\n const candidates = index.query(graphX, graphY, queryReach, queryReach / yToX);\n let hovered = null;\n let best = Infinity;\n for (const { nodeId, segmentIdx } of candidates) {\n const segments = nodePositions[nodeId];\n const dist = distanceToSegment(\n graphX,\n graphY * yToX,\n segments[segmentIdx].x,\n segments[segmentIdx].y * yToX,\n segments[segmentIdx + 1].x,\n segments[segmentIdx + 1].y * yToX\n );\n if (dist < best && dist < reach(ink?.halfWidthPx(nodeId) ?? 0)) {\n best = dist;\n hovered = nodeId;\n }\n }\n return hovered;\n}\nfunction segmentMeetsBox(a, b, box) {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n let t0 = 0;\n let t1 = 1;\n for (const [p, q] of [\n [-dx, a.x - box.x0],\n [dx, box.x1 - a.x],\n [-dy, a.y - box.y0],\n [dy, box.y1 - a.y]\n ]) {\n if (p === 0) {\n if (q < 0) {\n return false;\n }\n } else if (p < 0) {\n t0 = Math.max(t0, q / p);\n } else {\n t1 = Math.min(t1, q / p);\n }\n }\n return t0 <= t1;\n}\nfunction nodesUnderBox(nodePositions, t, version = 0) {\n const index = getSpatialIndex(nodePositions, version);\n const screen = (p) => ({\n x: p.x * t.scaleX + t.translateX,\n y: p.y * t.scaleY + t.translateY\n });\n return (box) => {\n const hits = /* @__PURE__ */ new Set();\n const candidates = index.query(\n ((box.x0 + box.x1) / 2 - t.translateX) / t.scaleX,\n ((box.y0 + box.y1) / 2 - t.translateY) / t.scaleY,\n Math.abs((box.x1 - box.x0) / 2 / t.scaleX),\n Math.abs((box.y1 - box.y0) / 2 / t.scaleY)\n );\n for (const { nodeId, segmentIdx } of candidates) {\n const line = nodePositions[nodeId];\n if (!hits.has(nodeId) && segmentMeetsBox(\n screen(line[segmentIdx]),\n screen(line[segmentIdx + 1]),\n box\n )) {\n hits.add(nodeId);\n }\n }\n return hits;\n };\n}\nfunction findHoveredEdge(nodePositions, graph, graphX, graphY, axis, drawPaths, version = 0, deletions, hiddenEdges, deletionRoutes, stranded = false) {\n const yToX = yToXOf(axis);\n const edgeThreshold = 10 / axis.scaleX;\n const edgeIndex = getEdgeSpatialIndex(\n nodePositions,\n graph,\n drawPaths,\n axis,\n version,\n deletions,\n deletionRoutes,\n stranded\n );\n const candidates = edgeIndex.query(\n graphX,\n graphY,\n edgeThreshold,\n edgeThreshold / yToX\n );\n let hovered = null;\n let best = edgeThreshold;\n for (const edgeIdx of candidates) {\n const edge = graph.edges[edgeIdx];\n const fromSegments = nodePositions[edge.from];\n const toSegments = nodePositions[edge.to];\n if (!fromSegments?.length || !toSegments?.length || hiddenEdges?.has(edgeIdx)) {\n continue;\n }\n const numPaths = edge.pathIds?.length ?? 0;\n const baseCurves = edgeIndex.getCurves(edgeIdx);\n if (!baseCurves) {\n continue;\n }\n let dist;\n if (!drawPaths || numPaths === 0) {\n dist = distanceToEdgeCurves(graphX, graphY * yToX, baseCurves, yToX);\n } else {\n let minDist = Infinity;\n for (const offset of pathRibbonOffsets(\n fromSegments,\n toSegments,\n numPaths,\n axis\n )) {\n const curves = offset.x === 0 && offset.y === 0 ? baseCurves : translateCurves(baseCurves, offset.x, offset.y);\n const d = distanceToEdgeCurves(graphX, graphY * yToX, curves, yToX);\n if (d < minDist) {\n minDist = d;\n }\n }\n dist = minDist;\n }\n if (dist < best) {\n best = dist;\n hovered = edgeIdx;\n }\n }\n return hovered;\n}\n\nexport {\n distanceToSegment,\n distanceToCubicBezier,\n findHoveredNode,\n nodesUnderBox,\n findHoveredEdge\n};\n", "import {\n nodesUnderBox\n} from \"./chunk-FP4H7SFT.js\";\nimport {\n nodeLabelBudget,\n placeSizeLabels,\n rowLabelBox,\n sizeLabelCandidates\n} from \"./chunk-3ZZSX5HN.js\";\nimport {\n LABEL_CHAR_PX,\n LABEL_PAD,\n LABEL_PX,\n occupancy,\n placeLabels\n} from \"./chunk-AB35TJST.js\";\n\n// src/labelLayout.ts\nvar HALO_FACTOR = 3.4;\nvar LEGEND_INSET_PX = 6;\nvar ROUTE_STACK = 8;\nvar GENE_PIN_DROP_PX = 18;\nvar GENE_STACK = 2;\nvar TOPMOST_BASELINE = LABEL_PX + LABEL_PAD;\nfunction geneCoverageNote(pin) {\n const length = pin.gene.end - pin.gene.start;\n if (pin.covered >= 0.98) {\n return void 0;\n }\n const [per, unit] = length >= 1e6 ? [1e6, \"Mb\"] : length >= 1e3 ? [1e3, \"kb\"] : [1, \"bp\"];\n const amount = (bp) => +(bp / per).toFixed(per === 1 ? 0 : 1);\n return `${amount(pin.covered * length)} of ${amount(length)} ${unit}`;\n}\nfunction geneLabelCandidates(pins, screen, contigThickness, nodesUnder) {\n const ink = contigThickness / 2;\n return byExtent(pins, (pin) => pin.gene.end - pin.gene.start).map((pin) => {\n const { x, y } = screen(pin.at);\n const note = geneCoverageNote(pin);\n return {\n item: pin,\n x,\n y: y + contigThickness + GENE_PIN_DROP_PX,\n text: note ? `${pin.gene.name} \\xB7 ${note}` : pin.gene.name,\n fallback: note ? `${pin.gene.name} \\u2026` : void 0,\n stack: GENE_STACK,\n fits: (box) => [\n ...nodesUnder({\n x0: box.x0 - ink,\n x1: box.x1 + ink,\n y0: box.y0 - ink,\n y1: box.y1 + ink\n })\n ].every((id) => pin.nodeIds.has(id))\n };\n });\n}\nfunction byExtent(items, extent) {\n return [...items].sort((a, b) => extent(b) - extent(a));\n}\nfunction layoutLabels(m) {\n const { paneWidth: width, canvasHeight: height, translateX, translateY } = m;\n const { scaleX, scaleY } = m.axisScale;\n const frame = { width, height };\n const screen = (p) => ({\n x: p.x * scaleX + translateX,\n y: p.y * scaleY + translateY\n });\n const reserved = m.drawnRowLabels.map(\n ({ label, y }) => rowLabelBox(label, y * scaleY + translateY)\n );\n const stripPx = m.referenceStripZonePx ?? 0;\n if (stripPx > 0) {\n reserved.push({ x0: 0, x1: width, y0: 0, y1: stripPx });\n }\n if (m.legendSize.width > 0) {\n reserved.push({\n x0: width - LEGEND_INSET_PX - m.legendSize.width,\n x1: width,\n y0: 0,\n y1: stripPx + LEGEND_INSET_PX + m.legendSize.height\n });\n }\n if (m.poppedFrom) {\n reserved.push({\n x0: 0,\n x1: 60 + m.poppedFrom.label.length * LABEL_CHAR_PX * 1.2,\n y0: 0,\n y1: 44\n });\n }\n const take = occupancy(frame, reserved);\n const onRows = m.drawnRowLabels.length > 0;\n const rowsTop = onRows ? Math.min(...m.drawnRowLabels.map((r) => r.y)) : Infinity;\n const halo = m.contigThickness * HALO_FACTOR;\n const byBubble = byExtent(m.bubbleHalos, (h) => h.members);\n const bubbles = placeLabels(\n byBubble.map((h) => {\n const { x, y } = screen({\n x: h.labelAt.x,\n y: Math.min(h.labelAt.y, rowsTop)\n });\n const baseline = y - halo / 2 - 6;\n return {\n item: h,\n x,\n y: onRows ? Math.max(baseline, TOPMOST_BASELINE) : baseline,\n text: h.label\n };\n }),\n frame,\n take\n );\n const genes = placeLabels(\n geneLabelCandidates(\n m.genePins,\n screen,\n m.contigThickness,\n nodesUnderBox(\n m.nodePositions ?? {},\n { scaleX, scaleY, translateX, translateY },\n m.positionsVersion\n )\n ),\n frame,\n take\n );\n const sizeCandidates = m.nodePositions && m.labelsNodeSizes ? sizeLabelCandidates({\n nodePositions: m.nodePositions,\n nodeLengths: m.nodeLengths,\n deletions: m.deletions,\n deletionRoutes: m.deletionRoutes,\n stranded: m.stranded,\n alleleDeletions: m.alleleDeletions,\n axis: m.axisScale,\n translateX,\n translateY,\n width,\n height,\n version: m.positionsVersion\n }) : { deletions: [], nodes: [] };\n const deletionLabels = placeSizeLabels(sizeCandidates.deletions, take);\n const routes = placeLabels(\n byBubble.flatMap(\n (h) => h.routes.map((route) => {\n const { x, y } = screen(route.at);\n return {\n item: { halo: h, route },\n x,\n y: y + 4,\n text: route.text,\n stack: ROUTE_STACK\n };\n })\n ),\n frame,\n take\n );\n const nodeLabels = placeSizeLabels(\n sizeCandidates.nodes,\n take,\n nodeLabelBudget(width, height)\n );\n return {\n bubbles,\n genes,\n routes,\n sizes: [...deletionLabels, ...nodeLabels]\n };\n}\n\nexport {\n HALO_FACTOR,\n LEGEND_INSET_PX,\n geneCoverageNote,\n geneLabelCandidates,\n layoutLabels\n};\n", "import { isAnchored } from '@jbrowse/bandage-core/anchoredNodes'\nimport {\n panSNContig,\n panSNHaplotype,\n panSNSample,\n} from '@jbrowse/bandage-core/pansn'\n\nimport type { AnchoredNode } from '@jbrowse/bandage-core/anchoredNodes'\nimport type { Graph, GraphNode } from '@jbrowse/bandage-core/types'\n\nexport interface GraphLocation {\n // PanSN sample name off the node's own stable sequence. The assembly that\n // contributed the sequence, which is a *name*, not a resolved assembly \u2014 see\n // resolveContributors.\n sample: string\n // `sample#hap` where the stable name states a haplotype (HPRC release 2.1\n // names every node `NA20809#2#CM094351.1`), so a sample loaded as two\n // assemblies opens the right one; undefined where it states none\n haplotype: string | undefined\n refName: string\n start: number\n end: number\n}\n\n// Where a node's own sequence lives, in the coordinates of the assembly that\n// contributed it. rGFA states this on every segment: SN names the stable\n// sequence and SO the offset on it, so this is exact at every rank.\n//\n// It is the other question from nodeReferenceSpan, which asks where a node sits\n// on the *reference* axis and can only approximate that off the backbone. A\n// rank>0 node has an exact coordinate of its own; what it has no coordinate for\n// is the reference.\nexport function nodeOwnLocation(node: GraphNode): GraphLocation | undefined {\n return isAnchored(node) ? anchoredNodeLocation(node) : undefined\n}\n\nfunction anchoredNodeLocation(node: AnchoredNode): GraphLocation {\n return {\n sample: panSNSample(node.stable.refName),\n haplotype: panSNHaplotype(node.stable.refName),\n refName: panSNContig(node.stable.refName),\n start: node.stable.start,\n end: node.stable.start + node.length,\n }\n}\n\nexport interface Contributor extends GraphLocation {\n // lowest rank this assembly holds here: 0 means it is the reference backbone\n rank: number\n nodeCount: number\n}\n\ninterface Span {\n start: number\n end: number\n}\n\n// The widest run of spans with no gap larger than `maxGap`, which is the locus\n// this assembly contributes *here*. A bare union of every span would be wrong\n// on a graph where a sample also contributes sequence from a distant\n// duplication: the union then reads as a multi-megabase locus, and a linear view\n// launched at it shows neither end.\nfunction widestCluster(spans: Span[], maxGap: number) {\n const sorted = [...spans].sort((a, b) => a.start - b.start)\n let best: Span | undefined\n let current: Span | undefined\n for (const span of sorted) {\n current =\n current && span.start - current.end <= maxGap\n ? { start: current.start, end: Math.max(current.end, span.end) }\n : { start: span.start, end: span.end }\n if (!best || current.end - current.start > best.end - best.start) {\n best = current\n }\n }\n return best\n}\n\ninterface Group {\n sample: string\n haplotype: string | undefined\n refName: string\n rank: number\n spans: Span[]\n}\n\nfunction groupKey(loc: GraphLocation) {\n return `${loc.haplotype ?? loc.sample}\\u0000${loc.refName}`\n}\n\n// Every assembly with a segment in this graph, and the locus each one covers on\n// its own coordinates.\n//\n// This is what makes a launch out of the graph possible at all: the graph names\n// its contributors in the data (rGFA's SN tag), so a node, a row and the graph\n// as a whole can each say which assembly they belong to without consulting an\n// alignment.\n//\n// Ordered reference-first, then by name, so the row order matches\n// sampleRowLayout's and neither reshuffles as the window moves.\nexport function contributingAssemblies(\n graph: Graph,\n { maxGap = Infinity }: { maxGap?: number } = {},\n): Contributor[] {\n const groups = new Map<string, Group>()\n for (const node of graph.nodes) {\n if (isAnchored(node)) {\n const loc = anchoredNodeLocation(node)\n const key = groupKey(loc)\n const group = groups.get(key)\n if (group) {\n group.spans.push({ start: loc.start, end: loc.end })\n group.rank = Math.min(group.rank, node.stable.rank)\n } else {\n groups.set(key, {\n sample: loc.sample,\n haplotype: loc.haplotype,\n refName: loc.refName,\n rank: node.stable.rank,\n spans: [{ start: loc.start, end: loc.end }],\n })\n }\n }\n }\n\n // One entry per assembly (a haplotype where the names state one, else the\n // sample): an assembly contributing on several contigs is launched at the\n // contig it contributes most of, since a linear view opens on one region.\n const bySample = new Map<string, Contributor>()\n for (const group of groups.values()) {\n const span = widestCluster(group.spans, maxGap)\n if (span) {\n const candidate = {\n sample: group.sample,\n haplotype: group.haplotype,\n refName: group.refName,\n start: span.start,\n end: span.end,\n rank: group.rank,\n nodeCount: group.spans.length,\n }\n const key = group.haplotype ?? group.sample\n const existing = bySample.get(key)\n if (!existing || candidate.nodeCount > existing.nodeCount) {\n bySample.set(key, candidate)\n }\n }\n }\n\n // Reference first, then by name: the same order sampleRowLayout gives its\n // rows, so the menu lists the assemblies in the order they are stacked on\n // screen. Sorting by rank instead would order them by minigraph's build\n // order, which is not what the labels beside the drawing say.\n return [...bySample.values()].sort(\n (a, b) =>\n Number(a.rank !== 0) - Number(b.rank !== 0) ||\n a.sample.localeCompare(b.sample) ||\n (a.haplotype ?? '').localeCompare(b.haplotype ?? ''),\n )\n}\n\n// The assembly a location opens on: its haplotype's where the name states one\n// and the session holds it, else its sample's. A session holding both\n// haplotypes of a sample opens the right one; one holding a haplotype under\n// the bare sample name still opens it.\nexport function resolveLocationAssembly(\n resolve: (sample: string) => string | undefined,\n loc: Pick<GraphLocation, 'sample' | 'haplotype'>,\n) {\n const byHaplotype =\n loc.haplotype === undefined ? undefined : resolve(loc.haplotype)\n return byHaplotype ?? resolve(loc.sample)\n}\n\n// Contributors that name an assembly this session has loaded, which are the\n// only ones a linear or synteny view can open on.\n//\n// The two cases this filters apart are both normal. An E. coli pangenome demo\n// loads every strain as its own assembly, so every contributor resolves and the\n// whole graph is navigable. An HPRC graph names hundreds of haplotypes that no\n// session would ever load as assemblies, so only the reference resolves \u2014\n// there the reference projection (nodeReferenceSpan) is the way back to a\n// coordinate, not this.\n//\n// `resolve` is a name lookup rather than a list of names, because a PanSN sample\n// is the *graph's* spelling and need not be the assembly's. HPRC's graph writes\n// `CHM13`, and the assembly holding that sequence is UCSC's `hs1`, with CHM13\n// among its aliases; matching on names alone leaves that donor unopenable unless\n// the reader renames their assembly after the graph. The resolved (canonical)\n// name replaces the sample, so a launch opens the assembly the session knows.\nexport function resolveContributors(\n contributors: Contributor[],\n resolve: (sample: string) => string | undefined,\n) {\n return contributors.flatMap(c => {\n const sample = resolveLocationAssembly(resolve, c)\n return sample === undefined ? [] : [{ ...c, sample }]\n })\n}\n\n// 1-based inclusive, which is what a locstring means. Unformatted digits: this\n// is parsed, not read. locLabel is the one people read.\nexport function locString(loc: GraphLocation) {\n return `${loc.refName}:${loc.start + 1}-${loc.end}`\n}\n\nexport function locLabel(loc: { refName: string; start: number; end: number }) {\n return `${loc.refName}:${(loc.start + 1).toLocaleString()}-${loc.end.toLocaleString()}`\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M9.01 14H2v2h7.01v3L13 15l-3.99-4zm5.98-1v-3H22V8h-7.01V5L11 9z\"\n}), 'CompareArrows');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M17 5h-2V3h2zm-2 16h2v-2.59L19.59 21 21 19.59 18.41 17H21v-2h-6zm4-12h2V7h-2zm0 4h2v-2h-2zm-8 8h2v-2h-2zM7 5h2V3H7zM3 17h2v-2H3zm2 4v-2H3c0 1.1.9 2 2 2M19 3v2h2c0-1.1-.9-2-2-2m-8 2h2V3h-2zM3 9h2V7H3zm4 12h2v-2H7zm-4-8h2v-2H3zm0-8h2V3c-1.1 0-2 .9-2 2\"\n}), 'HighlightAlt');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M3 16h5v-2H3zm6.5 0h5v-2h-5zm6.5 0h5v-2h-5zM3 20h2v-2H3zm4 0h2v-2H7zm4 0h2v-2h-2zm4 0h2v-2h-2zm4 0h2v-2h-2zM3 12h8v-2H3zm10 0h8v-2h-8zM3 4v4h18V4z\"\n}), 'LineStyle');", "import CompareArrowsIcon from '@mui/icons-material/CompareArrows'\nimport HighlightAltIcon from '@mui/icons-material/HighlightAlt'\nimport LineStyleIcon from '@mui/icons-material/LineStyle'\n\nimport { locLabel } from './contributors'\n\nimport type { Contributor, GraphLocation } from './contributors'\nimport type { LaunchableSyntenyTrack } from './syntenyTracks'\nimport type { MenuItem } from '@jbrowse/core/ui'\n\nconst LINEAR_LABEL = 'Linear genome view'\nconst SYNTENY_LABEL = 'Linear synteny view'\nconst NO_SYNTENY_TRACK =\n 'No synteny track in this session aligns these assemblies'\n\nexport interface LinearTarget {\n location: GraphLocation\n assembly: string\n}\n\n// One flat item when there is one thing to open, a submenu when there is a\n// choice. Same shape as subgraphMenuItems uses in the other direction, so the\n// two ends of the graph <-> linear trip read the same way.\nfunction oneOrMany<T>({\n label,\n icon,\n entries,\n entryLabel,\n onSelect,\n disabledHelpText,\n nameTheOnlyEntry = true,\n}: {\n label: string\n icon: React.ElementType\n entries: T[]\n entryLabel: (entry: T) => string\n onSelect: (entry: T) => () => void\n disabledHelpText?: string\n // Whether a lone entry's name is worth appending to the item. It is when the\n // entry is where you land (`GRCh38 chr6:31,980,000-32,050,000`) and not when\n // it is the ingredient used to get there \u2014 a synteny track's name says\n // nothing the item does not already say, and reading it costs the width of\n // `pggb graph: all-vs-all synteny (wfmash)`.\n nameTheOnlyEntry?: boolean\n}): MenuItem[] {\n const [first] = entries\n // Nothing to open: a *disabled* item with the reason in its tooltip, when\n // there is a reason worth reading. An item that vanishes teaches nobody that\n // the session is one synteny track short of a multi-genome view.\n const empty: MenuItem[] = disabledHelpText\n ? [{ label, icon, disabled: true, disabledHelpText, onClick: () => {} }]\n : []\n return entries.length === 0\n ? empty\n : entries.length === 1 && first\n ? [\n {\n label: nameTheOnlyEntry ? `${label} \u2014 ${entryLabel(first)}` : label,\n icon,\n onClick: onSelect(first),\n },\n ]\n : [\n {\n label,\n icon,\n type: 'subMenu',\n subMenu: entries.map(entry => ({\n label: entryLabel(entry),\n onClick: onSelect(entry),\n })),\n },\n ]\n}\n\n// The graph's way out: a linear view of any assembly the graph names here, and a\n// synteny view of all of them at once. Until this existed the triangle had two\n// edges \u2014 a linear view could open a graph or a synteny view of a locus, and the\n// graph could open nothing at all.\n//\n// `contributors` are already resolved against the session's assemblies. On an\n// E. coli pangenome every strain is its own assembly, so all of them appear and\n// the synteny item is the interesting one; on an HPRC graph the 400-odd\n// contributing haplotypes are not loaded assemblies and only the reference\n// appears, which is the honest answer rather than a missing feature.\nexport function graphLaunchMenuItems({\n contributors,\n syntenyTracks,\n onShowLinear,\n onShowSynteny,\n}: {\n contributors: Contributor[]\n syntenyTracks: LaunchableSyntenyTrack[]\n onShowLinear: (target: LinearTarget) => void\n onShowSynteny: (trackId: string) => void\n}): MenuItem[] {\n // sorted widest first\n const widest = syntenyTracks[0]?.coverage ?? contributors.length\n return [\n ...oneOrMany({\n label: LINEAR_LABEL,\n icon: LineStyleIcon,\n entries: contributors,\n entryLabel: c => `${c.sample} ${locLabel(c)}`,\n onSelect: c => () => {\n onShowLinear({ location: c, assembly: c.sample })\n },\n }),\n ...(contributors.length >= 2\n ? oneOrMany({\n // the count the launch opens, which is what the widest track aligns\n // and not always every contributor; see launchSyntenyView\n label: `${SYNTENY_LABEL} (${widest} assemblies)`,\n icon: CompareArrowsIcon,\n entries: syntenyTracks,\n entryLabel: track =>\n track.coverage < widest\n ? `${track.name} (${track.coverage} of ${widest})`\n : track.name,\n nameTheOnlyEntry: false,\n disabledHelpText: NO_SYNTENY_TRACK,\n onSelect: track => () => {\n onShowSynteny(track.trackId)\n },\n })\n : []),\n ]\n}\n\n// A single node's way out, for the node context menu. Two different questions,\n// both worth offering:\n//\n// - the node's own coordinates, on the assembly that contributed it. Exact,\n// from the node's SN/SO, and available at every rank \u2014 but only openable\n// when that assembly is loaded, which for an HPRC haplotype it is not.\n// - where the node sits on the reference the graph was cut against. Always\n// openable, and off the backbone it is the flanking projection rather than\n// an exact span (see nodeReferenceSpan), so it is labelled as the region\n// around the node rather than as the node.\n//\n// Labels are verbs. Review: \"the lineargenomeview menu item should say launch\n// if that is what it does\" \u2014 a bare `Linear genome view \u2014 hg38 chr6:\u2026` names a\n// place and leaves the reader to guess whether clicking scrolls the view beside\n// the graph or opens a new one. It does the first when there is one to scroll\n// (see showInLinearView), so \"Open in\" covers both without claiming a launch.\n//\n// Verb, assembly, and where \u2014 nothing else. Every word here is read inside a\n// menu opened on a node, so \"this node in the hg38 view\" and \"in linear view\"\n// restate the context they are already in; what a coordinate opens in is not in\n// question, and the assembly name is.\n//\n// Flat, not under a \"Launch view\" submenu: this menu is a handful of items and\n// every one is contextual to the node just clicked.\nexport function nodeLaunchMenuItems({\n own,\n reference,\n highlight,\n onShowLinear,\n onHighlight,\n}: {\n own: LinearTarget | undefined\n reference: LinearTarget | undefined\n // the node's exact reference span, where `reference` is padded to open on\n highlight: LinearTarget | undefined\n onShowLinear: (target: LinearTarget) => void\n // absent when no linear view in the session is this graph's to mark\n onHighlight?: (target: LinearTarget) => void\n}): MenuItem[] {\n const entries = [\n own\n ? {\n label: `Open in ${own.assembly} \u2014 ${locLabel(own.location)}`,\n target: own,\n }\n : undefined,\n // Only when it says something the item above doesn't. A backbone segment on\n // a loaded reference answers both questions with the same assembly and\n // nearly the same span, and offering that twice reads as two different\n // places to go.\n reference && reference.assembly !== own?.assembly\n ? {\n label: `Open in ${reference.assembly} \u2014 around this node`,\n target: reference,\n }\n : undefined,\n ].filter(entry => entry !== undefined)\n\n // The reference projection, not the node's own coordinates: a highlight is\n // drawn in the linear view already on screen, and that view is on the\n // reference the subgraph was cut from.\n return [\n ...(onHighlight && highlight\n ? [\n {\n label: `Highlight in ${highlight.assembly}`,\n icon: HighlightAltIcon,\n onClick: () => {\n onHighlight(highlight)\n },\n },\n ]\n : []),\n ...entries.map(({ label, target }) => ({\n label,\n icon: LineStyleIcon,\n onClick: () => {\n onShowLinear(target)\n },\n })),\n ]\n}\n", "import {\n parseCs\n} from \"./chunk-C44YRP5F.js\";\n\n// src/tubeMap/reads.ts\nfunction canonicalStrand(node) {\n return node.id.endsWith(\"-\") ? \"-\" : \"+\";\n}\nfunction stepName(node, strand) {\n return strand === canonicalStrand(node) ? node.id : `-${node.id}`;\n}\nfunction stepStarts(lengths, total) {\n const starts = lengths.map(() => void 0);\n let head = 0;\n let i = 0;\n for (; i < lengths.length && lengths[i] !== void 0; i++) {\n starts[i] = head;\n head += lengths[i];\n }\n let tail = total;\n for (let j = lengths.length - 1; j > i && lengths[j] !== void 0; j--) {\n tail -= lengths[j];\n starts[j] = tail;\n }\n return starts;\n}\nfunction mismatchesByStep(record, lengths) {\n const byStep = record.path.map(() => []);\n if (record.cs === void 0) {\n return byStep;\n }\n const starts = stepStarts(lengths, record.pathLength);\n const stepAt = (pos2, atEnd = false) => {\n for (let s = 0; s < starts.length; s++) {\n const start = starts[s];\n const length = lengths[s];\n if (start !== void 0 && length !== void 0 && start <= pos2 && (pos2 < start + length || atEnd && pos2 === start + length)) {\n return { s, local: pos2 - start, room: start + length - pos2 };\n }\n }\n return void 0;\n };\n const add = (s, mismatch) => {\n const list = byStep[s];\n const last = list.at(-1);\n if (mismatch.type === \"substitution\" && last?.type === \"substitution\" && last.pos + last.seq.length === mismatch.pos) {\n last.seq += mismatch.seq;\n } else {\n list.push(mismatch);\n }\n };\n let pos = record.pathStart;\n for (const op of parseCs(record.cs)) {\n if (op.op === \"match\") {\n pos += op.length;\n } else if (op.op === \"substitution\") {\n const at = stepAt(pos);\n if (at) {\n add(at.s, { type: \"substitution\", pos: at.local, seq: op.seq });\n }\n pos += 1;\n } else if (op.op === \"insertion\") {\n const at = stepAt(pos, pos === record.pathEnd);\n if (at) {\n add(at.s, { type: \"insertion\", pos: at.local, seq: op.seq });\n }\n } else {\n let left = op.length;\n while (left > 0) {\n const at = stepAt(pos);\n const take = at ? Math.min(left, at.room) : left;\n if (at) {\n add(at.s, { type: \"deletion\", pos: at.local, length: take });\n }\n pos += take;\n left -= take;\n }\n }\n }\n return byStep;\n}\nfunction tubeMapReads(graph, records, firstId) {\n const nodeByName = new Map(graph.nodes.map((n) => [n.name, n]));\n const reads = [];\n for (const record of records) {\n const nodes = record.path.map((step) => nodeByName.get(step.name));\n const kept = nodes.flatMap((node, i) => node ? [i] : []);\n const first = kept[0];\n const last = kept.at(-1);\n if (first !== void 0 && last !== void 0) {\n const mismatches = mismatchesByStep(\n record,\n nodes.map((n) => n?.length)\n );\n const names = kept.map((i) => stepName(nodes[i], record.path[i].strand));\n const lastLength = nodes[last].length;\n reads.push({\n id: firstId + reads.length,\n name: record.name,\n type: \"read\",\n sourceTrackID: 1,\n sequence: names,\n sequenceNew: kept.map((i, k) => ({\n nodeName: names[k],\n mismatches: mismatches[i]\n })),\n firstNodeOffset: first === 0 ? record.pathStart : 0,\n finalNodeCoverLength: last === record.path.length - 1 ? lastLength - (record.pathLength - record.pathEnd) : lastLength,\n mapping_quality: record.mappingQuality === 255 ? 0 : record.mappingQuality,\n is_secondary: record.secondary,\n is_reverse: record.strand === \"-\"\n });\n }\n }\n return reads;\n}\nvar FORWARD_READ_COLORS = [\"#6baed6\", \"#4292c6\", \"#2171b5\", \"#08519c\"];\nvar REVERSE_READ_COLORS = [\"#fb6a4a\", \"#ef3b2c\", \"#cb181d\", \"#a50f15\"];\nfunction readColor(read) {\n const colors = read.is_reverse ? REVERSE_READ_COLORS : FORWARD_READ_COLORS;\n return colors[read.id % colors.length];\n}\n\nexport {\n canonicalStrand,\n stepName,\n tubeMapReads,\n FORWARD_READ_COLORS,\n REVERSE_READ_COLORS,\n readColor\n};\n", "import {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\nimport {\n REFERENCE_RANK,\n isAnchored\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/alleleProjection/projectAlleles.ts\nfunction parsePanSN(refName) {\n const parts = refName.split(\"#\");\n const haplotype = parts.length >= 2 ? Number(parts[1]) : Number.NaN;\n return {\n sample: parts[0] ?? refName,\n haplotype: Number.isFinite(haplotype) ? haplotype : void 0\n };\n}\nfunction collectRun(seed, byId, adj, claimed) {\n const members = [];\n const anchors = [];\n const queue = [seed];\n claimed.add(seed);\n while (queue.length > 0) {\n const id = queue.pop();\n const node = byId.get(id);\n if (node) {\n members.push(node);\n for (const neighborId of adj.get(id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor) {\n if (neighbor.stable.rank === REFERENCE_RANK) {\n anchors.push(neighbor);\n } else if (!claimed.has(neighborId)) {\n claimed.add(neighborId);\n queue.push(neighborId);\n }\n }\n }\n }\n }\n return { members, anchors };\n}\nfunction anchorSpan(anchors) {\n const refNames = new Set(anchors.map((a) => a.stable.refName));\n if (refNames.size !== 1 || anchors.length < 2) {\n return void 0;\n }\n const sorted = [...anchors].sort((a, b) => a.stable.start - b.stable.start);\n const first = sorted[0];\n const last = sorted.at(-1);\n const start = first.stable.start + first.length;\n const end = last.stable.start;\n return end >= start ? { start, end, entry: first } : void 0;\n}\nfunction runDistances(members, entry, adj) {\n const byId = new Map(members.map((m) => [m.id, m]));\n const dist = /* @__PURE__ */ new Map();\n const queue = [];\n for (const neighborId of adj.get(entry.id) ?? []) {\n if (byId.has(neighborId)) {\n dist.set(neighborId, 0);\n queue.push(neighborId);\n }\n }\n if (queue.length === 0) {\n for (const member of members) {\n dist.set(member.id, 0);\n queue.push(member.id);\n }\n }\n for (const id of queue) {\n const reach = dist.get(id) + byId.get(id).length;\n for (const neighborId of adj.get(id) ?? []) {\n if (byId.has(neighborId)) {\n const known = dist.get(neighborId);\n if (known === void 0 || reach < known) {\n dist.set(neighborId, reach);\n queue.push(neighborId);\n }\n }\n }\n }\n return dist;\n}\nfunction runOffsets(members, entry, adj) {\n const dist = runDistances(members, entry, adj);\n const ordered = [...members].sort((a, b) => dist.get(a.id) - dist.get(b.id));\n const rank = new Map(ordered.map((m, i) => [m.id, i]));\n const byId = new Map(members.map((m) => [m.id, m]));\n const offsets = /* @__PURE__ */ new Map();\n for (const [i, member] of ordered.entries()) {\n let offset = 0;\n for (const neighborId of adj.get(member.id) ?? []) {\n const neighbor = byId.get(neighborId);\n if (neighbor && rank.get(neighborId) < i) {\n offset = Math.max(offset, offsets.get(neighborId) + neighbor.length);\n }\n }\n offsets.set(member.id, offset);\n }\n return { offsets, ordered };\n}\nfunction projectAlleles(graph) {\n const byId = new Map(\n graph.nodes.filter(isAnchored).map((n) => [n.id, n])\n );\n const adj = buildNeighbors(graph);\n const claimed = /* @__PURE__ */ new Set();\n const alleles = [];\n for (const node of byId.values()) {\n if (node.stable.rank !== REFERENCE_RANK && !claimed.has(node.id)) {\n const { members, anchors } = collectRun(node.id, byId, adj, claimed);\n const span = anchorSpan(anchors);\n if (span) {\n const { offsets, ordered } = runOffsets(members, span.entry, adj);\n alleles.push({\n start: span.start,\n refSpan: span.end - span.start,\n nodeIds: ordered.map((m) => m.id),\n nodeOffsets: ordered.map((m) => offsets.get(m.id)),\n pathLength: ordered.reduce(\n (max, m) => Math.max(max, offsets.get(m.id) + m.length),\n 0\n )\n });\n }\n }\n }\n return alleles.sort((a, b) => a.start - b.start);\n}\n\nexport {\n parsePanSN,\n projectAlleles\n};\n", "import {\n projectAlleles\n} from \"./chunk-RVS2QCOX.js\";\nimport {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\n\n// src/layout/placeOffReference.ts\nvar MIN_DELETION_BP = 1;\nvar MIN_ALLELE_SPAN_FRACTION = 0.015;\nfunction placeOffReference({\n graph,\n span,\n rowY,\n positions\n}) {\n const minSpan = span * MIN_ALLELE_SPAN_FRACTION;\n const alleles = projectAlleles(graph);\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const alleleDeletions = [];\n for (const allele of alleles) {\n const skipped = allele.refSpan - allele.pathLength;\n if (skipped >= MIN_DELETION_BP) {\n alleleDeletions.push({ nodeIds: allele.nodeIds, bp: skipped });\n }\n const drawn = Math.max(allele.refSpan, minSpan);\n const scale = allele.pathLength > 0 ? drawn / allele.pathLength : 0;\n allele.nodeIds.forEach((nodeId, i) => {\n const node = byId.get(nodeId);\n if (node) {\n const offset = allele.nodeOffsets[i];\n const even = drawn / allele.nodeIds.length;\n const at = (bp) => allele.start + bp * scale;\n const y = rowY(node);\n positions[nodeId] = scale ? [\n { x: at(offset), y },\n { x: at(offset + node.length), y }\n ] : [\n { x: allele.start + i * even, y },\n { x: allele.start + (i + 1) * even, y }\n ];\n }\n });\n }\n const neighbors = buildNeighbors(graph);\n const queue = Object.keys(positions);\n for (const fromId of queue) {\n const fromEnd = positions[fromId].at(-1).x;\n for (const nextId of neighbors.get(fromId) ?? []) {\n const next = byId.get(nextId);\n if (next && !(nextId in positions)) {\n const y = rowY(next);\n positions[nextId] = [\n { x: fromEnd, y },\n { x: fromEnd + minSpan, y }\n ];\n queue.push(nextId);\n }\n }\n }\n return alleleDeletions;\n}\n\nexport {\n placeOffReference\n};\n", "import {\n placeOffReference\n} from \"./chunk-TZFWUT2C.js\";\nimport {\n parsePanSN\n} from \"./chunk-RVS2QCOX.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\nimport {\n backboneNodes,\n backbonePositions,\n isOffReference,\n referenceSpan\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/sampleRowLayout.ts\nfunction contributingSamples(graph, keep) {\n const carried = /* @__PURE__ */ new Map();\n for (const node of graph.nodes) {\n if (isOffReference(node)) {\n const { sample } = parsePanSN(node.stable.refName);\n carried.set(sample, (carried.get(sample) ?? 0) + node.length);\n }\n }\n const held = new Map(keep.map((sample, row) => [sample, row]));\n return [...carried.keys()].sort(\n (a, b) => (held.get(a) ?? Infinity) - (held.get(b) ?? Infinity) || carried.get(b) - carried.get(a) || a.localeCompare(b)\n );\n}\nfunction sampleRowLayout(graph, region, keep = []) {\n const backbone = backboneNodes(graph);\n const samples = contributingSamples(graph, keep);\n if (backbone.length === 0 || samples.length === 0) {\n return void 0;\n }\n const span = referenceSpan(backbone, region);\n const rowOf = new Map(samples.map((s, i) => [s, i + 1]));\n const nodePositions = backbonePositions(backbone);\n const spareRow = samples.length + 1;\n const alleleDeletions = placeOffReference({\n graph,\n span,\n rowY: (node) => {\n const stable = node.stable;\n const row = stable ? rowOf.get(parsePanSN(stable.refName).sample) : void 0;\n return (row ?? spareRow) * ROW_HEIGHT_PX;\n },\n positions: nodePositions\n });\n const referenceSample = parsePanSN(backbone[0].stable.refName).sample;\n const rowLabels = [\n { label: referenceSample, y: 0 },\n ...samples.map((sample) => ({\n label: sample,\n y: rowOf.get(sample) * ROW_HEIGHT_PX\n }))\n ];\n return {\n nodePositions,\n rowLabels,\n sampleRows: samples,\n referenceAxis: true,\n pixelRows: true,\n alleleDeletions\n };\n}\n\nexport {\n sampleRowLayout\n};\n", "export type MismatchType = 'insertion' | 'deletion' | 'substitution'\n\nexport interface Mismatch {\n type: MismatchType\n pos: number\n seq?: string\n length?: number\n}\n\nexport interface ReadSequenceEntry {\n nodeName: string\n mismatches: Mismatch[]\n}\n\nexport type TrackType = 'haplotype' | 'read'\n\nexport interface TrackRectangle {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface TrackCurve {\n xStart: number\n yStart: number\n xEnd: number\n yEnd: number\n width: number\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n // the nodes the curve leaves and enters, null at a gap in a track's path\n nodeStart: number | null\n nodeEnd: number | null\n // the order slots it leaves and enters\n orderStart: number\n orderEnd: number\n path?: string\n}\n\nexport interface TrackCorner {\n path: string\n id: number\n name?: string | undefined\n type?: TrackType | undefined\n}\n\nexport interface Segment {\n order: number\n lane?: number\n isForward: boolean\n node: number | null\n y?: number\n betweenCycleReverseTraversal?: boolean\n}\n\n// Loose input shape: just the basics produced by vgExtractTracks /\n// vgExtractReads. Layout passes accrete indexSequence / path / width.\nexport interface InputTrack {\n id: number\n name?: string\n sequence: string[]\n type?: TrackType\n freq?: number\n hidden?: boolean\n sourceTrackID: number\n indexOfFirstBase?: number\n isCompletelyReverse?: boolean\n // Read-specific fields populated by vgExtractReads.\n sequenceNew?: ReadSequenceEntry[]\n firstNodeOffset?: number\n finalNodeCoverLength?: number\n mapping_quality?: number\n is_secondary?: boolean\n is_reverse?: boolean\n sample_name?: string | null\n read_group?: string | null\n cigar_string?: string\n score?: number\n}\n\n// How many of the banded haplotypes take a coarsened band\nexport interface HaplotypeShare {\n count: number\n total: number\n}\n\n// Layout-complete track shape, as layoutTubeMap returns it.\nexport interface Track extends InputTrack {\n indexSequence: number[]\n path: Segment[]\n width: number\n haplotypeShare?: HaplotypeShare | undefined\n}\n\n// Loose input shape passed to layoutTubeMap. Its passes (generateNodeWidth \u2192\n// generateNodeOrder \u2192 generateLaneAssignment \u2192 generateNodeXCoords) accrete\n// more fields, producing the full `Node` below. A graph fetched with\n// removeSequences has no seq, and sequenceLength defaults to seq's length.\nexport interface InputNode {\n name: string\n seq?: string\n sequenceLength?: number\n}\n\n// Layout-complete node \u2014 fields used by drawing code after the pipeline.\n// (Marked optional only for the genuinely conditional fields like switched/d.)\n// layoutTubeMap fills in seq, as '' when the input had none, and\n// sequenceLength.\nexport interface Node extends InputNode {\n seq: string\n sequenceLength: number\n width: number\n pixelWidth: number\n order?: number | undefined\n y: number\n contentHeight: number\n x: number\n topLane: number\n successors: number[]\n predecessors: number[]\n tracks: number[]\n degree: number\n switched?: boolean\n incomingReads: [number, number][]\n outgoingReads: [number, number][]\n internalReads: number[]\n d?: string\n}\n\n// Node after generateNodeOrder() has run \u2014 order is guaranteed to be set.\nexport interface LayoutNode extends Node {\n order: number\n}\n\nexport interface SegmentAssignment {\n trackID: number\n segmentID: number\n compareToFromSame: SegmentAssignment | null\n idealLane?: number | undefined\n idealY?: number | null | undefined\n lane?: number\n}\n\nexport interface NodeAssignment {\n type: 'single' | 'multiple'\n node: number | null\n tracks: SegmentAssignment[]\n idealLane?: number | undefined\n}\n\n// Drawing instructions from one layout, in layout coordinates.\nexport interface TrackShapes {\n rectangles: TrackRectangle[]\n curves: TrackCurve[]\n corners: TrackCorner[]\n // drawn separately so they don't overlap the horizontal rectangles\n verticalRectangles: TrackRectangle[]\n}\n\nexport function emptyTrackShapes(): TrackShapes {\n return {\n rectangles: [],\n curves: [],\n corners: [],\n verticalRectangles: [],\n }\n}\n\n// The extent of the drawn content, in layout coordinates.\nexport interface ImageBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n", "// A PanSN path name: sample#haplotype#contig, sometimes with further\n// #-separated fields such as a fragment offset after the contig.\n// https://github.com/pangenome/PanSN-spec\nexport interface PanSNName {\n sample: string\n haplotype: number\n contig: string\n}\n\n// gbz-base names a generic reference `_gbwt_ref#0#contig` and a haplotype the\n// GBWT kept no metadata for `unknown#N#contig`; neither names a sample.\nconst NOT_SAMPLES = new Set(['_gbwt_ref', 'unknown'])\n\n// The sample, haplotype and contig of a PanSN name, or undefined for any other\n// name: fewer than three fields, an empty sample or contig, a haplotype that\n// isn't a whole number, or a placeholder sample.\nexport function parsePanSN(name: string | undefined): PanSNName | undefined {\n const [sample, haplotype, contig] = name?.split('#') ?? []\n if (\n sample === undefined ||\n sample === '' ||\n NOT_SAMPLES.has(sample) ||\n haplotype === undefined ||\n !/^\\d+$/.test(haplotype) ||\n contig === undefined ||\n contig === ''\n ) {\n return undefined\n }\n return { sample, haplotype: Number(haplotype), contig }\n}\n", "// The tube map layout, from input nodes and tracks to drawable shapes. Ported\n// from the original sequenceTubeMap JS, where it shared one module with the d3\n// drawing. It runs in two phases, each on a fresh LayoutState: layoutTopology\n// merges, orders, orients and sizes the nodes and fixes their x, and\n// placeTubeMap stacks a chosen set of tracks and reads on that topology.\nimport { parsePanSN } from './panSN.ts'\nimport { emptyTrackShapes } from './types.ts'\n\nimport type {\n HaplotypeShare,\n ImageBounds,\n InputNode,\n InputTrack,\n LayoutNode,\n Mismatch,\n Node,\n NodeAssignment,\n ReadSequenceEntry,\n Segment,\n SegmentAssignment,\n Track,\n TrackShapes,\n TrackType,\n} from './types.ts'\n\nconst DEBUG = false as boolean\n\nfunction debugLog(...args: unknown[]): void {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.log(...args)\n }\n}\n\n// Node and Track declare some fields that not every entry gets: layout places\n// only the nodes a track or read reaches, and a normal read has no width until\n// assignReadsToNodes.\ntype MaybeUnset<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\ntype MaybeUnplacedNode = MaybeUnset<LayoutNode, 'x' | 'y'>\n\nexport type NodeWidthOption = 'normal' | 'compressed' | 'small' | 'fixed'\n\n// The fields of a placed track a renderer colors it by. Shapes carry only the\n// track's id, so a renderer can recolor without laying out again.\nexport interface ColorableTrack {\n id: number\n sourceTrackID: number\n type?: TrackType\n name?: string\n mapping_quality?: number\n is_reverse?: boolean\n haplotypeShare?: HaplotypeShare\n}\n\nexport type LayerData = 'haplotypes' | 'reads'\n\n// A track set placement draws, and the stat it runs first. `coarsen` turns\n// the set into one band per edge; banded haplotypes keep the reference's lane.\nexport interface Layer {\n data: LayerData\n stat?: 'coarsen'\n}\n\n// The options a topology fixes. trackWidth, the layers and ignoreStrand leave\n// node order alone, but the topology measures x from placing every track and\n// read under them.\nexport interface TopologyOptions {\n mergeNodes?: boolean\n showReads?: boolean\n // Shorthand for `layers` when those are unset: band the reads, or the\n // haplotypes when no reads were loaded\n coarsenedReadView?: boolean\n // The haplotypes draw first and the reads stack under them, each data under\n // the stat of its first layer here\n layers?: readonly Layer[]\n ignoreStrand?: boolean\n // normal: width is sequence length, at `charWidth` per base\n // compressed: log2 of sequence length\n // small: 1% of sequence length\n // fixed: every node one width\n nodeWidthOption?: NodeWidthOption\n charWidth?: number\n // a haplotype tube's width in layout px, where no `freq` scales it\n trackWidth?: number\n}\n\nexport const READ_FACET_FIELDS = ['read_group', 'sample_name'] as const\nexport type ReadFacetBy = (typeof READ_FACET_FIELDS)[number]\n// A read field, or the sample in the haplotypes' PanSN names\nexport const FACET_FIELDS = [...READ_FACET_FIELDS, 'haplotype_sample'] as const\nexport type FacetBy = (typeof FACET_FIELDS)[number]\n\n// One panel's subset. A read facet keeps every haplotype and the reads whose\n// `by` field is `key`, or that lack one when `key` is null. A haplotype facet\n// keeps the reference and no reads, plus the haplotypes of sample `key`, or\n// those with no PanSN sample when `key` is null; its `reads` panel keeps the\n// reference and the reads.\nexport interface ReadFacet {\n by: ReadFacetBy\n key: string | null\n}\nexport type HaplotypeFacet =\n | { by: 'haplotype_sample'; key: string | null }\n | { by: 'haplotype_sample'; reads: true }\nexport type Facet = ReadFacet | HaplotypeFacet\n\n// Which of a topology's tracks and reads a placement draws\nexport interface PlacementOptions {\n mappingQualityCutoff?: number\n focusReadNames?: string[] | null\n facet?: Facet | undefined\n}\n\nexport interface FacetOptions extends PlacementOptions {\n // One panel per value of this field\n facetBy?: FacetBy | null\n}\n\nexport interface LayoutOptions extends TopologyOptions, PlacementOptions {}\n\nexport type CoarsenedUnit = 'read' | 'haplotype'\n\n// A coarsened band's count of contributing reads or haplotypes and its label,\n// keyed by the band's synthetic track id, unique across layers\nexport interface CoarsenedEdgeMeta {\n count: number\n label: string\n}\n\n// What a layer's coarsening drew as bands, how many reads or haplotypes it\n// banded (counting a deduplicated walk `freq` times), and whether any band\n// runs reverse-strand\nexport interface Coarsening {\n unit: CoarsenedUnit\n total: number\n reverse: boolean\n}\n\n// Each layer that drew bands, by its data\nexport type Coarsenings = Partial<Record<LayerData, Coarsening>>\n\nexport interface TubeMapLayout {\n // 1-indexed with a hole at 0: a signed index\n // is an oriented visit, and 0 has no sign\n nodes: LayoutNode[]\n // the haplotype tracks and placed reads together, sorted by where each\n // first meets the others, which is the order their shapes were made in\n tracks: Track[]\n // the placed reads alone\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n shapes: TrackShapes\n bounds: ImageBounds\n maxOrder: number\n // the name of the track that carries a coordinate for the ruler\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n coarsened: Coarsenings\n}\n\n// A node before placement gives it a y and the reads through it\nexport type TopologyNode = Omit<\n LayoutNode,\n | 'y'\n | 'contentHeight'\n | 'topLane'\n | 'incomingReads'\n | 'outgoingReads'\n | 'internalReads'\n>\n\n// A haplotype or read before placement gives it a width and lanes\nexport type TopologyTrack = Omit<Track, 'path' | 'width'>\n\n// What every placement of one input shares: the merged, ordered and oriented\n// nodes with their widths and x positions, and the oriented haplotypes and\n// reads. A placement reads it and never changes it.\nexport interface TubeMapTopology {\n options: Required<TopologyOptions>\n // 1-indexed with a hole at 0, like TubeMapLayout.nodes. A node no track or\n // read reaches has order UNREACHABLE_ORDER and no x.\n nodes: readonly TopologyNode[]\n // the visible haplotypes, track 0 read left to right\n tracks: readonly TopologyTrack[]\n // every primary alignment that shares a node with a track, unfiltered\n reads: readonly TopologyTrack[]\n nodeMap: ReadonlyMap<string, number>\n maxOrder: number\n trackForRuler: string | undefined\n}\n\ntype LayoutConfig = Required<TopologyOptions>\n\n// The coarsened view bands haplotypes only when no reads were loaded, not when\n// a filter hides them all\nfunction layersFrom(\n { layers, coarsenedReadView = false, showReads = true }: TopologyOptions,\n hasReads: boolean,\n): readonly Layer[] {\n if (layers !== undefined) {\n return layers\n }\n const coarsen = coarsenedReadView && showReads\n const stat = (banded: boolean): Pick<Layer, 'stat'> =>\n banded ? { stat: 'coarsen' } : {}\n return [\n { data: 'haplotypes', ...stat(coarsen && !hasReads) },\n { data: 'reads', ...stat(coarsen && hasReads) },\n ]\n}\n\nfunction statOf(layers: readonly Layer[], data: LayerData) {\n return layers.find(layer => layer.data === data)?.stat\n}\n\nfunction configFrom(options: TopologyOptions, hasReads: boolean): LayoutConfig {\n return {\n mergeNodes: options.mergeNodes ?? true,\n showReads: options.showReads ?? true,\n coarsenedReadView: options.coarsenedReadView ?? false,\n layers: layersFrom(options, hasReads),\n ignoreStrand: options.ignoreStrand ?? false,\n nodeWidthOption: options.nodeWidthOption ?? 'normal',\n charWidth: options.charWidth ?? 8.401,\n trackWidth: options.trackWidth ?? 15,\n }\n}\n\n// The working state of one topology or placement, shared by its passes.\ninterface LayoutState {\n config: LayoutConfig\n // Sparse like TubeMapLayout.nodes, but forEach, map and sort skip the hole\n // and noUncheckedIndexedAccess already types indexed reads as possibly\n // undefined, so only for...of would ever see it.\n nodes: LayoutNode[]\n // Each track's `path` lists the Segments to draw, in order along the path.\n tracks: Track[]\n // Reads have a `path` too, but stack vertically by a different system.\n reads: Track[]\n nodeMap: ReadonlyMap<string, number>\n nodesPerOrder: number[][]\n // generateNodeOrder's scratch, by node index; undefined until assigned.\n nodeOrders: (number | undefined)[]\n // Lane assignments for tracks (not reads), one list per order slot.\n assignments: NodeAssignment[][]\n extraLeft: number[]\n extraRight: number[]\n // horizontal order of the rightmost node\n maxOrder: number\n shapes: TrackShapes\n imageBounds: ImageBounds\n trackForRuler: string | undefined\n coarsenedEdgeMeta: Map<number, CoarsenedEdgeMeta>\n}\n\nfunction emptyState(config: LayoutConfig): LayoutState {\n return {\n config,\n nodes: [],\n tracks: [],\n reads: [],\n nodeMap: new Map(),\n nodesPerOrder: [],\n nodeOrders: [],\n assignments: [],\n extraLeft: [],\n extraRight: [],\n maxOrder: -1,\n shapes: emptyTrackShapes(),\n imageBounds: { minX: 0, maxX: 0, minY: 0, maxY: 0 },\n trackForRuler: undefined,\n coarsenedEdgeMeta: new Map(),\n }\n}\n\n// placeTubeMap(layoutTopology(...), options). Undefined when nothing visible\n// is left to draw.\nexport function layoutTubeMap(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: LayoutOptions = {},\n): TubeMapLayout | undefined {\n const topology = layoutTopology(inputNodes, inputTracks, inputReads, options)\n return topology && placeTubeMap(topology, options)\n}\n\n// Each topology's placement of every track and read, which fixed its x\nconst measurements = new WeakMap<TubeMapTopology, TubeMapLayout>()\n\n// Merge, order and orient the nodes under the visible `inputTracks` and, when\n// `showReads`, every primary alignment in `inputReads`, then size them and\n// fix their x positions. Undefined when nothing visible is left to draw.\n// Neither input is modified. Track 0 is the reference the layout straightens.\n// The x gaps between order slots make room for the tracks' turns and slopes,\n// so the topology takes its x positions from placing every track and read.\nexport function layoutTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[] = [],\n options: TopologyOptions = {},\n): TubeMapTopology | undefined {\n const topology = arrangeTopology(inputNodes, inputTracks, inputReads, options)\n if (topology === undefined) {\n return undefined\n }\n const everything = place(topology, topology.tracks, topology.reads, 'measure')\n everything.nodes.forEach((node, i) => {\n if (node.order >= 0) {\n topology.nodes[i]!.x = node.x\n }\n })\n measurements.set(topology, everything)\n return topology\n}\n\n// Lay out the haplotypes and reads `options` keep at the topology's x\n// positions, stacking each read under the nodes it visits. When they keep\n// everything, this returns the placement layoutTopology measured x from, the\n// same object on every such call.\nexport function placeTubeMap(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): TubeMapLayout {\n return placeSubset(\n topology,\n selectTracks(topology, options.facet),\n selectReads(topology, options),\n )\n}\n\nfunction placeSubset(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n bandIdBase?: BandIdBase,\n): TubeMapLayout {\n const measured = measurements.get(topology)\n return measured !== undefined &&\n tracks.length === topology.tracks.length &&\n reads.length === topology.reads.length\n ? measured\n : place(topology, tracks, reads, 'topology', bandIdBase)\n}\n\nfunction arrangeTopology(\n inputNodes: readonly InputNode[],\n inputTracks: readonly InputTrack[],\n inputReads: readonly InputTrack[],\n options: TopologyOptions,\n): TubeMapTopology | undefined {\n const state = emptyState(configFrom(options, inputReads.length > 0))\n\n if (inputNodes.length === 0 || inputTracks.length === 0) {\n return undefined\n }\n\n // Boundary promotion: layout passes below populate the Node/Track fields\n // (width, order, x/y, path, indexSequence, etc.) before any reader runs.\n //\n // Nodes are referenced in inputs by internal `name` attribute and not by\n // index. Internally in e.g. a path's indexSequence we need to reference\n // nodes by *signed* index, so index 0 can never be used: budge everything\n // down and leave a hole (rather than an `undefined` entry) at 0, which we\n // won't iterate over. Made after the copy, because not every structuredClone\n // keeps a hole.\n structuredClone(inputNodes).forEach((node, i) => {\n node.seq ??= ''\n node.sequenceLength ??= node.seq.length\n state.nodes[i + 1] = node as LayoutNode\n })\n state.tracks = structuredClone(inputTracks) as Track[]\n // Secondary alignments never draw, so drop them before the deep copy, the\n // most expensive step in a redraw.\n state.reads = state.config.showReads\n ? (structuredClone(\n inputReads.filter(read => read.is_secondary !== true),\n ) as Track[])\n : []\n\n for (let i = state.tracks.length - 1; i >= 0; i -= 1) {\n const t = state.tracks[i]!\n t.type ??= 'haplotype'\n if (t.hidden === true) {\n state.tracks.splice(i, 1)\n continue\n }\n if (t.indexOfFirstBase !== undefined) {\n state.trackForRuler = t.name\n }\n }\n if (state.tracks.length === 0) {\n return undefined\n }\n\n // Run against the visible tracks only, so hiding the reference doesn't leave\n // the layout straightened around a track that is no longer drawn.\n straightenTrack(state, 0)\n\n state.nodeMap = generateNodeMap(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n generateNodeWidth(state)\n\n if (state.config.mergeNodes) {\n generateNodeSuccessors(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n mergeNodes(state)\n state.nodeMap = generateNodeMap(state)\n generateNodeWidth(state)\n generateTrackIndexSequences(state, state.tracks)\n generateTrackIndexSequences(state, state.reads)\n }\n\n generateNodeSuccessors(state)\n generateNodeDegree(state)\n generateNodeOrder(state)\n\n // can cause problems when there is a reversed single track node\n // OTOH, can solve problems with complex inversion patterns\n switchNodeOrientation(state)\n generateNodeOrder(state)\n reverseReversedReads(state)\n generateTrackIndexSequences(state, state.reads)\n\n return {\n options: state.config,\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n maxOrder: getMaxOrder(state),\n trackForRuler: state.trackForRuler,\n }\n}\n\nfunction selectReads(\n topology: TubeMapTopology,\n { mappingQualityCutoff = 0, focusReadNames = null, facet }: PlacementOptions,\n): readonly TopologyTrack[] {\n const focus = focusReadNames ? new Set(focusReadNames) : null\n return topology.reads.filter(\n read =>\n (read.mapping_quality ?? 0) >= mappingQualityCutoff &&\n (focus === null || (read.name !== undefined && focus.has(read.name))) &&\n (facet === undefined || facetHoldsRead(facet, read)),\n )\n}\n\n// Whether a panel of `facet` draws this read when the read filters keep it\nexport function facetHoldsRead(\n facet: Facet,\n read: Pick<TopologyTrack, ReadFacetBy>,\n): boolean {\n return facet.by === 'haplotype_sample'\n ? 'reads' in facet\n : (read[facet.by] ?? null) === facet.key\n}\n\n// What every haplotype panel keeps: track 0, which the topology straightened,\n// and the track carrying the ruler's coordinates, when that is another\nfunction references(topology: TubeMapTopology): Set<TopologyTrack> {\n return new Set(\n topology.tracks.filter(\n (track, i) => i === 0 || track.name === topology.trackForRuler,\n ),\n )\n}\n\nfunction selectTracks(\n topology: TubeMapTopology,\n facet: Facet | undefined,\n): readonly TopologyTrack[] {\n if (facet?.by !== 'haplotype_sample') {\n return topology.tracks\n }\n const kept = references(topology)\n return topology.tracks.filter(\n track =>\n kept.has(track) || (!('reads' in facet) && sampleOf(track) === facet.key),\n )\n}\n\nfunction sampleOf(track: TopologyTrack): string | null {\n return parsePanSN(track.name)?.sample ?? null\n}\n\n// The haplotypes among `tracks` beside the reference, a PanSN haplotype\n// counted once however many walks it makes through the window\nfunction haplotypeCount(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n): number {\n const skip = references(topology)\n return new Set(\n tracks.flatMap(track => {\n if (skip.has(track)) {\n return []\n }\n const name = parsePanSN(track.name)\n return [name ? `${name.sample}#${name.haplotype}` : track]\n }),\n ).size\n}\n\n// A facet and the haplotypes and reads it draws\nexport interface FacetSubset<F extends Facet = Facet> {\n facet: F\n tracks: readonly TopologyTrack[]\n reads: readonly TopologyTrack[]\n}\n\n// Group `items` by key: in sort order, the null key last\nfunction groupBy<T>(\n items: readonly T[],\n keyOf: (item: T) => string | null,\n): [string | null, T[]][] {\n const groups = new Map<string | null, T[]>()\n for (const item of items) {\n const key = keyOf(item)\n const group = groups.get(key)\n if (group === undefined) {\n groups.set(key, [item])\n } else {\n group.push(item)\n }\n }\n return [...groups].sort(([a], [b]) =>\n a === null || b === null\n ? Number(a === null) - Number(b === null)\n : a.localeCompare(b, undefined, { numeric: true }),\n )\n}\n\n// Split the reads `options` keep by their `by` field: one subset per value,\n// in sort order with the reads lacking one last, and none left empty. Every\n// subset keeps every haplotype.\nexport function facetReads(\n topology: TubeMapTopology,\n by: ReadFacetBy,\n options: PlacementOptions = {},\n): FacetSubset<ReadFacet>[] {\n return groupBy(\n selectReads(topology, { ...options, facet: undefined }),\n read => read[by] ?? null,\n ).map(([key, reads]) => ({\n facet: { by, key },\n tracks: topology.tracks,\n reads,\n }))\n}\n\n// Split the haplotypes beside the reference by the sample in their PanSN\n// names: one subset per sample, in sort order, then one for the haplotypes\n// with no PanSN name, each holding the reference too and no reads. The reads\n// `options` keep, when any, go in a last subset with the reference alone. No\n// haplotype beside the reference leaves nothing to split.\nexport function facetHaplotypes(\n topology: TubeMapTopology,\n options: PlacementOptions = {},\n): FacetSubset<HaplotypeFacet>[] {\n const kept = references(topology)\n const samples = groupBy(\n topology.tracks.filter(track => !kept.has(track)),\n sampleOf,\n )\n if (samples.length === 0) {\n return []\n }\n const ofSample = samples.map(([key]) => {\n const facet: HaplotypeFacet = { by: 'haplotype_sample', key }\n return { facet, tracks: selectTracks(topology, facet), reads: [] }\n })\n const facet: HaplotypeFacet = { by: 'haplotype_sample', reads: true }\n const reads = selectReads(topology, { ...options, facet })\n return reads.length === 0\n ? ofSample\n : [...ofSample, { facet, tracks: selectTracks(topology, facet), reads }]\n}\n\n// One placement in a stack of them. Its layout keeps its own coordinates;\n// `offsetY` moves it into the stack.\nexport interface FacetPanel {\n // undefined for the one panel of an unfaceted view\n facet?: Facet\n readCount: number\n // beside the reference, a PanSN haplotype counted once\n haplotypeCount: number\n layout: TubeMapLayout\n offsetY: number\n}\n\nexport interface FacetedLayout {\n panels: FacetPanel[]\n // every panel and its label, in stack coordinates\n bounds: ImageBounds\n}\n\n// Room above each faceted panel for its label, and between one panel and the\n// next label\nexport const FACET_LABEL_HEIGHT = 30\nexport const FACET_GAP = 40\n\n// Place the topology once per facet and stack the placements top to bottom,\n// the first where an unfaceted placement would draw. Every panel takes the\n// topology's x, so the panels line up in x. Band ids run on from one panel to\n// the next where panels band different tracks: the reads under a read facet,\n// the haplotypes under a haplotype facet, whose bands then take their share\n// of the panel's haplotypes. Without `facetBy`, or with nothing to split, this\n// is one panel of placeTubeMap's layout.\nexport function placeFacets(\n topology: TubeMapTopology,\n options: FacetOptions = {},\n): FacetedLayout {\n const { facetBy, ...placement } = options\n const subsets =\n facetBy === undefined || facetBy === null\n ? []\n : facetBy === 'haplotype_sample'\n ? facetHaplotypes(topology, placement)\n : facetReads(topology, facetBy, placement)\n if (subsets.length === 0) {\n const layout = placeTubeMap(topology, placement)\n return {\n panels: [\n {\n layout,\n readCount: layout.reads.length,\n haplotypeCount: haplotypeCount(topology, topology.tracks),\n offsetY: 0,\n },\n ],\n bounds: layout.bounds,\n }\n }\n const banded: LayerData =\n facetBy === 'haplotype_sample' ? 'haplotypes' : 'reads'\n let nextBandId: number | undefined\n let bottom = 0\n const panels = subsets.map(({ facet, tracks, reads }, i) => {\n const layout = placeSubset(\n topology,\n tracks,\n reads,\n nextBandId === undefined ? undefined : { [banded]: nextBandId },\n )\n const bandIds = [...layout.coarsenedEdgeMeta.keys()]\n if (bandIds.length > 0) {\n nextBandId = Math.max(...bandIds) + 1\n }\n const offsetY =\n i === 0 ? 0 : bottom + FACET_GAP + FACET_LABEL_HEIGHT - layout.bounds.minY\n bottom = offsetY + layout.bounds.maxY\n return {\n facet,\n readCount: reads.length,\n haplotypeCount: haplotypeCount(topology, tracks),\n layout,\n offsetY,\n }\n })\n return {\n panels,\n bounds: {\n minX: Math.min(...panels.map(p => p.layout.bounds.minX)),\n maxX: Math.max(...panels.map(p => p.layout.bounds.maxX)),\n minY: panels[0]!.layout.bounds.minY - FACET_LABEL_HEIGHT,\n maxY: bottom,\n },\n }\n}\n\n// The first id each layer's bands take\ntype BandIdBase = Partial<Record<LayerData, number>>\n\n// Place copies of the topology's nodes and the given tracks and reads,\n// measuring x from them or taking the topology's. Haplotype bands take ids\n// from COARSENED_ID_BASE and read bands straight after, unless `bandIdBase`\n// says otherwise.\nfunction place(\n topology: TubeMapTopology,\n tracks: readonly TopologyTrack[],\n reads: readonly TopologyTrack[],\n x: 'measure' | 'topology',\n bandIdBase: BandIdBase = {},\n): TubeMapLayout {\n const state = emptyState(topology.options)\n topology.nodes.forEach((node, i) => {\n state.nodes[i] = { ...node } as LayoutNode\n })\n state.tracks = tracks.map(track => ({ ...track }) as Track)\n state.reads = reads.map(read => ({ ...read }) as Track)\n state.nodeMap = topology.nodeMap\n state.maxOrder = topology.maxOrder\n state.trackForRuler = topology.trackForRuler\n\n // Banded haplotypes leave the reference its lane and join the reads'\n // overlay, above the reads, before calculateTrackWidth and\n // generateLaneAssignment see the tracks.\n const { layers, ignoreStrand } = state.config\n const haplotypeBandIdBase = bandIdBase.haplotypes ?? COARSENED_ID_BASE\n const haplotypeBands =\n statOf(layers, 'haplotypes') === 'coarsen'\n ? bandHaplotypes(state, haplotypeBandIdBase)\n : undefined\n if (haplotypeBands !== undefined) {\n state.tracks = [haplotypeBands.ref]\n }\n\n calculateTrackWidth(state)\n generateLaneAssignment(state)\n // also places the nodes that only filtered-out reads visit\n generateReadOnlyNodeAttributes(state)\n\n // A band crosses exactly two nodes, so placeReads and the shapes handle it\n // like any read, and node heights grow with the edge count rather than the\n // read or haplotype count.\n const readBands =\n statOf(layers, 'reads') === 'coarsen' && state.reads.length > 0\n ? buildCoarsenedSyntheticBands(\n state,\n state.reads,\n 'read',\n bandIdBase.reads ??\n haplotypeBandIdBase + (haplotypeBands?.bands.length ?? 0),\n )\n : undefined\n if (readBands !== undefined) {\n state.reads = readBands.bands\n }\n const coarsened: Coarsenings = {}\n for (const [data, unit, banding] of [\n ['haplotypes', 'haplotype', haplotypeBands],\n ['reads', 'read', readBands],\n ] as const) {\n if (banding !== undefined) {\n reverseReversedReads(state, banding.bands)\n generateTrackIndexSequences(state, banding.bands)\n coarsened[data] = {\n unit,\n total: banding.total,\n reverse: !ignoreStrand && banding.bands.some(b => b.is_reverse),\n }\n }\n }\n if (haplotypeBands !== undefined) {\n state.reads = haplotypeBands.bands.concat(state.reads)\n }\n\n if (state.reads.length > 0) {\n placeReads(state)\n state.tracks = state.tracks.concat(state.reads)\n } else {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n }\n\n if (x === 'measure') {\n generateNodeXCoords(state)\n }\n\n generateSVGShapesFromPath(state)\n debugLog('Tracks:', state.tracks)\n debugLog('Nodes:', state.nodes)\n debugLog('Lane assignment:', state.assignments)\n getImageDimensions(state)\n return {\n nodes: state.nodes,\n tracks: state.tracks,\n reads: state.reads,\n nodeMap: state.nodeMap,\n shapes: state.shapes,\n bounds: state.imageBounds,\n maxOrder: state.maxOrder,\n trackForRuler: state.trackForRuler,\n coarsenedEdgeMeta: state.coarsenedEdgeMeta,\n coarsened,\n }\n}\n\n// Return true if the given name names a reverse strand node, and false otherwise.\nexport function isReverse(nodeName: string): boolean {\n return nodeName.startsWith('-')\n}\n\n// Get the forward version of a node name, which may be either forward or backward (negative)\nexport function forward(nodeName: string): string {\n return isReverse(nodeName) ? nodeName.substring(1) : nodeName\n}\n\n// Get the reverse version of a node name, which may be either forward or backward (negative)\nexport function reverse(nodeName: string): string {\n return isReverse(nodeName) ? nodeName : `-${nodeName}`\n}\n\n// Get the opposite orientation node name for the given node.\nexport function flip(nodeName: string): string {\n return isReverse(nodeName) ? forward(nodeName) : reverse(nodeName)\n}\n\n// Whether a signed node index visits its node forward. Index 0 is never a\n// node, so no visit is -0.\nexport function isForwardIndex(n: number): boolean {\n return n > 0\n}\n\n// Turn around every node the given track visits in reverse before it visits\n// it forward, so that track reads left to right, and flip every track's and\n// read's visits to those nodes to match, as switchNodeOrientationForPaths\n// does for the nodes it switches.\nfunction straightenTrack(state: LayoutState, index: number): void {\n const nodesToInvert = new Set<string>()\n const visitedForward = new Set<string>()\n for (const visit of state.tracks[index]!.sequence) {\n if (!isReverse(visit)) {\n visitedForward.add(visit)\n } else if (!visitedForward.has(forward(visit))) {\n nodesToInvert.add(forward(visit))\n }\n }\n if (nodesToInvert.size === 0) {\n return\n }\n\n for (const { sequence } of [...state.tracks, ...state.reads]) {\n for (let j = 0; j < sequence.length; j += 1) {\n if (nodesToInvert.has(forward(sequence[j]!))) {\n sequence[j] = flip(sequence[j]!)\n }\n }\n }\n\n state.nodes.forEach(node => {\n if (nodesToInvert.has(node.name)) {\n node.seq = getReverseComplement(node.seq)\n }\n })\n}\n\n// generates attributes (node.y, node.contentHeight) for nodes without tracks, only reads\nfunction generateReadOnlyNodeAttributes(state: LayoutState): void {\n state.nodesPerOrder = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.nodesPerOrder[i] = []\n }\n\n const orderY = new Map<number, number>()\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n setMapToMax(orderY, node.order, node.y + node.contentHeight)\n }\n })\n\n // for order values where there is no node with haplotypes, orderY is calculated via tracks\n state.tracks.forEach(track => {\n if (track.type === 'haplotype') {\n track.path.forEach(step => {\n setMapToMax(orderY, step.order, (step.y ?? 0) + track.width)\n })\n }\n })\n\n state.nodes.forEach((node: MaybeUnplacedNode, i) => {\n if (node.order >= 0 && node.y === undefined) {\n node.y = (orderY.get(node.order) ?? 0) + 25\n node.contentHeight = 0\n state.nodesPerOrder[node.order]!.push(i)\n }\n })\n}\n\nfunction setMapToMax<K>(map: Map<K, number>, key: K, value: number): void {\n const existing = map.get(key)\n if (existing === undefined) {\n map.set(key, value)\n } else {\n map.set(key, Math.max(existing, value))\n }\n}\n\nexport const READ_WIDTH = 7\n\n// add info about reads to nodes (incoming, outgoing and internal reads)\nfunction assignReadsToNodes(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.incomingReads = []\n node.outgoingReads = []\n node.internalReads = []\n })\n state.reads.forEach((read: MaybeUnset<Track, 'width'>, idx) => {\n // coarsened bands arrive sized by their crossing count\n if (read.width === undefined || read.width === 0) {\n read.width = READ_WIDTH\n }\n if (read.path.length === 1) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.internalReads.push(idx)\n }\n } else {\n read.path.forEach((element, pathIdx) => {\n if (pathIdx === 0) {\n const firstNode = read.path[0]!.node\n if (firstNode !== null) {\n state.nodes[firstNode]!.outgoingReads.push([idx, pathIdx])\n }\n } else {\n const elemNode = element.node\n if (elemNode !== null) {\n state.nodes[elemNode]!.incomingReads.push([idx, pathIdx])\n }\n }\n })\n }\n })\n}\n\n// calculate paths (incl. correct y coordinate) for all reads\nfunction placeReads(state: LayoutState): void {\n state.reads.forEach(read => {\n read.path = basicPath(state, read)\n })\n assignReadsToNodes(state)\n\n // placed nodes by order, then by y-coordinate\n const sortedNodes = state.nodes.filter(node => node.order >= 0)\n sortedNodes.sort(compareNodesByOrder)\n\n // One set per layer and source track: haplotype bands, then each read file\n const sets = new Map<\n string,\n { layer: number; source: number; reads: Set<number> }\n >()\n for (let i = 0; i < state.reads.length; i++) {\n const read = state.reads[i]!\n const layer = read.haplotypeShare === undefined ? 1 : 0\n const source = read.sourceTrackID\n const key = `${layer}:${source}`\n const set = sets.get(key)\n if (set === undefined) {\n sets.set(key, { layer, source, reads: new Set([i]) })\n } else {\n set.reads.add(i)\n }\n }\n const orderedSets = [...sets.values()].sort(\n (a, b) => a.layer - b.layer || a.source - b.source,\n )\n\n // A margin sets each set apart from the one above it\n const topMargin = orderedSets.length > 1 ? READ_WIDTH : 0\n sortedNodes.forEach(node => {\n for (const { reads } of orderedSets) {\n placeReadSet(state, reads, node, topMargin)\n }\n })\n\n // place read segments which are without node\n const bottomY = calculateBottomY(state)\n const elementsWithoutNode: ElementWithoutNode[] = []\n state.reads.forEach((read, idx) => {\n const len = read.path.length\n\n // For each path index, precompute the nearest preceding/following segment\n // whose node is non-null and truthy. Falls back to the boundary segment when\n // none qualifies, matching the original walking-loop semantics.\n const prevSegment = new Array<Segment | undefined>(len)\n let lastValidPrev: Segment | undefined\n for (let i = 0; i < len; i++) {\n if (i === 0) {\n prevSegment[i] = undefined\n } else {\n prevSegment[i] = lastValidPrev ?? read.path[0]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n lastValidPrev = seg\n }\n }\n const nextSegment = new Array<Segment | undefined>(len)\n let firstValidNext: Segment | undefined\n for (let i = len - 1; i >= 0; i--) {\n if (i === len - 1) {\n nextSegment[i] = undefined\n } else {\n nextSegment[i] = firstValidNext ?? read.path[len - 1]\n }\n const seg = read.path[i]!\n if (seg.node !== null && seg.node) {\n firstValidNext = seg\n }\n }\n\n read.path.forEach((element, pathIdx) => {\n if (element.y === undefined) {\n const previousVisitToNode = prevSegment[pathIdx]\n const nextVisitToNode = nextSegment[pathIdx]\n\n // Specifically referring to segments between a cycle that's traversing from right to left\n const betweenCycleReverseTraversal = Boolean(\n // A segment can be between a cycle if it there are nodes on both sides\n nextVisitToNode &&\n previousVisitToNode &&\n // A segment is between a cycle if the next node it visits is behind the previous node it visited\n (previousVisitToNode.order > nextVisitToNode.order ||\n // A segment can also be between a cycle if it's visiting the same node it just visited in the same direction\n (nextVisitToNode.order === previousVisitToNode.order &&\n nextVisitToNode.isForward === previousVisitToNode.isForward)),\n )\n\n element.betweenCycleReverseTraversal = betweenCycleReverseTraversal\n\n elementsWithoutNode.push({\n readIndex: idx,\n pathIndex: pathIdx,\n previousY: previousVisitToNode?.y,\n previousNode: previousVisitToNode?.node,\n })\n }\n })\n })\n\n elementsWithoutNode.sort((a, b) => compareNoNodeReads(state, a, b))\n elementsWithoutNode.forEach(element => {\n const read = state.reads[element.readIndex]!\n const segment = read.path[element.pathIndex]!\n segment.y = bottomY[segment.order]!\n bottomY[segment.order]! += read.width\n })\n\n debugLog('Reads:', state.reads)\n}\n\n// Place a particular collection of reads, identified by a list of read\n// numbers, into the given node at the right Y coordinates. All reads in all\n// nodes above it, and no reads in any nodes below it, are already placed.\n// Makes the given node bigger if needed and moves other nodes down if needed.\n// If topMargin is set, applies that amount of spacing down from whatever is above the reads.\nfunction placeReadSet(\n state: LayoutState,\n toPlace: Set<number>,\n node: LayoutNode,\n topMargin: number,\n): void {\n // Get arrays of the read entry/exit/internal-ness records we want to work on\n let incomingReads = node.incomingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const outgoingReads = node.outgoingReads.filter(([readID]) =>\n toPlace.has(readID),\n )\n const internalReads = node.internalReads.filter(readID => toPlace.has(readID))\n\n // Only actually use the top margin if we have any reads on the node.\n if (\n incomingReads.length === 0 &&\n outgoingReads.length === 0 &&\n internalReads.length === 0\n ) {\n topMargin = 0\n }\n\n // Determine where we start vertically in the node.\n // TODO: Why do we have to double this to keep reads out of adjacent lanes???\n const startY = node.y + node.contentHeight + topMargin * 2\n\n // sort incoming reads \u2014 decorate with a precomputed key so each compare is O(1).\n // The original comparator walks pathIdx backwards in lockstep on both sides, picking\n // the first step where either has a defined y (or reaches index 0). The walk's outcome\n // for a single entry is fully captured by:\n // decisionStep: the smallest k>=1 where path[pathIdx-k].y is defined, or pathIdx+1\n // if no preceding segment has a defined y (the \"reached 0\" case).\n // y: the defined y at decisionStep, or undefined for \"reached 0\".\n // Smaller decisionStep wins; ties put the \"reached 0\" entries first;\n // otherwise compare y's.\n const incomingKeys = incomingReads.map(entry => {\n const [readID, pathIdx] = entry\n const path = state.reads[readID]!.path\n let decisionStep = pathIdx + 1\n let foundY: number | undefined\n for (let k = 1; k <= pathIdx; k++) {\n const y = path[pathIdx - k]?.y\n if (y !== undefined) {\n decisionStep = k\n foundY = y\n break\n }\n }\n return { entry, decisionStep, y: foundY }\n })\n incomingKeys.sort(compareIncomingReadKeys)\n incomingReads = incomingKeys.map(k => k.entry)\n\n // place incoming reads\n let currentY = startY\n const occupiedUntil = new Map<number, number>()\n incomingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n read.path[readElement[1]]!.y = currentY\n setOccupiedUntil(occupiedUntil, read, readElement[1], currentY, node)\n currentY += read.width\n })\n let maxY = currentY\n\n // sort outgoing reads\n outgoingReads.sort((a, b) =>\n compareReadOutgoingSegmentsByGoingTo(state, a, b),\n )\n\n // place outgoing reads\n const occupiedFrom = new Map<number, number>()\n currentY = startY\n outgoingReads.forEach(readElement => {\n const read = state.reads[readElement[0]]!\n const firstNodeOffset = read.firstNodeOffset ?? 0\n // place in next lane\n read.path[readElement[1]]!.y = currentY\n occupiedFrom.set(currentY, firstNodeOffset)\n // if no conflicts. The original predicate was strict-less-than, which\n // treats two reads that exactly touch (incoming ends at base K, outgoing\n // starts at base K+1) as conflicting. They don't overlap, so they can\n // share a lane \u2014 relax to <=. This also matters for coarsened Sankey\n // bands at single-base nodes (e.g. a 1bp \"G\" node): with edge-only offsets\n // the math becomes 0+1 < 1 (conflict, wrong) vs. 0+1 <= 1 (no conflict).\n const occUntil = occupiedUntil.get(currentY)\n if (occUntil === undefined || occUntil + 1 <= firstNodeOffset) {\n currentY += read.width\n maxY = Math.max(maxY, currentY)\n } else {\n // otherwise push down incoming reads to make place for outgoing Read\n occupiedUntil.set(currentY, 0)\n incomingReads.forEach(incReadElementIndices => {\n const incRead = state.reads[incReadElementIndices[0]]!\n const incReadPathElement = incRead.path[incReadElementIndices[1]]!\n if (\n incReadPathElement.y !== undefined &&\n incReadPathElement.y >= currentY\n ) {\n incReadPathElement.y += read.width\n setOccupiedUntil(\n occupiedUntil,\n incRead,\n incReadElementIndices[1],\n incReadPathElement.y,\n node,\n )\n }\n })\n currentY += read.width\n maxY += read.width\n }\n })\n\n // sort internal reads\n internalReads.sort((a, b) => compareInternalReads(state, a, b))\n\n // place internal reads\n internalReads.forEach(readIdx => {\n const currentRead = state.reads[readIdx]!\n const firstNodeOffset = currentRead.firstNodeOffset ?? 0\n const finalNodeCoverLength = currentRead.finalNodeCoverLength ?? 0\n currentY = startY\n while (\n firstNodeOffset < (occupiedUntil.get(currentY) ?? -Infinity) + 2 ||\n finalNodeCoverLength > (occupiedFrom.get(currentY) ?? Infinity) - 3\n ) {\n currentY += currentRead.width || READ_WIDTH\n }\n currentRead.path[0]!.y = currentY\n occupiedUntil.set(currentY, finalNodeCoverLength)\n maxY = Math.max(maxY, currentY)\n })\n\n // adjust node height and move other nodes vertically down\n const heightIncrease = maxY - node.y - node.contentHeight\n node.contentHeight += heightIncrease\n adjustVertically3(state, node, heightIncrease)\n}\n\n// The decorated sort key for one incoming read segment; see the comment in\n// placeReadSet for how it is derived. Exported for testing.\nexport interface IncomingReadKey {\n decisionStep: number\n y: number | undefined\n}\n\n// Smaller decisionStep wins. On a tie, entries that walked off the front of the\n// path (no defined y) sort first and tie with each other; otherwise compare y.\nexport function compareIncomingReadKeys(\n a: IncomingReadKey,\n b: IncomingReadKey,\n): number {\n if (a.decisionStep !== b.decisionStep) {\n return a.decisionStep - b.decisionStep\n }\n if (a.y === undefined || b.y === undefined) {\n return (a.y === undefined ? 0 : 1) - (b.y === undefined ? 0 : 1)\n }\n return a.y - b.y\n}\n\n// keeps track of where reads end within nodes\nfunction setOccupiedUntil(\n map: Map<number, number>,\n read: Track,\n pathIndex: number,\n y: number,\n node: Node,\n): void {\n if (pathIndex === read.path.length - 1) {\n // last node of current read\n map.set(y, read.finalNodeCoverLength ?? 0)\n } else {\n // read covers the whole node\n map.set(y, node.sequenceLength)\n }\n}\n\ninterface ElementWithoutNode {\n readIndex: number\n pathIndex: number\n previousY: number | undefined\n previousNode: number | null | undefined\n}\n\n// compare read segments which are outside of nodes to sort them in a good horizontal\n// and then vertical display order.\nfunction compareNoNodeReads(\n state: LayoutState,\n a: ElementWithoutNode,\n b: ElementWithoutNode,\n): number {\n const readA = state.reads[a.readIndex]!\n const readB = state.reads[b.readIndex]!\n const segmentA = readA.path[a.pathIndex]!\n const segmentB = readB.path[b.pathIndex]!\n // Sort by order by segments\n if (segmentA.order !== segmentB.order) {\n return segmentA.order - segmentB.order\n }\n // Sort by reads' source track\n if (readA.sourceTrackID !== readB.sourceTrackID) {\n return readA.sourceTrackID - readB.sourceTrackID\n }\n // Sort by order of previous node\n if (a.previousNode && b.previousNode) {\n const prevNodeA = state.nodes[a.previousNode]\n const prevNodeB = state.nodes[b.previousNode]\n if (prevNodeA && prevNodeB && prevNodeA.order !== prevNodeB.order) {\n return prevNodeA.order - prevNodeB.order\n }\n }\n // Segments on the reverse-going part of a cycle go below the rest, in\n // reverse order, so a loop that starts on the outside stays there and rolls\n // up in order with the other loops.\n const aPrev = a.previousY ?? 0\n const bPrev = b.previousY ?? 0\n const aReverse = segmentA.betweenCycleReverseTraversal === true\n const bReverse = segmentB.betweenCycleReverseTraversal === true\n if (aReverse !== bReverse) {\n return aReverse ? 1 : -1\n }\n return aReverse ? bPrev - aPrev : aPrev - bPrev\n}\n\n// compare read segments by where they are going to\nfunction compareReadOutgoingSegmentsByGoingTo(\n state: LayoutState,\n [readIndexA, pathIndexA]: [number, number],\n [readIndexB, pathIndexB]: [number, number],\n): number {\n // Expect two arrays both containing 2 integers.\n // The first index of each array contains the read index\n // The second index of each array contains the path index\n\n // Segments are first sorted by the y value of their last node,\n // then by the node they end on,\n // then by length in final node\n const readA = state.reads[readIndexA]!\n const readB = state.reads[readIndexB]!\n let previousValidYA: number | undefined\n let previousValidYB: number | undefined\n let lastPathIndexA = readA.path.length - 1\n let lastPathIndexB = readB.path.length - 1\n while (!previousValidYA && lastPathIndexA >= 0) {\n previousValidYA = readA.path[lastPathIndexA]?.y\n lastPathIndexA -= 1\n }\n while (!previousValidYB && lastPathIndexB >= 0) {\n previousValidYB = readB.path[lastPathIndexB]?.y\n lastPathIndexB -= 1\n }\n\n if (previousValidYA && previousValidYB) {\n return previousValidYA - previousValidYB\n }\n\n // Couldn't find a valid y value for at least one of the reads, sort by which node reads end on\n const initialNodeA = readA.path[pathIndexA]?.node\n const initialNodeB = readB.path[pathIndexB]?.node\n let nodeA: LayoutNode | null | undefined =\n typeof initialNodeA === 'number' ? state.nodes[initialNodeA] : null\n let nodeB: LayoutNode | null | undefined =\n typeof initialNodeB === 'number' ? state.nodes[initialNodeB] : null\n // Follow the reads' paths until we find the node they diverge at\n // Or, they go through all the same nodes and we do a tiebreaker at the end\n while (nodeA && nodeB && nodeA === nodeB) {\n if (pathIndexA < readA.path.length - 1) {\n pathIndexA += 1\n while (readA.path[pathIndexA]?.node === null) {\n pathIndexA += 1\n } // skip null nodes in path\n const nextNodeIdx = readA.path[pathIndexA]?.node\n nodeA = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeA = null\n }\n if (pathIndexB < readB.path.length - 1) {\n pathIndexB += 1\n while (readB.path[pathIndexB]?.node === null) {\n pathIndexB += 1\n } // skip null nodes in path\n const nextNodeIdx = readB.path[pathIndexB]?.node\n nodeB = typeof nextNodeIdx === 'number' ? state.nodes[nextNodeIdx] : null\n } else {\n nodeB = null\n }\n }\n if (nodeA) {\n if (nodeB) {\n return compareNodesByOrder(nodeA, nodeB)\n }\n return 1 // nodeB is null, nodeA not null\n }\n if (nodeB) {\n return -1\n } // nodeB not null, nodeA null\n // both nodes are null -> both end in the same node\n const beginDiff = (readA.firstNodeOffset ?? 0) - (readB.firstNodeOffset ?? 0)\n if (beginDiff !== 0) {\n return beginDiff\n }\n\n // break tie: both reads cover the same nodes and begin at the same position\n\n // One or both reads didn't have a previously valid Y value, compare by the endPosition of the read\n return (readA.finalNodeCoverLength ?? 0) - (readB.finalNodeCoverLength ?? 0)\n}\n\n// Compare tracks based on ordering at their first convergence\nfunction compareTrackByInitialOrdering(trackA: Track, trackB: Track): number {\n // Find the first node where the two tracks converge, sort by layer.\n const pathA = trackA.path\n const pathB = trackB.path\n\n let AIndex = 0\n let BIndex = 0\n while (AIndex < pathA.length && BIndex < pathB.length) {\n const a = pathA[AIndex]!\n const b = pathB[BIndex]!\n const trackAOrder = a.order\n const trackBOrder = b.order\n if (trackAOrder === trackBOrder && a.node && b.node) {\n return (b.y ?? 0) - (a.y ?? 0)\n } else if (trackAOrder < trackBOrder) {\n AIndex += 1\n } else if (trackAOrder > trackBOrder) {\n BIndex += 1\n } else {\n // Orders are equal but are traversing out of nodes\n AIndex += 1\n BIndex += 1\n }\n }\n\n // Tracks do not converge, keep the same ordering\n return 0\n}\n\n// compare 2 reads which are completely within a single node\nfunction compareInternalReads(\n state: LayoutState,\n idxA: number,\n idxB: number,\n): number {\n const a = state.reads[idxA]!\n const b = state.reads[idxB]!\n // compare by first base within first node\n const aFirst = a.firstNodeOffset ?? 0\n const bFirst = b.firstNodeOffset ?? 0\n if (aFirst < bFirst) {\n return -1\n } else if (aFirst > bFirst) {\n return 1\n }\n\n // compare by last base within last node\n const aLast = a.finalNodeCoverLength ?? 0\n const bLast = b.finalNodeCoverLength ?? 0\n if (aLast < bLast) {\n return -1\n } else if (aLast > bLast) {\n return 1\n }\n\n return 0\n}\n\n// determine biggest y-coordinate for each order-value\nfunction calculateBottomY(state: LayoutState): number[] {\n const bottomY: number[] = []\n for (let i = 0; i <= state.maxOrder; i += 1) {\n bottomY.push(0)\n }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.y !== undefined) {\n bottomY[node.order] = Math.max(\n bottomY[node.order]!,\n node.y + node.contentHeight + 20,\n )\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(element => {\n bottomY[element.order] = Math.max(\n bottomY[element.order]!,\n (element.y ?? 0) + track.width,\n )\n })\n })\n return bottomY\n}\n\n// The segments a track draws, in order: one per node visit, plus one per\n// order slot it passes or turns around in without visiting a node. They carry\n// no lanes or coordinates yet.\nfunction basicPath(state: LayoutState, track: Track): Segment[] {\n const path: Segment[] = []\n const pass = (order: number, isForward: boolean): void => {\n path.push({ order, isForward, node: null })\n }\n const visit = (order: number, isForward: boolean, node: number): void => {\n path.push({ order, isForward, node })\n }\n\n let currentNodeIndex = Math.abs(track.indexSequence[0]!)\n let currentNodeIsForward = isForwardIndex(track.indexSequence[0]!)\n let currentNode = state.nodes[currentNodeIndex]!\n visit(currentNode.order, currentNodeIsForward, currentNodeIndex)\n\n for (let i = 1; i < track.sequence.length; i += 1) {\n const previousNode = currentNode\n const previousNodeIsForward = currentNodeIsForward\n currentNodeIndex = Math.abs(track.indexSequence[i]!)\n currentNodeIsForward = isForwardIndex(track.indexSequence[i]!)\n currentNode = state.nodes[currentNodeIndex]!\n const { order } = currentNode\n\n if (order > previousNode.order) {\n if (!previousNodeIsForward) {\n pass(previousNode.order, true)\n }\n for (let j = previousNode.order + 1; j < order; j += 1) {\n pass(j, true)\n }\n if (!currentNodeIsForward) {\n pass(order, true)\n }\n } else if (order < previousNode.order) {\n if (previousNodeIsForward) {\n pass(previousNode.order, false)\n }\n for (let j = previousNode.order - 1; j > order; j -= 1) {\n pass(j, false)\n }\n if (currentNodeIsForward) {\n pass(order, false)\n }\n } else if (currentNodeIsForward === previousNodeIsForward) {\n pass(order, !currentNodeIsForward)\n }\n visit(order, currentNodeIsForward, currentNodeIndex)\n }\n return path\n}\n\n// Turn each read that visits only reverse nodes around to visit them forward\nfunction reverseReversedReads(\n state: LayoutState,\n reads: readonly Track[] = state.reads,\n): void {\n reads.forEach(read => {\n let pos = 0\n while (pos < read.sequence.length && read.sequence[pos]!.startsWith('-')) {\n pos += 1\n }\n if (pos === read.sequence.length) {\n // completely reversed read\n read.is_reverse = true\n read.sequence = read.sequence.reverse() // invert sequence\n for (let i = 0; i < read.sequence.length; i += 1) {\n read.sequence[i] = forward(read.sequence[i]!) // visit nodes forward\n // TODO: Do we really want to visit all the nodes forward here? Are we\n // sure we aren't in mixed orientation?\n }\n\n const sequenceNew = read.sequenceNew ?? []\n sequenceNew.reverse() // invert sequence\n read.sequenceNew = sequenceNew\n for (const entry of sequenceNew) {\n entry.nodeName = forward(entry.nodeName) // visit nodes forward\n reverseMismatches(\n entry.mismatches,\n nodeByName(state, entry.nodeName).sequenceLength,\n )\n }\n\n // adjust firstNodeOffset and finalNodeCoverLength\n const temp = read.firstNodeOffset ?? 0\n const firstLen = nodeByName(state, read.sequence[0]!).sequenceLength\n read.firstNodeOffset = firstLen - (read.finalNodeCoverLength ?? 0)\n const lastLen = nodeByName(\n state,\n read.sequence[read.sequence.length - 1]!,\n ).sequenceLength\n read.finalNodeCoverLength = lastLen - temp\n }\n })\n}\n\n// Flip a node's mismatches onto the opposite strand: positions are measured\n// from the other end of the node, and sequences are reverse-complemented.\n// sequenceLength (not node.width, which is only equal to it in 'normal'\n// node-width mode) is the right pivot because mismatch positions are base\n// offsets.\nexport function reverseMismatches(\n mismatches: Mismatch[],\n sequenceLength: number,\n): void {\n mismatches.forEach(mm => {\n Object.assign(mm, mirroredMismatch(mm, sequenceLength))\n })\n}\n\nexport function mirroredMismatch(\n mm: Mismatch,\n sequenceLength: number,\n): Mismatch {\n const span =\n mm.type === 'insertion'\n ? 0\n : mm.type === 'deletion'\n ? (mm.length ?? 0)\n : (mm.seq?.length ?? 0)\n return {\n ...mm,\n pos: sequenceLength - mm.pos - span,\n ...(mm.seq !== undefined && { seq: getReverseComplement(mm.seq) }),\n }\n}\n\nconst COMPLEMENT: Record<string, string> = { A: 'T', T: 'A', C: 'G', G: 'C' }\n\nfunction getReverseComplement(s: string): string {\n let result = ''\n for (let i = s.length - 1; i >= 0; i -= 1) {\n result += COMPLEMENT[s.charAt(i)] ?? 'N'\n }\n return result\n}\n\n// for each track: generate sequence of node indices from seq. of node names.\n// Tracks revisit the same names, so each name resolves once per call.\nfunction generateTrackIndexSequences(\n state: LayoutState,\n tracksOrReads: Track[],\n): void {\n const signedIndexOf = new Map<string, number>()\n tracksOrReads.forEach(track => {\n track.indexSequence = track.sequence.map(nodeName => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))\n if (index === undefined) {\n throw new Error(\n `Track ${track.name ?? track.id} visits unknown node ${nodeName}`,\n )\n }\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n })\n })\n}\n\n// Tracks enter and leave a node this far outside it horizontally. Note that\n// getImageDimensions() below only adds it on the right: the pannable area\n// understates the left edge of the drawing by this much.\nconst NODE_HORIZONTAL_SLACK = 20\n\n// get the minimum and maximum coordinates used in the image to calculate image dimensions\nfunction getImageDimensions(state: LayoutState): void {\n // Sentinels, deliberately crossed: if nothing below runs, minZoom() and\n // alignSVG() detect the empty content rather than computing a negative scale.\n const bounds: ImageBounds = { minX: 99, maxX: -99, minY: 99, maxY: -99 }\n\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n bounds.minX = Math.min(bounds.minX, node.x)\n bounds.maxX = Math.max(\n bounds.maxX,\n node.x + NODE_HORIZONTAL_SLACK + node.pixelWidth,\n )\n }\n if (node.y !== undefined) {\n bounds.minY = Math.min(bounds.minY, node.y - 10)\n bounds.maxY = Math.max(bounds.maxY, node.y + node.contentHeight + 10)\n }\n })\n\n state.tracks.forEach(track => {\n track.path.forEach(segment => {\n const y = segment.y ?? 0\n bounds.maxY = Math.max(bounds.maxY, y + track.width)\n bounds.minY = Math.min(bounds.minY, y)\n })\n })\n\n state.imageBounds = bounds\n}\n\n// Resolve a (possibly reverse-oriented) node name to its layout node. Every\n// caller runs after generateNodeMap, so a miss is a programming error.\nfunction nodeByName(state: LayoutState, nodeName: string): LayoutNode {\n const index = state.nodeMap.get(forward(nodeName))\n const node = index === undefined ? undefined : state.nodes[index]\n if (node === undefined) {\n throw new Error(`Unknown node ${nodeName}`)\n }\n return node\n}\n\n// map node names to node indices\nfunction generateNodeMap(state: LayoutState): Map<string, number> {\n const nodeMap = new Map<string, number>()\n state.nodes.forEach((node, index) => {\n nodeMap.set(node.name, index)\n })\n return nodeMap\n}\n\n// adds a successor-array to each node containing the indices of the nodes coming directly after the current node\nfunction generateNodeSuccessors(state: LayoutState): void {\n const successorSets: Set<number>[] = state.nodes.map(() => new Set())\n const predecessorSets: Set<number>[] = state.nodes.map(() => new Set())\n\n const addEdges = (track: Track): void => {\n for (let i = 0; i < track.indexSequence.length - 1; i += 1) {\n const current = Math.abs(track.indexSequence[i]!)\n const follower = Math.abs(track.indexSequence[i + 1]!)\n successorSets[current]!.add(follower)\n predecessorSets[follower]!.add(current)\n }\n }\n\n state.tracks.forEach(addEdges)\n state.reads.forEach(addEdges)\n\n state.nodes.forEach((node, i) => {\n node.successors = Array.from(successorSets[i]!)\n node.predecessors = Array.from(predecessorSets[i]!)\n })\n}\n\nfunction generateNodeOrderOfSingleTrack(\n state: LayoutState,\n sequence: number[],\n): void {\n let forwardOrder = 0\n let backwardOrder = 0\n let minOrder = 0\n\n sequence.forEach(nodeIndex => {\n const idx = Math.abs(nodeIndex)\n if (nodeIndex < 0) {\n const order = (state.nodeOrders[idx] ??= backwardOrder)\n if (order < minOrder) {\n minOrder = order\n }\n forwardOrder = order\n backwardOrder = order - 1\n } else {\n const order = (state.nodeOrders[idx] ??= forwardOrder)\n forwardOrder = order + 1\n backwardOrder = order\n }\n })\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n}\n\n// calculate the order-value of nodes contained in sequence which are to the left of the first node which already has an order-value\nfunction generateNodeOrderTrackBeginning(\n state: LayoutState,\n sequence: number[],\n): number | null {\n let anchorIndex = 0\n let minOrder = 0\n\n while (\n anchorIndex < sequence.length &&\n state.nodeOrders[Math.abs(sequence[anchorIndex]!)] === undefined\n ) {\n anchorIndex += 1 // anchor = first node in common with existing graph\n }\n if (anchorIndex >= sequence.length) {\n return null\n }\n\n const anchorSeqVal = sequence[anchorIndex]!\n let currentOrder: number\n let increment: number\n if (anchorSeqVal >= 0) {\n // regular node\n currentOrder = state.nodeOrders[anchorSeqVal]! - 1\n increment = -1\n } else {\n // reverse node\n currentOrder = state.nodeOrders[-anchorSeqVal]! + 1\n increment = 1\n }\n\n for (let j = anchorIndex - 1; j >= 0; j -= 1) {\n // assign order to nodes which are left of anchor node\n const idx = Math.abs(sequence[j]!)\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder += increment\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n return anchorIndex\n}\n\n// Sentinel order for nodes no track or read reaches.\nexport const UNREACHABLE_ORDER = -1\n\n// Replace every unassigned entry with UNREACHABLE_ORDER, producing a dense\n// array. Holes matter here: `new Array(n)` is all holes and forEach/map skip\n// them, so an in-place forEach would leave the sentinel unset.\nexport function fillUnassignedOrders(\n orders: readonly (number | undefined)[],\n): number[] {\n const filled: number[] = []\n for (const order of orders) {\n filled.push(order ?? UNREACHABLE_ORDER)\n }\n return filled\n}\n\n// generate global sequence of nodes from left to right, starting with first track and adding other tracks sequentially\nfunction generateNodeOrder(state: LayoutState): void {\n let modifiedSequence: number[]\n let currentOrder: number\n let rightIndex: number | null\n let leftIndex: number\n let minOrder = 0\n const tracksAndReads = state.tracks.concat(state.reads)\n const reachability: ReachabilityScratch = {\n stamp: new Int32Array(state.nodes.length),\n generation: 0,\n }\n\n // fill() makes the array dense: `new Array(n)` alone is all holes, which\n // forEach skips, so neither the sentinel pass nor the copy-back below ran.\n state.nodeOrders = new Array<number | undefined>(state.nodes.length).fill(\n undefined,\n )\n // Widened to Node, whose order is optional, to clear the previous run's orders\n state.nodes.forEach((node: Node) => {\n node.order = undefined\n })\n\n generateNodeOrderOfSingleTrack(state, state.tracks[0]!.indexSequence)\n\n for (let i = 1; i < tracksAndReads.length; i += 1) {\n debugLog(`generating order for track ${i + 1}`)\n rightIndex = generateNodeOrderTrackBeginning(\n state,\n tracksAndReads[i]!.indexSequence,\n )\n if (rightIndex === null) {\n if (i < state.tracks.length) {\n generateNodeOrderOfSingleTrack(state, tracksAndReads[i]!.indexSequence)\n } else {\n tracksAndReads.splice(i, 1)\n state.reads.splice(i - state.tracks.length, 1)\n i -= 1\n }\n continue\n }\n modifiedSequence = uninvert(tracksAndReads[i]!.indexSequence)\n\n while (rightIndex < modifiedSequence.length) {\n // move right until the end of the sequence\n leftIndex = rightIndex\n rightIndex += 1\n while (\n rightIndex < modifiedSequence.length &&\n state.nodeOrders[modifiedSequence[rightIndex]!] === undefined\n ) {\n rightIndex += 1\n }\n\n if (rightIndex < modifiedSequence.length) {\n // middle segment between two anchors\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n currentOrder += 1\n }\n\n if (\n state.nodeOrders[modifiedSequence[rightIndex]!]! >\n state.nodeOrders[modifiedSequence[leftIndex]!]!\n ) {\n if (state.nodeOrders[modifiedSequence[rightIndex]!]! < currentOrder) {\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n }\n } else {\n if (\n tracksAndReads[i]!.indexSequence[rightIndex]! >= 0 &&\n !isSuccessor(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[leftIndex]!,\n reachability,\n )\n ) {\n // no real reversal\n increaseOrderForSuccessors(\n state,\n modifiedSequence[rightIndex]!,\n modifiedSequence[rightIndex - 1]!,\n currentOrder,\n )\n } else {\n // real reversal\n if (\n tracksAndReads[i]!.indexSequence[leftIndex]! < 0 ||\n (state.nodes[modifiedSequence[leftIndex + 1]!]!.degree < 2 &&\n state.nodeOrders[modifiedSequence[rightIndex]!]! <\n state.nodeOrders[modifiedSequence[leftIndex]!]!)\n ) {\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < rightIndex; j += 1) {\n state.nodeOrders[modifiedSequence[j]!] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n } else {\n // right segment to the right of last anchor\n if (tracksAndReads[i]!.indexSequence[leftIndex]! >= 0) {\n // elongate towards the right\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! + 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n currentOrder += 1\n }\n }\n } else {\n // elongate towards the left\n currentOrder = state.nodeOrders[modifiedSequence[leftIndex]!]! - 1\n for (let j = leftIndex + 1; j < modifiedSequence.length; j += 1) {\n const idx = modifiedSequence[j]!\n if (state.nodeOrders[idx] === undefined) {\n state.nodeOrders[idx] = currentOrder\n minOrder = Math.min(minOrder, currentOrder)\n currentOrder -= 1\n }\n }\n }\n }\n }\n }\n\n if (minOrder < 0) {\n increaseOrderForAllNodes(state, -minOrder)\n }\n\n // Nodes unreachable from any track get UNREACHABLE_ORDER so every node ends\n // up with a defined order; downstream code uses `order >= 0` to skip them.\n const finalOrders = fillUnassignedOrders(state.nodeOrders)\n state.nodeOrders = finalOrders\n finalOrders.forEach((order, i) => {\n const node = state.nodes[i]\n if (node !== undefined) {\n node.order = order\n }\n })\n}\n\n// Reusable visited-set for the reachability searches in generateNodeOrder.\n// Stamping with a generation counter avoids reallocating (and re-zeroing) an\n// array of nodes.length booleans on every call.\ninterface ReachabilityScratch {\n stamp: Int32Array\n generation: number\n}\n\nfunction isSuccessor(\n state: LayoutState,\n first: number,\n second: number,\n scratch: ReachabilityScratch,\n): boolean {\n scratch.generation += 1\n const { stamp, generation } = scratch\n const stack: number[] = [first]\n stamp[first] = generation\n while (stack.length > 0) {\n const current = stack.pop()!\n if (current === second) {\n return true\n }\n for (const childIndex of state.nodes[current]!.successors) {\n if (stamp[childIndex] !== generation) {\n stamp[childIndex] = generation\n stack.push(childIndex)\n }\n }\n }\n return false\n}\n\n// get order number of the rightmost node\nfunction getMaxOrder(state: LayoutState): number {\n let max = -1\n state.nodeOrders.forEach(order => {\n if (order !== undefined && order > max) {\n max = order\n }\n })\n return max\n}\n\n// generates sequence keeping the order but switching all reversed (negative) nodes to forward nodes\nfunction uninvert(sequence: number[]): number[] {\n return sequence.map(v => Math.abs(v))\n}\n\n// increases the order-value of all nodes by amount\nfunction increaseOrderForAllNodes(state: LayoutState, amount: number): void {\n state.nodeOrders.forEach((order, i) => {\n if (order !== undefined) {\n state.nodeOrders[i] = order + amount\n }\n })\n}\n\n// increases the order-value for currentNode and (if necessary) successor nodes recursively\nfunction increaseOrderForSuccessors(\n state: LayoutState,\n startingNode: number,\n tabuNode: number,\n newOrder: number,\n): void {\n const increasedOrders = new Map<number, number>()\n // Walked with a head pointer rather than shift(), which is O(length) per pop.\n const queue: [number, number][] = [[startingNode, newOrder]]\n let head = 0\n\n while (head < queue.length) {\n const [currentNode, currentOrder] = queue[head]!\n head += 1\n const currentNodeOrder = state.nodeOrders[currentNode]\n\n if (currentNodeOrder !== undefined && currentNodeOrder < currentOrder) {\n if (\n !increasedOrders.has(currentNode) ||\n increasedOrders.get(currentNode)! < currentOrder\n ) {\n increasedOrders.set(currentNode, currentOrder)\n state.nodes[currentNode]!.successors.forEach(successor => {\n if (\n state.nodeOrders[successor]! > currentNodeOrder &&\n successor !== tabuNode\n ) {\n // only increase order of successors to the right of currentNode\n queue.push([successor, currentOrder + 1])\n }\n })\n if (currentNode !== startingNode) {\n state.nodes[currentNode]!.predecessors.forEach(predecessor => {\n if (\n state.nodeOrders[predecessor]! > currentNodeOrder &&\n predecessor !== tabuNode\n ) {\n // only increase order of predecessors to the right of currentNode\n queue.push([predecessor, currentOrder + 1])\n }\n })\n }\n }\n }\n }\n\n increasedOrders.forEach((value, key) => {\n state.nodeOrders[key] = value\n })\n}\n\n// calculates the node degree: the number of tracks passing through the node / the node height\nfunction generateNodeDegree(state: LayoutState): void {\n state.nodes.forEach(node => {\n node.tracks = []\n })\n\n state.tracks.forEach(track => {\n track.indexSequence.forEach(nodeIndex => {\n state.nodes[Math.abs(nodeIndex)]!.tracks.push(track.id)\n })\n })\n\n state.nodes.forEach(node => {\n node.degree = node.tracks.length\n })\n}\n\n// Orient the nodes to suit the tracks and reads\nfunction switchNodeOrientation(state: LayoutState): void {\n switchNodeOrientationForPaths(\n state,\n [...state.tracks.slice(1), ...state.reads],\n state.tracks[0]!,\n )\n}\n\n// If more of the given paths pass through a specific node in reverse direction than in\n// regular direction, switch its orientation. Nodes the pivot path visits\n// forward keep theirs. Processes all paths' nodes in place, reading each\n// visit's node from its indexSequence, which must match its sequence.\nfunction switchNodeOrientationForPaths(\n state: LayoutState,\n paths: Track[],\n pivotPath: Track,\n): void {\n const scores = new Int32Array(state.nodes.length)\n const onPivot = new Uint8Array(state.nodes.length)\n for (const nodeName of pivotPath.sequence) {\n const index = isReverse(nodeName) ? undefined : state.nodeMap.get(nodeName)\n if (index !== undefined) {\n onPivot[index] = 1\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n const last = indexSequence.length - 1\n for (let j = 0; j <= last; j += 1) {\n const index = Math.abs(indexSequence[j]!)\n if (onPivot[index] === 1) {\n continue\n }\n const order = state.nodes[index]!.order\n const prevOrder =\n j > 0 ? state.nodes[Math.abs(indexSequence[j - 1]!)]!.order : undefined\n const nextOrder =\n j < last\n ? state.nodes[Math.abs(indexSequence[j + 1]!)]!.order\n : undefined\n // A reverse visit votes for switching when the path runs left to right\n // through the node, and against when it runs right to left.\n const vote = isReverse(sequence[j]!) ? 1 : -1\n if (\n (prevOrder === undefined || prevOrder < order) &&\n (nextOrder === undefined || order < nextOrder)\n ) {\n scores[index]! += vote\n }\n if (\n (prevOrder === undefined || prevOrder > order) &&\n (nextOrder === undefined || order > nextOrder)\n ) {\n scores[index]! -= vote\n }\n }\n }\n\n for (const path of paths) {\n const { sequence, indexSequence } = path\n for (let j = 0; j < indexSequence.length; j += 1) {\n if (scores[Math.abs(indexSequence[j]!)]! > 0) {\n sequence[j] = flip(sequence[j]!)\n indexSequence[j] = -indexSequence[j]!\n }\n }\n }\n\n state.nodes.forEach((node, index) => {\n if (scores[index]! > 0) {\n node.seq = getReverseComplement(node.seq)\n node.switched = true\n }\n })\n}\n\n// calculates the concrete values for the nodes' x-coordinates\nfunction generateNodeXCoords(state: LayoutState): void {\n let currentX = 0\n let nextX = 20\n let currentOrder = -1\n const sortedNodes = state.nodes.slice()\n sortedNodes.sort(compareNodesByOrder)\n const extra = calculateExtraSpace(state)\n\n sortedNodes.forEach(node => {\n if (node.order >= 0) {\n if (node.order > currentOrder) {\n currentOrder = node.order\n currentX = nextX + 10 * extra[node.order]!\n }\n node.x = currentX\n nextX = Math.max(nextX, currentX + 40 + node.pixelWidth)\n }\n })\n}\n\n// calculates additional horizontal space needed between two nodes\n// two neighboring nodes have to be moved further apart if there is a lot going on in between them\n// -> edges turning to vertical orientation should not overlap\nfunction calculateExtraSpace(state: LayoutState): number[] {\n const leftSideEdges: number[] = []\n const rightSideEdges: number[] = []\n const fallAngleAdjustment: number[] = []\n const extra: number[] = []\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n leftSideEdges.push(0)\n rightSideEdges.push(0)\n fallAngleAdjustment.push(0)\n }\n\n state.tracks.forEach(track => {\n for (let i = 1; i < track.path.length; i += 1) {\n const seg = track.path[i]!\n const prevSeg = track.path[i - 1]!\n // Track is going to the same node, account for space taken up by edges looping around\n if (seg.order === prevSeg.order) {\n // repeat or translocation\n if (seg.isForward) {\n leftSideEdges[seg.order] = leftSideEdges[seg.order]! + 1\n } else {\n rightSideEdges[seg.order] = rightSideEdges[seg.order]! + 1\n }\n } else {\n // Track is going to a different node; account for space needed to limit rise/fall angle\n const yDifference = Math.abs((seg.y ?? 0) - (prevSeg.y ?? 0))\n // TODO: Extra space should also be accounted when there are too many tracks curving at the nodes\n fallAngleAdjustment[seg.order] = Math.max(\n yDifference / 17.5,\n fallAngleAdjustment[seg.order]!,\n )\n }\n }\n })\n\n extra.push(Math.max(0, leftSideEdges[0]! - 1))\n for (let i = 1; i <= state.maxOrder; i += 1) {\n // Extra space uses space needed for edges(tracks looping), or space needed to limit rise/fall angle, whichever is larger\n extra.push(\n Math.max(\n Math.max(0, leftSideEdges[i]! - 1) +\n Math.max(0, rightSideEdges[i - 1]! - 1),\n fallAngleAdjustment[i]!,\n ),\n )\n }\n return extra\n}\n\n// create and fill assignment-variable, which contains info about tracks and lanes for each order-value\nfunction generateLaneAssignment(state: LayoutState): void {\n // For each horizontal order slot, for each track number, holds the\n // SegmentAssignment object for the visit of that track to that order slot.\n // When an order slot is visited multiple times, holds whatever\n // SegmentAssignment was created most recently.\n const prevSegmentPerOrderPerTrack: SegmentAssignment[][] = []\n // Index into assignments[order] by node, so addToAssignment can find an\n // existing entry without scanning the whole order slot.\n const assignmentByOrderAndNode: Map<number, NodeAssignment>[] = []\n\n // create empty variables\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.assignments[i] = []\n assignmentByOrderAndNode[i] = new Map()\n prevSegmentPerOrderPerTrack[i] = []\n }\n\n // Record each track's segments in the order slots they cross, leaving the\n // lanes for the sweep below.\n state.tracks.forEach((track, trackNo) => {\n track.path = basicPath(state, track)\n track.path.forEach((segment, segmentNumber) => {\n addToAssignment(\n state,\n segment.order,\n segment.node,\n trackNo,\n segmentNumber,\n prevSegmentPerOrderPerTrack,\n assignmentByOrderAndNode,\n )\n })\n })\n\n // Now sweep left to right across order slots and assign vertical lanes to all the segments.\n for (let i = 0; i <= state.maxOrder; i += 1) {\n generateSingleLaneAssignment(state, state.assignments[i]!, i) // this is where the lanes get assigned\n }\n}\n\nfunction addToAssignment(\n state: LayoutState,\n order: number,\n nodeIndex: number | null,\n trackNo: number,\n segmentID: number,\n prevSegmentPerOrderPerTrack: SegmentAssignment[][],\n assignmentByOrderAndNode: Map<number, NodeAssignment>[],\n): void {\n const segment: SegmentAssignment = {\n trackID: trackNo,\n segmentID,\n compareToFromSame: prevSegmentPerOrderPerTrack[order]![trackNo] ?? null,\n }\n // A null node means the track is passing through / turning around here rather\n // than visiting a node, so such segments never share a NodeAssignment.\n const existing =\n nodeIndex === null\n ? undefined\n : assignmentByOrderAndNode[order]!.get(nodeIndex)\n\n if (existing === undefined) {\n const assignment: NodeAssignment = {\n type: 'single',\n node: nodeIndex,\n tracks: [segment],\n }\n state.assignments[order]!.push(assignment)\n if (nodeIndex !== null) {\n assignmentByOrderAndNode[order]!.set(nodeIndex, assignment)\n }\n } else {\n // add to existing node in assignment\n existing.type = 'multiple'\n existing.tracks.push(segment)\n }\n prevSegmentPerOrderPerTrack[order]![trackNo] = segment\n}\n\n// looks at assignment and sets idealY and idealLane by looking at where the tracks come from\nfunction getIdealLanesAndCoords(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let index: number\n\n assignment.forEach(node => {\n node.idealLane = 0\n node.tracks.forEach(track => {\n if (track.segmentID === 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n if (\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID - 1]!.y\n } else if (\n track.segmentID < state.tracks[track.trackID]!.path.length - 1 &&\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.order ===\n order - 1\n ) {\n track.idealLane =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.lane ??\n undefined\n track.idealY =\n state.tracks[track.trackID]!.path[track.segmentID + 1]!.y\n } else {\n index = track.segmentID - 1\n while (\n index >= 0 &&\n state.tracks[track.trackID]!.path[index]!.order !== order - 1\n ) {\n index -= 1\n }\n if (index < 0) {\n track.idealLane = track.trackID\n track.idealY = null\n } else {\n track.idealLane = state.tracks[track.trackID]!.path[index]!.lane\n track.idealY = state.tracks[track.trackID]!.path[index]!.y\n }\n }\n }\n node.idealLane! += track.idealLane!\n })\n node.idealLane /= node.tracks.length\n })\n}\n\n// assigns the optimal lanes for a single horizontal position (=order)\n// first an ideal lane is calculated for each track (which is ~ the lane of its predecessor)\n// then the nodes are sorted by their average ideal lane\n// and the whole construct is then moved up or down if necessary\nfunction generateSingleLaneAssignment(\n state: LayoutState,\n assignment: NodeAssignment[],\n order: number,\n): void {\n let currentLane = 0\n const potentialAdjustmentValues = new Set<number>()\n let currentY = 20\n let prevNameIsNull = false\n let prevTrack = -1\n\n getIdealLanesAndCoords(state, assignment, order)\n assignment.sort(compareByIdealLane)\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.topLane = currentLane\n if (prevNameIsNull) {\n currentY -= 10\n }\n state.nodes[node.node]!.y = currentY\n state.nodes[node.node]!.contentHeight = 0\n prevNameIsNull = false\n } else {\n if (prevNameIsNull) {\n currentY -= 25\n } else if (currentY > 20) {\n currentY -= 10\n }\n prevNameIsNull = true\n }\n\n node.tracks.sort(compareByIdealLane)\n node.tracks.forEach(track => {\n track.lane = currentLane\n if (track.trackID === prevTrack && node.node === null && prevNameIsNull) {\n currentY += 10\n }\n state.tracks[track.trackID]!.path[track.segmentID]!.lane = currentLane\n state.tracks[track.trackID]!.path[track.segmentID]!.y = currentY\n if (typeof track.idealY === 'number') {\n potentialAdjustmentValues.add(track.idealY - currentY)\n }\n currentLane += 1\n currentY += state.tracks[track.trackID]!.width\n if (node.node !== null) {\n state.nodes[node.node]!.contentHeight +=\n state.tracks[track.trackID]!.width\n }\n prevTrack = track.trackID\n })\n currentY += 25\n })\n\n adjustVertically(state, assignment, potentialAdjustmentValues)\n}\n\n// moves all tracks at a single horizontal location (=order) up/down to minimize lane changes\nfunction adjustVertically(\n state: LayoutState,\n assignment: NodeAssignment[],\n potentialAdjustmentValues: Set<number>,\n): void {\n let verticalAdjustment = 0\n let minAdjustmentCost = Number.MAX_SAFE_INTEGER\n\n potentialAdjustmentValues.forEach(moveBy => {\n const cost = getVerticalAdjustmentCost(state, assignment, moveBy)\n if (cost < minAdjustmentCost) {\n minAdjustmentCost = cost\n verticalAdjustment = moveBy\n }\n })\n\n assignment.forEach(node => {\n if (node.node !== null) {\n state.nodes[node.node]!.y += verticalAdjustment\n }\n node.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + verticalAdjustment\n })\n })\n}\n\n// Budge down all nodes and out-of-node tracks below this node by this amount\nfunction adjustVertically3(\n state: LayoutState,\n node: LayoutNode,\n adjustBy: number,\n): void {\n if (node.order < 0 || state.assignments[node.order] === undefined) {\n return\n }\n state.assignments[node.order]!.forEach(assignmentNode => {\n if (assignmentNode.node !== null) {\n const aNode = state.nodes[assignmentNode.node]!\n if (aNode !== node && aNode.y > node.y) {\n aNode.y += adjustBy\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n seg.y = seg.y! + adjustBy\n })\n }\n } else {\n // track-segment not within a node\n assignmentNode.tracks.forEach(track => {\n const seg = state.tracks[track.trackID]!.path[track.segmentID]!\n if (seg.y! >= node.y) {\n seg.y = seg.y! + adjustBy\n }\n })\n }\n })\n if (state.nodesPerOrder[node.order]!.length > 0) {\n state.nodesPerOrder[node.order]!.forEach(nodeIndex => {\n if (\n state.nodes[nodeIndex] !== node &&\n state.nodes[nodeIndex]!.y > node.y\n ) {\n state.nodes[nodeIndex]!.y += adjustBy\n }\n })\n }\n}\n\n// calculates cost of vertical adjustment as vertical distance * width of track\nfunction getVerticalAdjustmentCost(\n state: LayoutState,\n assignment: NodeAssignment[],\n moveBy: number,\n): number {\n let result = 0\n assignment.forEach(node => {\n node.tracks.forEach(track => {\n if (\n typeof track.idealY === 'number' &&\n state.tracks[track.trackID]!.type !== 'read'\n ) {\n result +=\n Math.abs(\n track.idealY -\n moveBy -\n state.tracks[track.trackID]!.path[track.segmentID]!.y!,\n ) * state.tracks[track.trackID]!.width\n }\n })\n })\n return result\n}\n\nfunction compareByIdealLane(\n a: { idealLane?: number | undefined },\n b: { idealLane?: number | undefined },\n): number {\n if (a.idealLane !== undefined) {\n if (b.idealLane !== undefined) {\n if (a.idealLane < b.idealLane) {\n return -1\n } else if (a.idealLane > b.idealLane) {\n return 1\n }\n return 0\n }\n return -1\n }\n if (b.idealLane !== undefined) {\n return 1\n }\n return 0\n}\n\nfunction compareNodesByOrder(\n a: MaybeUnplacedNode,\n b: MaybeUnplacedNode,\n): number {\n if (a.order !== b.order) {\n return a.order - b.order\n }\n if (a.y !== undefined && b.y !== undefined) {\n return a.y - b.y\n }\n return 0\n}\n\nfunction calculateTrackWidth(state: LayoutState): void {\n // flag: if vg returns freq of 0 for all tracks, we will increase width manually\n let allAreFour = true\n\n const NARROW_WIDTH = 4\n const WIDE_WIDTH = state.config.trackWidth\n\n for (const track of state.tracks) {\n if (track.freq !== undefined) {\n track.width = Math.round(\n (Math.log(Math.max(track.freq, 1)) + 1) * NARROW_WIDTH,\n )\n } else {\n // default track width\n track.width = WIDE_WIDTH\n if (track.type !== undefined && track.type === 'read') {\n track.width = NARROW_WIDTH\n }\n }\n if (track.width !== NARROW_WIDTH) {\n allAreFour = false\n }\n }\n\n if (allAreFour) {\n state.tracks.forEach(track => {\n if (track.freq !== undefined) {\n track.width = WIDE_WIDTH\n }\n })\n }\n}\n\nfunction getReadXStart(state: LayoutState, read: Track): number {\n const seg = read.path[0]!\n const node = state.nodes[seg.node!]!\n const offset = read.firstNodeOffset ?? 0\n // read starts in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? offset : node.sequenceLength - offset,\n )\n}\n\nfunction getReadXEnd(state: LayoutState, read: Track): number {\n const seg = read.path[read.path.length - 1]!\n const node = state.nodes[seg.node!]!\n const cover = read.finalNodeCoverLength ?? 0\n // read ends in forward direction, or backward from the node's far end\n return clampedXCoordinateOfBaseWithinNode(\n node,\n seg.isForward ? cover : node.sequenceLength - cover,\n )\n}\n\n// returns the x coordinate (in pixels) of (the left side) of the given base\n// position within the given node, or null if the position is past its end\nexport function getXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number | null {\n if (base > node.sequenceLength) {\n return null\n } // equality is allowed\n return clampedXCoordinateOfBaseWithinNode(node, base)\n}\n\n// Same, but a base outside the node maps to the nearest node edge. Callers that\n// have to produce a coordinate no matter what use this: falling back to 0 would\n// put the shape at the far left of the whole image instead.\nexport function clampedXCoordinateOfBaseWithinNode(\n node: Node,\n base: number,\n): number {\n const [nodeLeftX, nodeRightX] = nodePixelCoordinatesInX(node)\n if (node.sequenceLength === 0) {\n return nodeLeftX\n }\n const clamped = Math.min(Math.max(base, 0), node.sequenceLength)\n return nodeLeftX + (clamped / node.sequenceLength) * (nodeRightX - nodeLeftX)\n}\n\n// transforms the info in the tracks' path attribute into actual coordinates\n// and saves them in shapes.rectangles and shapes.curves\nfunction generateSVGShapesFromPath(state: LayoutState): void {\n let xStart: number\n let xEnd: number\n let yStart: number\n let yEnd: number\n\n for (let i = 0; i <= state.maxOrder; i += 1) {\n state.extraLeft.push(0)\n state.extraRight.push(0)\n }\n\n // generate x coords where each order starts and ends\n const orderStartX: number[] = []\n const orderEndX: number[] = []\n state.nodes.forEach((node: MaybeUnplacedNode) => {\n if (node.x !== undefined) {\n orderStartX[node.order] = node.x\n if (orderEndX[node.order] === undefined) {\n orderEndX[node.order] = node.x + node.pixelWidth\n } else {\n orderEndX[node.order] = Math.max(\n orderEndX[node.order]!,\n node.x + node.pixelWidth,\n )\n }\n }\n })\n\n // Helps generation of verticalRectangles, correct increments of extraRight and extraLeft\n state.tracks.sort(compareTrackByInitialOrdering)\n\n state.tracks.forEach(track => {\n // start of path\n yStart = track.path[0]!.y!\n if (track.type !== 'read') {\n if (track.sequence[0]!.startsWith('-')) {\n // The track starts with an inversed node\n xStart = orderEndX[track.path[0]!.order]! + 20\n } else {\n // The track starts with a forward node\n xStart = orderStartX[track.path[0]!.order]! - 20\n }\n } else {\n xStart = getReadXStart(state, track)\n }\n\n // middle of path\n for (let i = 0; i < track.path.length; i += 1) {\n if (track.path[i]!.y !== yStart) {\n if (track.path[i - 1]!.isForward) {\n xEnd = orderEndX[track.path[i - 1]!.order]!\n } else {\n xEnd = orderStartX[track.path[i - 1]!.order]!\n }\n if (xEnd !== xStart) {\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n // TODO: This is not actually the index of the track!\n id: track.id,\n name: track.name,\n type: track.type,\n })\n }\n\n if (track.path[i]!.order - 1 === track.path[i - 1]!.order) {\n // regular forward connection\n xStart = xEnd\n xEnd = orderStartX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart,\n yStart,\n xEnd: xEnd + 1,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n })\n xStart = xEnd\n yStart = yEnd\n } else if (track.path[i]!.order + 1 === track.path[i - 1]!.order) {\n // regular backward connection\n xStart = xEnd\n xEnd = orderEndX[track.path[i]!.order]!\n yEnd = track.path[i]!.y!\n state.shapes.curves.push({\n xStart: xStart + 1,\n yStart,\n xEnd,\n yEnd,\n width: track.width,\n id: track.id,\n name: track.name,\n type: track.type,\n nodeStart: track.path[i - 1]!.node,\n nodeEnd: track.path[i]!.node,\n orderStart: track.path[i - 1]!.order,\n orderEnd: track.path[i]!.order,\n })\n xStart = xEnd\n yStart = yEnd\n } else {\n // change of direction\n if (track.path[i - 1]!.isForward) {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n 1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderEndX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n } else {\n yEnd = track.path[i]!.y!\n generateTurnaround(\n state,\n -1,\n xEnd,\n yStart,\n yEnd,\n track.width,\n track.id,\n track.path[i]!.order,\n track.type,\n track.name,\n )\n xStart = orderStartX[track.path[i]!.order]!\n yStart = track.path[i]!.y!\n }\n }\n }\n }\n\n // ending edges\n if (track.type !== 'read') {\n if (!track.path[track.path.length - 1]!.isForward) {\n // The track ends with an inversed node\n xEnd = orderStartX[track.path[track.path.length - 1]!.order]! - 20\n } else {\n // The track ends with a forward node\n xEnd = orderEndX[track.path[track.path.length - 1]!.order]! + 20\n }\n } else {\n xEnd = getReadXEnd(state, track)\n }\n state.shapes.rectangles.push({\n xStart: Math.min(xStart, xEnd),\n yStart,\n xEnd: Math.max(xStart, xEnd),\n yEnd: yStart + track.width - 1,\n id: track.id,\n name: track.name,\n type: track.type,\n })\n })\n}\n\n// Sankey-mode synthesis: one synthetic \"read\" per (srcSigned \u2192 dstSigned) edge,\n// fed through the normal placeReads/generateSVGShapesFromPath pipeline so the\n// band gets the same lane assignment, loop topology and bezier shape as a real\n// read. A read band takes its source's palette; a haplotype band carries its\n// share of the haplotypes for the colorer to shade by.\n//\n// Synthetic-track ids live above this base so they don't collide with real\n// track ids and so click/hover handlers can show count info instead of the\n// per-read info dialog.\nconst COARSENED_ID_BASE = 1_000_000_000\nexport const isCoarsenedId = (id: number) => id >= COARSENED_ID_BASE\n\n// Build one synthetic read per (srcSigned \u2192 dstSigned) edge in `source`\n// (real reads, or the alt haplotype tracks). The synthetic reads replace the\n// real ones BEFORE placeReads runs, so:\n// \u2022 placeReads sees N_edges reads instead of N_reads (huge node-height win),\n// \u2022 each band gets a lane and an \"right-down-left-up-right\" loop topology\n// for free (placeReads handles reversals and out-of-order jumps),\n// \u2022 generateSVGShapesFromPath emits exactly one TrackCurve per band using\n// the same bezier as a real read \u2014 no special draw path needed.\n//\n// The synthetic track's `sequence` is just the two signed node names. After\n// generateTrackIndexSequences runs, indexSequence is set and the rest of the\n// layout follows.\nfunction buildCoarsenedSyntheticBands(\n state: LayoutState,\n source: Track[],\n unit: CoarsenedUnit,\n firstId = COARSENED_ID_BASE,\n): { bands: Track[]; total: number } {\n // Aggregate by signed-edge key. Preserve orientation so e.g. (+A\u2192+B) and\n // (-B\u2192-A) stack as separate bands \u2014 they're different visual flows.\n interface EdgeAgg {\n sSigned: number\n dSigned: number\n sName: string\n dName: string\n // distinct walks, so a walk that loops back over an edge, or crosses it\n // both ways under ignoreStrand, counts once\n count: number\n // every crossing, loops included, which is what sizes the band\n crossings: number\n sourceTrackID: number\n lastSource: number\n }\n const edges = new Map<number, EdgeAgg>()\n let total = 0\n // One number per signed edge: signed indices run from -span to span.\n const span = state.nodes.length\n const edgeKey = (s: number, d: number): number =>\n (s + span) * (2 * span + 1) + d + span\n // When ignoring strand, (+A\u2192+B) and (-B\u2192-A) refer to the same underlying\n // graph connection, so both collapse into the smaller of their two keys;\n // whichever orientation is seen first determines the visual band direction.\n const ignoreStrand = state.config.ignoreStrand\n for (const [sourceIndex, item] of source.entries()) {\n // a deduplicated walk stands for `freq` identical haplotypes\n const weight = Math.max(item.freq ?? 1, 1)\n total += weight\n const seq = item.indexSequence\n if (seq.length < 2) {\n continue\n }\n for (let i = 0; i < seq.length - 1; i += 1) {\n const sSigned = seq[i]!\n const dSigned = seq[i + 1]!\n const srcNode = state.nodes[Math.abs(sSigned)]!\n const dstNode = state.nodes[Math.abs(dSigned)]!\n const key = ignoreStrand\n ? Math.min(edgeKey(sSigned, dSigned), edgeKey(-dSigned, -sSigned))\n : edgeKey(sSigned, dSigned)\n const existing = edges.get(key)\n if (existing === undefined) {\n edges.set(key, {\n sSigned,\n dSigned,\n sName: sSigned < 0 ? `-${srcNode.name}` : srcNode.name,\n dName: dSigned < 0 ? `-${dstNode.name}` : dstNode.name,\n count: weight,\n crossings: weight,\n sourceTrackID: item.sourceTrackID,\n lastSource: sourceIndex,\n })\n } else {\n existing.crossings += weight\n if (existing.lastSource !== sourceIndex) {\n existing.count += weight\n existing.lastSource = sourceIndex\n }\n }\n }\n }\n\n // Square-root scaling on crossings gives heavy edges visible weight without\n // letting one massive edge dwarf everything else. Min stays near READ_WIDTH\n // so single-read edges still look like a normal read; max is generous so\n // hot edges read as obvious \"highways.\"\n let maxEdgeCount = 0\n for (const e of edges.values()) {\n if (e.crossings > maxEdgeCount) {\n maxEdgeCount = e.crossings\n }\n }\n const BAND_MIN_WIDTH = READ_WIDTH\n const BAND_MAX_WIDTH = 60\n const widthForCount = (c: number): number => {\n if (maxEdgeCount <= 1) {\n return BAND_MIN_WIDTH\n }\n return (\n BAND_MIN_WIDTH +\n (BAND_MAX_WIDTH - BAND_MIN_WIDTH) * Math.sqrt(c / maxEdgeCount)\n )\n }\n\n const synthetic: Track[] = []\n let i = 0\n for (const edge of edges.values()) {\n const id = firstId + i\n const share =\n unit === 'haplotype' ? { count: edge.count, total } : undefined\n const shareText = share === undefined ? '' : ` (${formatShare(share)})`\n const crossingsText =\n edge.crossings === edge.count\n ? ''\n : `, ${edge.crossings.toLocaleString()} crossings`\n const label = `${edge.count.toLocaleString()} ${unit}${edge.count === 1 ? '' : 's'}${shareText}${crossingsText}: Node ${edge.sName} \u2192 Node ${edge.dName}`\n state.coarsenedEdgeMeta.set(id, { count: edge.count, label })\n // Place each synthetic band so it touches *only* its endpoint nodes' edges:\n // \u2022 firstNodeOffset = src.sequenceLength \u2192 curve exits at src's right\n // pixel edge, no rectangle drawn inside src.\n // \u2022 finalNodeCoverLength = 0 \u2192 curve enters at dst's left pixel edge,\n // no rectangle drawn inside dst.\n // The crucial side effect is in placeReadSet's conflict check: at any\n // node B with an incoming edge (A\u2192B) and an outgoing edge (B\u2192C), the\n // incoming's finalNodeCoverLength=0 and the outgoing's firstNodeOffset=\n // B.length leave them with no horizontal overlap, so they share a single\n // lane. Node heights collapse from ~(N_in + N_out) lanes down to\n // ~max(N_in, N_out) lanes.\n //\n // Note: reverseReversedReads will swap firstNodeOffset/finalNodeCoverLength\n // for fully-reverse synthetics. The math works out: pre-flip values of\n // (srcLen, 0) become post-flip (newSrcLen, 0), which is the same pattern\n // \u2014 bands stay edge-only regardless of orientation.\n const srcLen = state.nodes[Math.abs(edge.sSigned)]!.sequenceLength\n synthetic.push({\n id,\n sourceTrackID: edge.sourceTrackID,\n type: 'read',\n // Human-readable so the name surfaces sensibly in any UI that uses it\n // (right-click \u2192 add to group, etc.) \u2014 and so trackTooltipText fallback\n // shows something meaningful.\n name: label,\n sequence: [edge.sName, edge.dName],\n indexSequence: [],\n path: [],\n // Pre-set width so placeReads / placeReadSet allocate the right vertical\n // space and assignReadsToNodes (patched to honor pre-set widths) leaves\n // it alone.\n width: widthForCount(edge.crossings),\n firstNodeOffset: srcLen,\n finalNodeCoverLength: 0,\n sequenceNew: [\n { nodeName: edge.sName, mismatches: [] },\n { nodeName: edge.dName, mismatches: [] },\n ],\n mapping_quality: 0,\n is_secondary: false,\n sample_name: null,\n read_group: null,\n score: edge.count,\n haplotypeShare: share,\n })\n i += 1\n }\n\n if (DEBUG) {\n let tallestName = '?'\n let tallestH = 0\n state.nodes.forEach(n => {\n if (n.contentHeight > tallestH) {\n tallestH = n.contentHeight\n tallestName = n.name\n }\n })\n debugLog(\n `[coarsened] ${unit}s_in=${source.length} edges_out=${synthetic.length} ` +\n `tallestNodeBeforePlace=${tallestName}(${tallestH.toFixed(1)})`,\n )\n }\n return { bands: synthetic, total }\n}\n\n// Band every haplotype but the reference, which keeps its lane and the ruler.\n// Undefined when no alternate crosses an edge: a haplotype that stays on one\n// node makes no band, and its node would get no y from the read overlay.\nfunction bandHaplotypes(\n state: LayoutState,\n firstId: number,\n): { ref: Track; bands: Track[]; total: number } | undefined {\n const rulerIndex =\n state.trackForRuler === undefined\n ? -1\n : state.tracks.findIndex(t => t.name === state.trackForRuler)\n const refIndex = rulerIndex === -1 ? 0 : rulerIndex\n const ref = state.tracks[refIndex]!\n // A deduplicated reference walk also stands for the haplotypes identical to\n // it through the window; those belong in the bands, not the reference lane.\n const refDuplicates = (ref.freq ?? 1) - 1\n const refSigns = firstVisitSigns(state, ref)\n const altHaplotypes = state.tracks\n .filter((_, i) => i !== refIndex)\n .map(walk => orientedLike(refSigns, walk))\n if (refDuplicates > 0) {\n altHaplotypes.push({ ...ref, freq: refDuplicates })\n }\n if (altHaplotypes.length === 0) {\n return undefined\n }\n const { bands, total } = buildCoarsenedSyntheticBands(\n state,\n altHaplotypes,\n 'haplotype',\n firstId,\n )\n return bands.length > 0 ? { ref, bands, total } : undefined\n}\n\n// A graph can store a walk in either orientation, so a haplotype can arrive\n// back to front relative to the reference. Banded that way, one allele splits\n// into a forward and a reverse band. Turn a walk around when it runs against\n// the reference on most of the nodes they share.\nfunction orientedLike(refSigns: Int8Array, walk: Track): Track {\n let agreement = 0\n for (const visit of walk.indexSequence) {\n const sign = refSigns[Math.abs(visit)]\n if (sign !== undefined && sign !== 0) {\n agreement += sign === Math.sign(visit) ? 1 : -1\n }\n }\n return agreement >= 0\n ? walk\n : {\n ...walk,\n sequence: walk.sequence.map(flip).reverse(),\n indexSequence: walk.indexSequence.map(visit => -visit).reverse(),\n }\n}\n\n// The sign of `ref`'s first visit to each node index, 0 where it never visits.\nfunction firstVisitSigns(state: LayoutState, ref: Track): Int8Array {\n const signs = new Int8Array(state.nodes.length)\n for (const visit of ref.indexSequence) {\n const node = Math.abs(visit)\n if (signs[node] === 0) {\n signs[node] = Math.sign(visit)\n }\n }\n return signs\n}\n\nfunction formatShare({ count, total }: HaplotypeShare): string {\n const share = count / total\n if (share < 0.01) {\n return '<1%'\n }\n if (share > 0.99 && count < total) {\n return '>99%'\n }\n return `${Math.round(share * 100)}%`\n}\n\nconst MIN_BEND_WIDTH = 7\n\n// Emit the vertical rectangles + rounded corners for a track turning around at\n// one end of an order slot. The two directions are mirror images of each other:\n// a forward-to-reverse turn bulges out to the right of the node and consumes an\n// `extraRight` slot, a reverse-to-forward turn bulges out to the left and\n// consumes an `extraLeft` slot. `dir` is +1 for right, -1 for left.\nfunction generateTurnaround(\n state: LayoutState,\n dir: 1 | -1,\n x: number,\n yStart: number,\n yEnd: number,\n trackWidth: number,\n trackID: number,\n order: number,\n type: TrackType | undefined,\n trackName: string | undefined,\n): void {\n const extra = dir === 1 ? state.extraRight : state.extraLeft\n const offset = 10 * extra[order]!\n // The turn's apex, and the outward direction from it.\n const apex = x + dir * (offset + 5)\n const radius = MIN_BEND_WIDTH\n const stem = Math.min(MIN_BEND_WIDTH, trackWidth)\n const yTop = Math.min(yStart, yEnd)\n const yBottom = Math.max(yStart, yEnd)\n // The incoming/outgoing stubs run from the node's edge out to the apex. The\n // one-pixel asymmetry between the two directions is carried over verbatim\n // from the original pair of functions.\n const stubNear = dir === 1 ? x : apex - 1\n const stubFar = dir === 1 ? apex : x\n\n const horizontal = (segTop: number): void => {\n state.shapes.verticalRectangles.push({\n xStart: stubNear,\n yStart: segTop,\n xEnd: stubFar,\n yEnd: segTop + trackWidth - 1,\n id: trackID,\n name: trackName,\n type,\n })\n }\n // elongate the incoming and outgoing rectangles a bit past the node\n horizontal(yStart)\n state.shapes.verticalRectangles.push({\n xStart: dir === 1 ? apex + radius : apex - radius - stem,\n yStart: yTop + trackWidth + radius - 1,\n xEnd: dir === 1 ? apex + radius + stem - 1 : apex - radius - 1,\n yEnd: yBottom - radius + 1,\n id: trackID,\n name: trackName,\n type,\n })\n horizontal(yEnd)\n\n const inner = apex + dir * radius\n const outer = apex + dir * (radius + stem)\n\n // bottom 90 degree bend\n let d = `M ${apex} ${yBottom}`\n d += ` Q ${inner} ${yBottom} ${inner} ${yBottom - radius}`\n d += ` H ${outer}`\n d += ` Q ${outer} ${yBottom + trackWidth} ${apex} ${yBottom + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n\n // top 90 degree bend\n d = `M ${apex} ${yTop}`\n d += ` Q ${outer} ${yTop} ${outer} ${yTop + trackWidth + radius}`\n d += ` H ${inner}`\n d += ` Q ${inner} ${yTop + trackWidth} ${apex} ${yTop + trackWidth}`\n d += ' Z '\n state.shapes.corners.push({ path: d, id: trackID, type })\n extra[order]! += 1\n}\n\n// The x extent of a node's bases: pixelWidth, plus about half a character\n// each side under nodeWidthOption 'normal'\nexport function nodePixelCoordinatesInX(node: Node): [number, number] {\n const nodeLeftX = node.x - 4\n const nodeRightX = node.x + node.pixelWidth + 4\n return [nodeLeftX, nodeRightX]\n}\n\n// calculate node widths depending on sequence lengths and chosen calculation method\nfunction generateNodeWidth(state: LayoutState): void {\n switch (state.config.nodeWidthOption) {\n case 'compressed':\n state.nodes.forEach(node => {\n node.width = 1 + Math.log2(Math.max(node.sequenceLength, 1))\n node.pixelWidth = Math.round((node.width - 1) * 8.401)\n })\n break\n case 'small':\n state.nodes.forEach(node => {\n node.width = node.sequenceLength / 100\n node.pixelWidth = Math.max(Math.round((node.width - 1) * 8.401), 0)\n })\n break\n case 'fixed':\n state.nodes.forEach(node => {\n node.width = 10\n node.pixelWidth = Math.round(node.width * 8.401)\n })\n break\n case 'normal': {\n // The label draws a base per character from x - 4, in a monospace font\n // whose character width the caller measures. pixelWidth runs from the\n // first character to the last, so the outline, 9 px wider each side,\n // holds the whole label, and nodePixelCoordinatesInX's half character\n // each side puts base i under letter i.\n const charWidth = state.config.charWidth\n state.nodes.forEach(node => {\n node.width = node.sequenceLength\n node.pixelWidth = Math.round(\n charWidth * Math.max(node.sequenceLength - 1, 0),\n )\n })\n break\n }\n default:\n throw new Error(`${state.config.nodeWidthOption} not implemented`)\n }\n}\n\n// A node's distinct neighbors on one side, kept only as far as mergeNodes\n// needs them: none, exactly one, or several. A neighbor is a signed node index,\n// or TRACK_END where a haplotype starts or stops.\ninterface Neighbors {\n first: Int32Array\n count: Uint8Array\n}\n\nconst TRACK_END = 0\n\nfunction noNeighbors(nodeCount: number): Neighbors {\n return { first: new Int32Array(nodeCount), count: new Uint8Array(nodeCount) }\n}\n\nfunction addNeighbor(\n neighbors: Neighbors,\n index: number,\n neighbor: number,\n): void {\n const count = neighbors.count[index]!\n if (count === 0) {\n neighbors.first[index] = neighbor\n neighbors.count[index] = 1\n } else if (count === 1 && neighbors.first[index] !== neighbor) {\n neighbors.count[index] = 2\n }\n}\n\n// The index of a node's one neighbor on this side, or 0 when it has none,\n// several, or a track end.\nfunction soleNeighbor(neighbors: Neighbors, index: number): number {\n return neighbors.count[index] === 1 ? Math.abs(neighbors.first[index]!) : 0\n}\n\n// remove redundant nodes\n// two nodes A and B can be merged if all tracks leaving A go directly into B\n// and all tracks entering B come directly from A\n// (plus no inversions involved)\nfunction mergeNodes(state: LayoutState): void {\n const pred = noNeighbors(state.nodes.length)\n const succ = noNeighbors(state.nodes.length)\n const signedIndexOf = new Map<string, number>()\n const visit = (nodeName: string): number => {\n let signed = signedIndexOf.get(nodeName)\n if (signed === undefined) {\n const index = state.nodeMap.get(forward(nodeName))!\n signed = isReverse(nodeName) ? -index : index\n signedIndexOf.set(nodeName, signed)\n }\n return signed\n }\n\n const tracksAndReads = state.tracks.concat(state.reads)\n\n // A reverse visit on either side adds both orientations of the neighbor, so\n // no merge happens across an inversion.\n tracksAndReads.forEach(track => {\n const { sequence } = track\n const isHaplotype = track.type === 'haplotype'\n const last = sequence.length - 1\n let previous = TRACK_END\n let current = last >= 0 ? visit(sequence[0]!) : TRACK_END\n for (let i = 0; i <= last; i += 1) {\n const next = i < last ? visit(sequence[i + 1]!) : TRACK_END\n if (current > 0) {\n if (i > 0) {\n addNeighbor(pred, current, previous)\n if (previous < 0) {\n addNeighbor(pred, current, -previous)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, current, TRACK_END)\n }\n if (i < last) {\n addNeighbor(succ, current, next)\n if (next < 0) {\n addNeighbor(succ, current, -next)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, current, TRACK_END)\n }\n } else {\n const index = -current\n if (i > 0) {\n addNeighbor(succ, index, -previous)\n if (previous > 0) {\n addNeighbor(succ, index, previous)\n }\n } else if (isHaplotype) {\n addNeighbor(succ, index, TRACK_END)\n }\n if (i < last) {\n addNeighbor(pred, index, -next)\n if (next > 0) {\n addNeighbor(pred, index, next)\n }\n } else if (isHaplotype) {\n addNeighbor(pred, index, TRACK_END)\n }\n }\n previous = current\n current = next\n }\n })\n\n const absorbed = new Uint8Array(state.nodes.length)\n state.nodes.forEach((_, i) => {\n if (mergeableWithPred(i, pred, succ) !== 0) {\n absorbed[i] = 1\n }\n })\n\n // Merge each run into its first node, noting the node every run member\n // merges into and where the member's bases start and end within it.\n const origin = new Int32Array(state.nodes.length)\n const start = new Float64Array(state.nodes.length)\n const end = new Float64Array(state.nodes.length)\n state.nodes.forEach((node, head) => {\n if (absorbed[head] === 1) {\n return\n }\n origin[head] = head\n end[head] = node.sequenceLength\n for (let donor = head; mergeableWithSucc(donor, pred, succ);) {\n donor = soleNeighbor(succ, donor)\n origin[donor] = head\n start[donor] = node.sequenceLength\n node.sequenceLength += state.nodes[donor]!.sequenceLength\n node.seq += state.nodes[donor]!.seq\n end[donor] = node.sequenceLength\n }\n })\n\n // A read's offsets and mismatch positions count along the strand it visits\n // a node on: from the left end of a forward visit, the right end of a\n // reverse one. A forward visit to an absorbed node folds into the visit\n // before it, a reverse one into the visit after it.\n state.reads.forEach(read => {\n const { sequence } = read\n const entries =\n read.sequenceNew ??\n sequence.map(nodeName => ({ nodeName, mismatches: [] as Mismatch[] }))\n const shift = (nodeName: string): number => {\n const index = Math.abs(visit(nodeName))\n return isReverse(nodeName)\n ? state.nodes[origin[index]!]!.sequenceLength - end[index]!\n : start[index]!\n }\n const last = sequence.length - 1\n read.firstNodeOffset = (read.firstNodeOffset ?? 0) + shift(sequence[0]!)\n read.finalNodeCoverLength =\n (read.finalNodeCoverLength ?? 0) + shift(sequence[last]!)\n\n const mergedSequence: string[] = []\n const mergedEntries: ReadSequenceEntry[] = []\n let carried: Mismatch[] = []\n sequence.forEach((nodeName, i) => {\n const index = Math.abs(visit(nodeName))\n const { mismatches } = entries[i]!\n const by = shift(nodeName)\n mismatches.forEach(mismatch => {\n mismatch.pos += by\n })\n if (absorbed[index] === 1 && !isReverse(nodeName) && i > 0) {\n mergedEntries.at(-1)!.mismatches.push(...mismatches)\n } else if (absorbed[index] === 1 && isReverse(nodeName) && i < last) {\n carried.push(...mismatches)\n } else {\n const name = state.nodes[origin[index]!]!.name\n const merged = isReverse(nodeName) ? reverse(name) : name\n mergedSequence.push(merged)\n mergedEntries.push({\n nodeName: merged,\n mismatches: carried.concat(mismatches),\n })\n carried = []\n }\n })\n read.sequence = mergedSequence\n if (read.sequenceNew !== undefined) {\n read.sequenceNew = mergedEntries\n }\n })\n\n state.tracks.forEach(track => {\n const { sequence } = track\n let kept = 0\n for (const nodeName of sequence) {\n if (absorbed[Math.abs(visit(nodeName))] === 0) {\n sequence[kept] = nodeName\n kept += 1\n }\n }\n sequence.length = kept\n })\n\n let kept = 1\n for (let i = 1; i < state.nodes.length; i += 1) {\n if (absorbed[i] === 0) {\n state.nodes[kept] = state.nodes[i]!\n kept += 1\n }\n }\n state.nodes.length = kept\n}\n\n// The index of the node `index` merges into, or 0 when it merges into none.\nfunction mergeableWithPred(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): number {\n const predecessor = soleNeighbor(pred, index)\n return predecessor !== 0 && soleNeighbor(succ, predecessor) !== 0\n ? predecessor\n : 0\n}\n\nfunction mergeableWithSucc(\n index: number,\n pred: Neighbors,\n succ: Neighbors,\n): boolean {\n const successor = soleNeighbor(succ, index)\n return successor !== 0 && soleNeighbor(pred, successor) !== 0\n}\n", "// SVG path data for the shapes a layout leaves as coordinates: a curve's\n// ribbon and a node's rounded outline. Both are strings so the same geometry\n// draws as an SVG `d` attribute or, through Path2D, on a canvas.\nimport type { Node, TrackCurve, TrackType } from './types.ts'\n\nfunction groupBy<T, K>(items: readonly T[], key: (item: T) => K): Map<K, T[]> {\n const groups = new Map<K, T[]>()\n for (const item of items) {\n const k = key(item)\n const group = groups.get(k)\n if (group === undefined) {\n groups.set(k, [item])\n } else {\n group.push(item)\n }\n }\n return groups\n}\n\nfunction compareCurvesByXYStartValue(a: TrackCurve, b: TrackCurve): number {\n if (a.xStart < b.xStart) {\n return 1\n } else if (a.xStart > b.xStart) {\n return -1\n } else if (a.yStart > b.yStart) {\n return 1\n } else if (a.yStart < b.yStart) {\n return -1\n }\n return 0\n}\n\n// Where a curve leaves and enters: a node, or a gap at an order slot\nfunction curveEnds(curve: TrackCurve): [number, number, number, number] {\n return [\n curve.nodeStart ?? -1,\n curve.nodeEnd ?? -1,\n curve.nodeStart === null ? curve.orderStart : -1,\n curve.nodeEnd === null ? curve.orderEnd : -1,\n ]\n}\n\nfunction compareTuples(a: readonly number[], b: readonly number[]): number {\n for (let i = 0; i < a.length; i += 1) {\n const d = a[i]! - b[i]!\n if (d !== 0) {\n return d\n }\n }\n return 0\n}\n\n// The curves of one track type in draw order, each with its `path` set. Curves\n// between the same pair of nodes, or gaps, form a group whose control points\n// fan out, so a bundle of tracks changing lanes together stays parallel rather\n// than crossing at one x.\nexport function curvePaths(\n curves: readonly TrackCurve[],\n type: TrackType | undefined,\n): TrackCurve[] {\n const groupedCurves = groupBy(\n curves.filter(curve => curve.type === type),\n curve => curveEnds(curve).join(','),\n )\n\n groupedCurves.forEach(curveGroup => {\n // Control point adjustment range: 30% to 70% of the original x values\n let adjustValue = 0.3\n let adjustIncrement = 0.4 / curveGroup.length\n\n // Ignore Beziar Curve skewing when a group is not too big\n if (curveGroup.length <= 5) {\n adjustValue = 0.5\n adjustIncrement = 0\n }\n\n curveGroup.sort(compareCurvesByXYStartValue)\n\n curveGroup.forEach(curve => {\n let xAdjusted: number\n // NextAdjusted is used to try to draw a parallel curve on the way back\n let xNextAdjusted: number\n if (curve.yStart < curve.yEnd) {\n xAdjusted =\n curve.xStart + (curve.xEnd - curve.xStart) * (1 - adjustValue)\n adjustValue += adjustIncrement\n xNextAdjusted =\n curve.xStart + (curve.xEnd - curve.xStart) * (1 - adjustValue)\n } else {\n xAdjusted = curve.xStart + (curve.xEnd - curve.xStart) * adjustValue\n adjustValue += adjustIncrement\n xNextAdjusted = curve.xStart + (curve.xEnd - curve.xStart) * adjustValue\n }\n let d = `M ${curve.xStart} ${curve.yStart}`\n d += ` C ${xAdjusted} ${curve.yStart} ${xAdjusted} ${curve.yEnd} ${curve.xEnd} ${curve.yEnd}`\n d += ` V ${curve.yEnd + curve.width}`\n d += ` C ${xNextAdjusted} ${curve.yEnd + curve.width} ${xNextAdjusted} ${\n curve.yStart + curve.width\n } ${curve.xStart} ${curve.yStart + curve.width}`\n d += ' Z'\n curve.path = d\n })\n })\n\n // One flat list ordered by group, then by the within-group sort\n return [...groupedCurves.values()]\n .sort((a, b) => compareTuples(curveEnds(a[0]!), curveEnds(b[0]!)))\n .flat()\n}\n\n// A node's outline: a rounded box 9 units outside the node's x extent and its\n// content height, the tracks through it inside.\nexport function nodeOutlinePath(node: Node): string {\n // top left arc\n let d = `M ${node.x - 9} ${node.y} Q ${node.x - 9} ${node.y - 9} ${\n node.x\n } ${node.y - 9}`\n let x = node.x\n let y = node.y - 9\n\n // top straight\n if (node.width > 1) {\n x += node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // top right arc\n d += ` Q ${x + 9} ${y} ${x + 9} ${y + 9}`\n x += 9\n y += 9\n\n // right straight\n if (node.contentHeight > 0) {\n y += node.contentHeight\n d += ` L ${x} ${y}`\n }\n\n // bottom right arc\n d += ` Q ${x} ${y + 9} ${x - 9} ${y + 9}`\n x -= 9\n y += 9\n\n // bottom straight\n if (node.width > 1) {\n x -= node.pixelWidth\n d += ` L ${x} ${y}`\n }\n\n // bottom left arc\n d += ` Q ${x - 9} ${y} ${x - 9} ${y - 9}`\n x -= 9\n y -= 9\n\n // left straight\n if (node.contentHeight > 0) {\n y -= node.contentHeight\n d += ` L ${x} ${y}`\n }\n return d\n}\n", "import {\n canonicalStrand,\n stepName,\n tubeMapReads\n} from \"./chunk-TEDQJPMI.js\";\nimport {\n pathCssColor,\n pathGreyCssColor\n} from \"./chunk-7GBL7SJY.js\";\nimport {\n pathOrigin\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/tubeMapLayout.ts\nimport { layoutTubeMap } from \"@jbrowse/tubemap-core\";\nfunction visitStrands(graph) {\n const strands = /* @__PURE__ */ new Map();\n for (const [segment, visits] of graph.pathVisits ?? []) {\n for (const visit of visits) {\n const key = `${visit.path}\t${segment}`;\n const list = strands.get(key);\n if (list) {\n list.push(visit.strand);\n } else {\n strands.set(key, [visit.strand]);\n }\n }\n }\n return strands;\n}\nfunction tubeMapTracks(graph) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const strands = visitStrands(graph);\n const paths = (graph.paths ?? []).map((path, index) => ({ path, index }));\n const reference = paths.findIndex(\n (p) => pathOrigin(p.path.name).name === graph.referencePath\n );\n if (reference > 0) {\n paths.unshift(...paths.splice(reference, 1));\n }\n return paths.flatMap(({ path, index }) => {\n const visitName = pathOrigin(path.name).name;\n const seen = /* @__PURE__ */ new Map();\n const sequence = path.nodeIds.flatMap((id) => {\n const node = nodeById.get(id);\n if (!node) {\n return [];\n }\n const k = seen.get(node.name) ?? 0;\n seen.set(node.name, k + 1);\n const strand = strands.get(`${visitName}\t${node.name}`)?.[k] ?? canonicalStrand(node);\n return [stepName(node, strand)];\n });\n return sequence.length > 0 ? [\n {\n id: index,\n name: path.name,\n sequence,\n sourceTrackID: 0,\n type: \"haplotype\"\n }\n ] : [];\n });\n}\nfunction tubeMapNodes(graph) {\n return graph.nodes.map((n) => ({\n name: n.id,\n seq: \"\",\n sequenceLength: Math.max(1, n.length)\n }));\n}\nfunction hasTubeMapPaths(graph) {\n return (graph.paths?.length ?? 0) > 0;\n}\nvar STACK_PX = 600;\nvar MIN_TUBE_PX = 3;\nvar MAX_TUBE_PX = 15;\nfunction tubeWidth(trackCount) {\n return Math.max(\n MIN_TUBE_PX,\n Math.min(MAX_TUBE_PX, Math.floor(STACK_PX / Math.max(1, trackCount)))\n );\n}\nfunction runTubeMap(graph) {\n const paths = graph.paths ?? [];\n const tracks = tubeMapTracks(graph);\n const reads = graph.reads ? tubeMapReads(graph, graph.reads, paths.length) : [];\n const tubeColor = reads.length > 0 ? pathGreyCssColor : pathCssColor;\n const pathColors = paths.map((_, i) => tubeColor(i, paths.length));\n const layout = layoutTubeMap(tubeMapNodes(graph), tracks, reads, {\n nodeWidthOption: \"compressed\",\n trackWidth: tubeWidth(tracks.length)\n });\n return layout ? { layout, pathColors } : void 0;\n}\nfunction drawnNodes(layout) {\n const nodes = [];\n layout.nodes.forEach((node) => {\n if (node.order >= 0) {\n nodes.push(node);\n }\n });\n return nodes;\n}\nfunction centreline(node, yOffset, x0, x1) {\n const y = node.y + node.contentHeight / 2 - yOffset;\n return [\n { x: x0, y },\n { x: x1, y }\n ];\n}\nfunction extentOf(layout, yOffset) {\n return {\n minY: layout.bounds.minY - yOffset,\n maxY: layout.bounds.maxY - yOffset\n };\n}\nfunction tubeMapLayout(graph) {\n const run = hasTubeMapPaths(graph) ? runTubeMap(graph) : void 0;\n if (!run) {\n return void 0;\n }\n const { layout, pathColors } = run;\n const yOffset = layout.bounds.minY;\n const nodePositions = {};\n for (const node of drawnNodes(layout)) {\n nodePositions[node.name] = centreline(\n node,\n yOffset,\n node.x,\n node.x + node.pixelWidth\n );\n }\n const { minY, maxY } = extentOf(layout, yOffset);\n return {\n nodePositions,\n tubeMap: { layout, yOffset, pathColors },\n extent: {\n minX: layout.bounds.minX,\n maxX: layout.bounds.maxX,\n minY,\n maxY\n }\n };\n}\nfunction tubeMapColumns(graph, layout) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const byOrder = /* @__PURE__ */ new Map();\n for (const node of drawnNodes(layout)) {\n const list = byOrder.get(node.order);\n if (list) {\n list.push(node);\n } else {\n byOrder.set(node.order, [node]);\n }\n }\n const columns = [];\n let end = -Infinity;\n for (const order of [...byOrder.keys()].sort((a, b) => a - b)) {\n const nodes = byOrder.get(order);\n let bp0 = Infinity;\n let bp1 = -Infinity;\n for (const node of nodes) {\n const graphNode = nodeById.get(node.name);\n if (graphNode && isBackbone(graphNode)) {\n bp0 = Math.min(bp0, graphNode.stable.start);\n bp1 = Math.max(bp1, graphNode.stable.start + node.sequenceLength);\n }\n }\n if (bp0 === Infinity) {\n bp0 = bp1 = end;\n }\n if (bp0 < end) {\n bp0 = end;\n bp1 = Math.max(end, bp1);\n }\n end = Math.max(end, bp1);\n columns.push({\n order,\n x0: Math.min(...nodes.map((n) => n.x)),\n x1: Math.max(...nodes.map((n) => n.x + n.pixelWidth)),\n bp0,\n bp1\n });\n }\n const first = columns.find((c) => c.bp0 !== -Infinity);\n for (const column of columns) {\n if (column.bp0 === -Infinity) {\n column.bp0 = column.bp1 = first?.bp0 ?? 0;\n }\n }\n return columns;\n}\nfunction pathsReachBackbone(graph) {\n return graph.nodes.some(isBackbone) && hasTubeMapPaths(graph);\n}\nfunction tubeMapReferenceLayout(graph) {\n const run = pathsReachBackbone(graph) ? runTubeMap(graph) : void 0;\n if (!run) {\n return void 0;\n }\n const { layout, pathColors } = run;\n const columns = tubeMapColumns(graph, layout);\n const byOrder = new Map(columns.map((c) => [c.order, c]));\n const yOffset = layout.bounds.minY;\n const nodePositions = {};\n for (const node of drawnNodes(layout)) {\n const column = byOrder.get(node.order);\n nodePositions[node.name] = centreline(node, yOffset, column.bp0, column.bp1);\n }\n return {\n nodePositions,\n tubeMap: { layout, yOffset, columns, pathColors },\n referenceAxis: true,\n pixelRows: true,\n extent: extentOf(layout, yOffset)\n };\n}\n\nexport {\n visitStrands,\n tubeMapTracks,\n hasTubeMapPaths,\n tubeWidth,\n tubeMapLayout,\n tubeMapReferenceLayout\n};\n", "import {\n placeOffReference\n} from \"./chunk-TZFWUT2C.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\nimport {\n backboneNodes,\n backbonePositions,\n referenceSpan\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/anchoredLayout.ts\nfunction rankRows(graph) {\n const present = /* @__PURE__ */ new Set();\n for (const node of graph.nodes) {\n if (node.stable) {\n present.add(node.stable.rank);\n }\n }\n return new Map([...present].sort((a, b) => a - b).map((r, i) => [r, i]));\n}\nfunction anchoredLayout(graph, region) {\n const backbone = backboneNodes(graph);\n if (backbone.length === 0) {\n return void 0;\n }\n const span = referenceSpan(backbone, region);\n const rows = rankRows(graph);\n const nodePositions = backbonePositions(backbone);\n const alleleDeletions = placeOffReference({\n graph,\n span,\n rowY: (node) => (node.stable ? rows.get(node.stable.rank) ?? rows.size : rows.size) * ROW_HEIGHT_PX,\n positions: nodePositions\n });\n const rowLabels = [...rows].map(([rank, row]) => ({\n label: rank === 0 ? \"Reference (rank 0)\" : `Rank ${rank}`,\n y: row * ROW_HEIGHT_PX\n }));\n return {\n nodePositions,\n rowLabels,\n referenceAxis: true,\n pixelRows: true,\n alleleDeletions\n };\n}\n\nexport {\n anchoredLayout\n};\n", "import {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/orderedLayout.ts\nvar GUTTER = 12;\nvar LANE_PX = ROW_HEIGHT_PX;\nfunction nodeWidth(node) {\n return 10 + 8 * Math.log2(1 + node.length);\n}\nfunction compare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\nfunction compareKeys(a, b) {\n return compare(a.at, b.at) || compare(a.side, b.side) || compare(a.hops, b.hops);\n}\nvar UNREACHED = { at: Infinity, side: 0, hops: 0 };\nfunction referenceOrder(graph) {\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const key = orderKeys(graph);\n return graph.nodes.map((n) => n.id).sort(\n (a, b) => compareKeys(key.get(a) ?? UNREACHED, key.get(b) ?? UNREACHED) || compare(byId.get(a).name, byId.get(b).name) || compare(a, b)\n );\n}\nfunction placeByWalks(graph, backbone) {\n const isNode = new Set(graph.nodes.map((n) => n.id));\n const startOf = new Map(backbone.map((n) => [n.id, n.stable.start]));\n const next = /* @__PURE__ */ new Map();\n const prev = /* @__PURE__ */ new Map();\n backbone.forEach((n, i) => {\n prev.set(n.id, backbone[i - 1]?.id);\n next.set(n.id, backbone[i + 1]?.id);\n });\n let head = backbone[0]?.id;\n const insertAfter = (at, id) => {\n const after = next.get(at);\n next.set(at, id);\n prev.set(id, at);\n next.set(id, after);\n if (after !== void 0) {\n prev.set(after, id);\n }\n };\n const insertBefore = (at, id) => {\n const before = prev.get(at);\n if (before === void 0) {\n head = id;\n prev.set(id, void 0);\n next.set(id, at);\n prev.set(at, id);\n } else {\n insertAfter(before, id);\n }\n };\n for (const path of graph.paths ?? []) {\n let rising = 0;\n let falling = 0;\n let last;\n for (const id of path.nodeIds) {\n const start = startOf.get(id);\n if (start !== void 0) {\n if (last !== void 0 && start !== last) {\n if (start > last) {\n rising++;\n } else {\n falling++;\n }\n }\n last = start;\n }\n }\n const ids = falling > rising ? [...path.nodeIds].reverse() : path.nodeIds;\n let from;\n const leading = /* @__PURE__ */ new Set();\n for (const id of ids) {\n if (next.has(id)) {\n if (from === void 0) {\n for (const lead of leading) {\n insertBefore(id, lead);\n }\n }\n from = id;\n } else if (isNode.has(id)) {\n if (from === void 0) {\n leading.add(id);\n } else {\n insertAfter(from, id);\n from = id;\n }\n }\n }\n }\n const placed = [];\n for (let id = head; id !== void 0; id = next.get(id)) {\n placed.push(id);\n }\n return placed;\n}\nfunction placeBySearch(adjacent, key) {\n const queue = [...key.entries()].sort(([a, ka], [b, kb]) => compareKeys(ka, kb) || compare(a, b)).map(([id]) => id);\n const placed = queue.length;\n for (const id of queue) {\n const from = key.get(id);\n for (const nb of adjacent.get(id) ?? []) {\n if (!key.has(nb)) {\n key.set(nb, { at: from.at, side: 1, hops: from.hops + 1 });\n queue.push(nb);\n }\n }\n }\n const searched = new Set(queue.slice(placed));\n const sided = /* @__PURE__ */ new Set();\n for (const seed of searched) {\n if (sided.has(seed)) {\n continue;\n }\n const { at } = key.get(seed);\n const run = [seed];\n sided.add(seed);\n let farHalf = true;\n for (const id of run) {\n const { hops } = key.get(id);\n let deadEnd = true;\n let touchesLeft = false;\n for (const nb of adjacent.get(id) ?? []) {\n const other = key.get(nb);\n if (other.at === at && searched.has(nb)) {\n deadEnd &&= other.hops <= hops;\n if (!sided.has(nb)) {\n sided.add(nb);\n run.push(nb);\n }\n } else if (other.at !== at) {\n touchesLeft ||= other.at < at;\n farHalf &&= other.at < at;\n }\n }\n farHalf &&= !deadEnd || touchesLeft;\n }\n if (farHalf) {\n for (const id of run) {\n const k = key.get(id);\n key.set(id, { ...k, side: -1, hops: -k.hops });\n }\n }\n }\n}\nfunction orderKeys(graph) {\n const ids = new Set(graph.nodes.map((n) => n.id));\n const adjacent = /* @__PURE__ */ new Map();\n for (const e of graph.edges) {\n if (!ids.has(e.from) || !ids.has(e.to)) {\n continue;\n }\n ;\n (adjacent.get(e.from) ?? adjacent.set(e.from, []).get(e.from)).push(e.to);\n (adjacent.get(e.to) ?? adjacent.set(e.to, []).get(e.to)).push(e.from);\n }\n const backbone = graph.nodes.filter(isBackbone).sort(\n (a, b) => compare(a.stable.start, b.stable.start) || compare(a.name, b.name)\n );\n const key = /* @__PURE__ */ new Map();\n placeByWalks(graph, backbone).forEach((id, rank) => {\n key.set(id, { at: rank, side: 0, hops: 0 });\n });\n placeBySearch(adjacent, key);\n return key;\n}\nfunction layerGraph(graph) {\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const order = referenceOrder(graph);\n const key = new Map(order.map((id, i) => [id, i]));\n const isRef = (id) => isBackbone(byId.get(id));\n const preds = new Map(order.map((id) => [id, []]));\n const succs = new Map(order.map((id) => [id, []]));\n const link = (a, b) => {\n preds.get(b).push(a);\n succs.get(a).push(b);\n };\n for (const e of graph.edges) {\n if (e.from === e.to || !key.has(e.from) || !key.has(e.to)) {\n continue;\n }\n if (key.get(e.from) < key.get(e.to)) {\n link(e.from, e.to);\n } else {\n link(e.to, e.from);\n }\n }\n const backbone = order.filter(isRef);\n for (let i = 1; i < backbone.length; i++) {\n link(backbone[i - 1], backbone[i]);\n }\n const layerOf = /* @__PURE__ */ new Map();\n for (const id of order) {\n let l = 0;\n for (const p of preds.get(id)) {\n l = Math.max(l, layerOf.get(p) + 1);\n }\n layerOf.set(id, l);\n }\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const s = succs.get(id);\n if (isRef(id) || s.length === 0) {\n continue;\n }\n let minSucc = Infinity;\n for (const t of s) {\n minSucc = Math.min(minSucc, layerOf.get(t));\n }\n const lo = layerOf.get(id);\n const hi = Math.max(lo, minSucc - 1);\n layerOf.set(id, Math.floor((lo + hi) / 2));\n }\n const layers = [];\n for (const id of order) {\n ;\n (layers[layerOf.get(id)] ??= []).push(id);\n }\n return { layers, layerOf, preds };\n}\nfunction orderedLayout(graph) {\n if (!graph.nodes.some(isBackbone)) {\n return void 0;\n }\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const isRef = (id) => isBackbone(byId.get(id));\n const { layers, layerOf: layer, preds } = layerGraph(graph);\n const layerWidth = layers.map((ids) => {\n let w = 0;\n for (const id of ids) {\n w = Math.max(w, nodeWidth(byId.get(id)));\n }\n return w;\n });\n const layerX = [];\n let x = 0;\n for (let l = 0; l < layers.length; l++) {\n layerX[l] = x;\n x += layerWidth[l] + GUTTER;\n }\n const y = /* @__PURE__ */ new Map();\n for (const ids of layers) {\n const free = [];\n for (const id of ids) {\n if (isRef(id)) {\n y.set(id, 0);\n continue;\n }\n const placed = preds.get(id).filter((p) => y.has(p));\n let ideal = 0;\n for (const p of placed) {\n ideal += y.get(p) / placed.length;\n }\n free.push({ id, ideal: ideal === 0 ? LANE_PX : ideal });\n }\n free.sort((a, b) => a.ideal - b.ideal);\n const taken = /* @__PURE__ */ new Set([0]);\n for (const { id, ideal } of free) {\n let lane = Math.round(ideal / LANE_PX);\n if (lane === 0) {\n lane = ideal >= 0 ? 1 : -1;\n }\n for (let d = 1; taken.has(lane); d++) {\n if (!taken.has(lane + d)) {\n lane += d;\n } else if (!taken.has(lane - d)) {\n lane -= d;\n }\n }\n taken.add(lane);\n y.set(id, lane * LANE_PX);\n }\n }\n const nodePositions = {};\n for (const n of graph.nodes) {\n const l = layer.get(n.id);\n const w = nodeWidth(n);\n const cx = layerX[l] + layerWidth[l] / 2;\n const ny = y.get(n.id);\n nodePositions[n.id] = [\n { x: cx - w / 2, y: ny },\n { x: cx + w / 2, y: ny }\n ];\n }\n return { nodePositions, referenceAxis: false, pixelRows: true };\n}\n\nexport {\n referenceOrder,\n layerGraph,\n orderedLayout\n};\n", "import {\n pathOrigin\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n panSNContig,\n panSNSample\n} from \"./chunk-BPLIXMH7.js\";\n\n// src/layout/walkRows.ts\nfunction sampleOf(path) {\n return path.sample ?? panSNSample(path.name);\n}\nfunction labelOf(path) {\n return path.haplotype !== void 0 && path.sample !== void 0 ? `${path.sample}#${path.haplotype}` : sampleOf(path);\n}\nfunction stepsOf(pieces, lengthOf) {\n const steps = [];\n let end;\n for (const piece of pieces) {\n if (end !== void 0 && piece.start !== void 0 && piece.start > end) {\n steps.push(piece.start - end);\n }\n steps.push(...piece.nodeIds);\n const bp = piece.nodeIds.reduce(\n (sum, id) => sum + (lengthOf.get(id) ?? 0),\n 0\n );\n end = piece.start === void 0 ? void 0 : piece.start + bp;\n }\n return steps;\n}\nfunction stepSpans(pieces, lengthOf) {\n const spans = [];\n let end;\n for (const piece of pieces) {\n if (piece.start === void 0 || end !== void 0 && piece.start < end) {\n return void 0;\n }\n if (end !== void 0 && piece.start > end) {\n spans.push({ start: end, end: piece.start });\n }\n let pos = piece.start;\n for (const id of piece.nodeIds) {\n const len = lengthOf.get(id) ?? 0;\n spans.push({ start: pos, end: pos + len });\n pos += len;\n }\n end = pos;\n }\n return spans;\n}\nfunction sliceBetween(steps, span, region, flanked = true) {\n if (!region || !flanked) {\n return { ids: steps, complete: true, from: -1, to: -1 };\n }\n let i0 = -1;\n let i1 = -1;\n let bestEnd = -Infinity;\n let bestStart = Infinity;\n steps.forEach((id, i) => {\n const s = typeof id === \"string\" ? span.get(id) : void 0;\n if (s) {\n if (s.end <= region.start && s.end > bestEnd) {\n bestEnd = s.end;\n i0 = i;\n }\n if (s.start >= region.end && s.start < bestStart) {\n bestStart = s.start;\n i1 = i;\n }\n }\n });\n if (i0 < 0 || i1 < 0) {\n return { ids: steps, complete: false, from: -1, to: -1 };\n }\n const ids = steps.slice(Math.min(i0, i1) + 1, Math.max(i0, i1));\n return {\n ids: i0 < i1 ? ids : ids.reverse(),\n complete: true,\n from: i0,\n to: i1\n };\n}\nfunction filterSamples(rows, samples) {\n return samples ? rows.filter((r) => samples.includes(r.sample)).sort(\n (a, b) => samples.indexOf(a.sample) - samples.indexOf(b.sample) || a.label.localeCompare(b.label)\n ) : rows;\n}\nfunction walkRows(graph, region, unit) {\n const paths = graph.paths ?? [];\n const isReference = (p) => pathOrigin(p.name).name === graph.referencePath;\n const referencePieces = paths.some(isReference) ? paths.filter(isReference).sort((a, b) => (a.start ?? 0) - (b.start ?? 0)) : paths.slice(0, 1);\n const first = referencePieces[0];\n const others = paths.filter((p) => !referencePieces.includes(p));\n if (!first || others.length === 0) {\n return void 0;\n }\n const walks = /* @__PURE__ */ new Map();\n for (const path of others) {\n walks.set(path.name, [...walks.get(path.name) ?? [], path]);\n }\n const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));\n const referenceStart = first.start ?? 0;\n const cut = region && region.end > region.start ? region : void 0;\n const span = /* @__PURE__ */ new Map();\n for (const piece of referencePieces) {\n let pos = piece.start ?? 0;\n for (const id of piece.nodeIds) {\n const len = lengthOf.get(id) ?? 0;\n if (!span.has(id)) {\n span.set(id, { start: pos, end: pos + len });\n }\n pos += len;\n }\n }\n const flanked = cut === void 0 || [...span.values()].some((s) => s.end <= cut.start) && [...span.values()].some((s) => s.start >= cut.end);\n const rowOf = (pieces) => {\n const path = pieces[0];\n const ordered = [...pieces].sort((a, b) => (a.start ?? 0) - (b.start ?? 0));\n const { ids, complete, from, to } = sliceBetween(\n stepsOf(ordered, lengthOf),\n span,\n cut,\n flanked\n );\n const spans = stepSpans(ordered, lengthOf);\n const contig = path.contig ?? panSNContig(pathOrigin(path.name).name);\n 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 };\n const runs = [];\n let bp = 0;\n let offReferenceBp = 0;\n let gapBp = 0;\n let step = 0;\n for (const id of ids) {\n if (typeof id === \"number\") {\n runs.push({ start: bp, bp: id, onReference: false, gap: true });\n bp += id;\n gapBp += id;\n step = 0;\n continue;\n }\n const len = lengthOf.get(id) ?? 0;\n const s = span.get(id);\n const last = runs.at(-1);\n const at = last?.referenceStart;\n const forward = s && at !== void 0 && step >= 0 && at + last.bp === s.start;\n const backward = s && at !== void 0 && step <= 0 && s.end === at;\n if (!s && last && !last.onReference && !last.gap) {\n last.bp += len;\n } else if (forward || backward) {\n last.bp += len;\n if (!forward) {\n last.referenceStart = s.start;\n last.reversed = true;\n }\n step = forward ? 1 : -1;\n } else {\n runs.push({\n start: bp,\n bp: len,\n onReference: s !== void 0,\n referenceStart: s?.start\n });\n step = 0;\n }\n bp += len;\n if (!s) {\n offReferenceBp += len;\n }\n }\n return {\n name: path.name,\n label: labelOf(path),\n sample: sampleOf(path),\n haplotype: path.haplotype,\n bp,\n offReferenceBp,\n gapBp,\n complete,\n runs,\n axis\n };\n };\n const origin = cut ? cut.start : referenceStart;\n return {\n origin,\n unit,\n reference: rowOf(referencePieces),\n rows: [...walks.values()].map(rowOf).sort(\n (a, b) => Number(b.complete) - Number(a.complete) || b.bp - a.bp || a.label.localeCompare(b.label)\n )\n };\n}\n\nexport {\n filterSamples,\n walkRows\n};\n", "import {\n walkRows\n} from \"./chunk-SZNZ2T6D.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\nimport {\n backboneNodes,\n backbonePositions,\n overlapsWindow\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/walkRowLayout.ts\nvar READOUT_ROOM = 1.3;\nfunction walkRowsExtent(walks, pitch = {\n rowPx: ROW_HEIGHT_PX,\n readouts: true\n}) {\n let longest = walks.reference.bp;\n for (const row of walks.rows) {\n longest = Math.max(longest, row.bp);\n }\n return {\n maxX: walks.origin + longest * (pitch.readouts ? READOUT_ROOM : 1),\n maxY: walks.rows.length * pitch.rowPx\n };\n}\nfunction walkRowLabels(rows, layout, pitch) {\n if (!rows) {\n return layout?.rowLabels ?? [];\n }\n if (pitch && !pitch.labelled) {\n return [];\n }\n return [rows.reference, ...rows.rows].map((row, i) => ({\n label: row.label,\n y: i * (pitch?.rowPx ?? ROW_HEIGHT_PX)\n }));\n}\nfunction walkRowLayout(graph, region) {\n const backbone = backboneNodes(graph);\n const walks = walkRows(graph, region);\n if (backbone.length === 0 || !walks) {\n return void 0;\n }\n const overWindow = region ? backbone.filter((n) => overlapsWindow(n, region)) : backbone;\n const nodePositions = backbonePositions(\n overWindow.length > 0 ? overWindow : backbone\n );\n const rowLabels = [\n { label: walks.reference.label, y: 0 },\n ...walks.rows.map((row, i) => ({\n label: row.label,\n y: (i + 1) * ROW_HEIGHT_PX\n }))\n ];\n return {\n nodePositions,\n rowLabels,\n referenceAxis: true,\n pixelRows: true,\n extent: walkRowsExtent(walks)\n };\n}\n\nexport {\n walkRowsExtent,\n walkRowLabels,\n walkRowLayout\n};\n", "import {\n sampleRowLayout\n} from \"./chunk-LOEA5IHZ.js\";\nimport {\n hasTubeMapPaths,\n tubeMapLayout,\n tubeMapReferenceLayout\n} from \"./chunk-W2I4DOL4.js\";\nimport {\n anchoredLayout\n} from \"./chunk-L3O7AWLI.js\";\nimport {\n orderedLayout\n} from \"./chunk-HNQPEMYE.js\";\nimport {\n walkRowLayout\n} from \"./chunk-MP7LXLWV.js\";\nimport {\n isBackbone,\n isOffReference\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layoutModes.ts\nvar FORCE_LAYOUT_LABEL = \"Force-directed layout\";\nvar hasBackbone = (graph) => graph.nodes.some(isBackbone);\nvar hasWalks = (graph) => hasBackbone(graph) && (graph.paths?.length ?? 0) > 1;\nvar hasTubeMapBackbone = (graph) => hasBackbone(graph) && hasTubeMapPaths(graph);\nvar hasAlleles = (graph) => hasBackbone(graph) && graph.nodes.some(isOffReference);\nvar LAYOUT_MODES = [\n {\n value: \"auto\",\n label: \"Anchored\",\n description: \"x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.\",\n run: anchoredLayout,\n cutMargins: true,\n wholeWalks: false,\n available: hasBackbone,\n drawsLocally: hasBackbone,\n drawsNodes: true\n },\n {\n value: \"samplerows\",\n label: \"Sample rows\",\n description: \"x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.\",\n run: sampleRowLayout,\n cutMargins: true,\n wholeWalks: false,\n available: hasAlleles,\n drawsLocally: hasAlleles,\n drawsNodes: true\n },\n {\n value: \"walkrows\",\n label: \"Walk rows\",\n description: \"x is each walk's own bp: one bar per haplotype, blue on the reference's path and purple off it, so a repeat expansion reads as bar length, and each bar boxes its haplotype's own genes where the session has them. Needs W or P lines.\",\n run: walkRowLayout,\n cutMargins: false,\n wholeWalks: true,\n available: hasWalks,\n drawsLocally: hasWalks,\n drawsNodes: false\n },\n {\n value: \"ordered\",\n label: \"Ordered\",\n description: \"x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.\",\n run: orderedLayout,\n cutMargins: false,\n wholeWalks: false,\n available: hasBackbone,\n drawsLocally: hasBackbone,\n drawsNodes: true\n },\n {\n value: \"tubemap\",\n label: \"Tube map\",\n description: \"sequenceTubeMap: every path a coloured tube through boxed nodes, columns in node order and node widths log-scaled. Needs P or W lines.\",\n run: tubeMapLayout,\n cutMargins: false,\n wholeWalks: false,\n available: hasTubeMapPaths,\n drawsLocally: hasTubeMapPaths,\n drawsNodes: false\n },\n {\n value: \"tubemapref\",\n label: \"Tube map on reference\",\n description: \"The tube map with each column at the reference bp it covers, so the tubes line up with the tracks around them. Needs P or W lines and a reference path.\",\n run: tubeMapReferenceLayout,\n cutMargins: true,\n wholeWalks: false,\n available: hasTubeMapBackbone,\n drawsLocally: hasTubeMapBackbone,\n drawsNodes: false\n },\n {\n value: \"force\",\n label: FORCE_LAYOUT_LABEL,\n description: \"OGDF FMMM, via the external Bandage engine.\",\n run: () => void 0,\n cutMargins: false,\n wholeWalks: false,\n available: () => true,\n drawsLocally: () => false,\n drawsNodes: true\n }\n];\nvar LAYOUT_MODE_VALUES = LAYOUT_MODES.map((m) => m.value);\nfunction modeUsesLayoutEngine(value, graph) {\n return !layoutModeByValue(value).drawsLocally(graph);\n}\nfunction layoutModeByValue(value) {\n return LAYOUT_MODES.find((m) => m.value === value) ?? LAYOUT_MODES[0];\n}\n\nexport {\n FORCE_LAYOUT_LABEL,\n LAYOUT_MODES,\n LAYOUT_MODE_VALUES,\n modeUsesLayoutEngine,\n layoutModeByValue\n};\n", "// src/facetGrid.ts\nvar FACET_GAP_PX = 8;\nvar FACET_TITLE_PX = 34;\nvar FACET_PAD_PX = 12;\nvar MIN_FACET_PANEL_PX = 60;\nfunction facetGrid({\n count,\n bounds,\n pixelRows,\n width,\n room,\n columns\n}) {\n function tile(across) {\n const rows = Math.ceil(count / across);\n const panelWidth = Math.floor(\n (width - (across - 1) * FACET_GAP_PX) / across\n );\n const panelRoom = (room - rows * FACET_TITLE_PX - (rows - 1) * FACET_GAP_PX) / rows;\n const fitX = (panelWidth - 2 * FACET_PAD_PX) / bounds.w;\n const fitY = bounds.h > 0 ? (panelRoom - 2 * FACET_PAD_PX) / bounds.h : Infinity;\n const scale = pixelRows ? fitX : Math.min(fitX, fitY);\n const drawn = pixelRows ? bounds.h : bounds.h * scale;\n const height = Math.floor(\n Math.max(\n MIN_FACET_PANEL_PX,\n Math.min(drawn + 2 * FACET_PAD_PX, panelRoom)\n )\n );\n return {\n columns: across,\n width: panelWidth,\n height,\n scale,\n total: rows * (height + FACET_TITLE_PX) + (rows - 1) * FACET_GAP_PX\n };\n }\n if (columns !== void 0) {\n return tile(Math.max(1, Math.min(count, Math.round(columns))));\n }\n let best = tile(1);\n for (let across = 2; across <= count; across++) {\n const grid = tile(across);\n if (grid.scale > best.scale) {\n best = grid;\n }\n }\n return best;\n}\nvar FACET_FIELDS = [\n { value: \"\", label: \"None\", description: \"Every lifted walk in one drawing\" },\n {\n value: \"walk\",\n label: \"A panel per walk\",\n description: \"One panel per lifted walk, side by side\"\n },\n {\n value: \"sample\",\n label: \"A row per sample\",\n description: \"A row per sample, a column per haplotype\"\n }\n];\nfunction facetSettingOf(facet) {\n const raw = typeof facet === \"string\" ? { field: facet } : facet ?? {};\n const field = raw.field === \"walk\" || raw.field === \"sample\" ? raw.field : \"\";\n return {\n field,\n domain: [...raw.domain ?? []],\n ...raw.columns === void 0 ? {} : { columns: raw.columns }\n };\n}\nfunction domainFirst(names, domain) {\n const rank = new Map(domain.map((name, i) => [name, i]));\n const listed = (name) => rank.get(name) ?? domain.length;\n return names.map((name, i) => ({ name, i })).sort((a, b) => listed(a.name) - listed(b.name) || a.i - b.i).map(({ name }) => name);\n}\nfunction facetCells(names, by, domain = []) {\n const wrapOrder = domainFirst(names, domain);\n const wrap = {\n columns: void 0,\n count: names.length,\n cells: names.map((name) => wrapOrder.indexOf(name))\n };\n if (by === \"walk\") {\n return wrap;\n }\n const places = names.map((name) => {\n const [sample, haplotype, contig] = name.split(\"#\");\n const n = Number(haplotype);\n return contig !== void 0 && Number.isInteger(n) && n >= 0 ? { sample, column: Math.max(0, n - 1) } : void 0;\n });\n const rows = domainFirst(\n [...new Set(places.flatMap((p) => p ? [p.sample] : []))],\n domain\n );\n const columns = Math.max(1, ...places.map((p) => p ? p.column + 1 : 1));\n const cells = places.map(\n (p) => p ? rows.indexOf(p.sample) * columns + p.column : -1\n );\n return cells.includes(-1) || new Set(cells).size < cells.length ? wrap : { columns, count: rows.length * columns, cells };\n}\n\nexport {\n FACET_GAP_PX,\n FACET_TITLE_PX,\n FACET_PAD_PX,\n facetGrid,\n FACET_FIELDS,\n facetSettingOf,\n facetCells\n};\n", "import { groupKeyComparator } from '@jbrowse/core/util/groupKeys'\n\n// Walk rows stacked into one section per value of a sample table's column,\n// as jbrowse-plugin-tandem-repeat's \"Group by\u2026\" stacks its alleles. Placement\n// here, not in bandage-core's walkRowsTree, which puts row i at i * rowPx.\n\n// One row of a samples TSV: the sample's name and a value per column\nexport type SampleRow = { name: string } & Record<string, string>\n\nexport interface WalkRowGroupBy {\n field: string\n domain?: string[]\n}\n\nexport interface WalkRowSection {\n // '' for the rows with no value\n key: string\n title: string\n // index of the section's first row among the reference row and the rows\n first: number\n count: number\n}\n\nexport const SECTION_HEADER_PX = 16\n\n// A samples TSV as core's samplesTsv reads one: a header row, the sample's\n// name in the first column, the first row of a repeated name kept. Hosts\n// re-export that module only from v5.0.0-beta.11, so it is read here.\nexport function parseSamplesTsv(text: string): SampleRow[] {\n const [head = '', ...lines] = text.split(/\\r\\n|\\r|\\n/)\n const columns = head.split('\\t').slice(1)\n const rows = new Map<string, SampleRow>()\n for (const line of lines) {\n if (!line) {\n continue\n }\n const [name = '', ...values] = line.split('\\t')\n if (name && !rows.has(name)) {\n rows.set(name, {\n ...Object.fromEntries(columns.map((c, i) => [c, values[i] ?? ''])),\n name,\n })\n }\n }\n return [...rows.values()]\n}\n\nexport function metadataColumns(rows: SampleRow[] | undefined) {\n const columns = new Set<string>()\n for (const row of rows ?? []) {\n for (const key of Object.keys(row)) {\n if (key !== 'name') {\n columns.add(key)\n }\n }\n }\n return [...columns]\n}\n\n// The setting as a snapshot may hold it: a bare field name, or the object\nexport function groupByOf(value: unknown): WalkRowGroupBy | undefined {\n if (typeof value === 'string') {\n return value ? { field: value } : undefined\n }\n const { field, domain } = (value ?? {}) as Record<string, unknown>\n if (typeof field !== 'string' || !field) {\n return undefined\n }\n return Array.isArray(domain)\n ? { field, domain: domain.filter(d => typeof d === 'string') }\n : { field }\n}\n\nfunction haplotypes(rows: { label: string }[]) {\n const n = new Set(rows.map(r => r.label)).size\n return `${n} haplotype${n === 1 ? '' : 's'}`\n}\n\n// The rows reordered section by section, each keeping the order it came in.\n// A row's value is its table row's, looked up by haplotype (`HG00097#1`)\n// and then by sample (`HG00097`); rows with none stack last.\nexport function groupWalkRows<R extends { sample: string; label: string }>(\n rows: R[],\n table: SampleRow[],\n { field, domain }: WalkRowGroupBy,\n) {\n const valueOf = new Map(table.map(row => [row.name, row[field] ?? '']))\n const groups = new Map<string, R[]>()\n for (const row of rows) {\n const key = valueOf.get(row.label) || valueOf.get(row.sample) || ''\n const group = groups.get(key)\n if (group) {\n group.push(row)\n } else {\n groups.set(key, [row])\n }\n }\n let first = 1\n const sections: WalkRowSection[] = [...groups.keys()]\n .sort(groupKeyComparator(domain))\n .map(key => {\n const members = groups.get(key)!\n const section = {\n key,\n title: `${key || `${field}: none`} \u00B7 ${haplotypes(members)}`,\n first,\n count: members.length,\n }\n first += members.length\n return section\n })\n return {\n rows: sections.flatMap(s => groups.get(s.key)!),\n sections,\n }\n}\n\n// Where rows and section headers sit, in px down from the reference row's\n// centre, at one row pitch shared by every section: a header strip above\n// each section's first row pushes every row after it down\nexport function sectionPlacement(sections: WalkRowSection[], rowPx: number) {\n const sectionOf = (i: number) => {\n let k = -1\n while (k + 1 < sections.length && sections[k + 1]!.first <= i) {\n k++\n }\n return k\n }\n const rowY = (i: number) => i * rowPx + (sectionOf(i) + 1) * SECTION_HEADER_PX\n return {\n rowY,\n headers: sections.map((s, k) => ({\n ...s,\n top: (s.first - 0.5) * rowPx + k * SECTION_HEADER_PX,\n })),\n headersPx: sections.length * SECTION_HEADER_PX,\n // the row whose centre is nearest y\n rowAt(y: number, rows: number) {\n let best = 0\n for (let k = -1; k < sections.length; k++) {\n const lo = k < 0 ? 0 : sections[k]!.first\n const hi =\n k < 0\n ? Math.min(rows, sections[0]?.first ?? rows)\n : lo + sections[k]!.count\n const shift = (k + 1) * SECTION_HEADER_PX\n const i = Math.min(\n hi - 1,\n Math.max(lo, Math.round((y - shift) / rowPx)),\n )\n if (Math.abs(rowY(i) - y) < Math.abs(rowY(best) - y)) {\n best = i\n }\n }\n return best\n },\n }\n}\n", "import {\n SATURATED_PATH_COUNT\n} from \"./chunk-MFKORG3F.js\";\n\n// src/bubbles/classifyBubble.ts\nvar REPEAT_GROWTH = 10;\nfunction coveringRepeat(b, repeats) {\n const span = b.end - b.start;\n const growth = b.longestAlleleLength - b.shortestAlleleLength;\n return repeats.find(\n (r) => growth <= REPEAT_GROWTH * (r.end - r.start) && (span === 0 ? r.start <= b.start && b.start <= r.end : Math.min(b.end, r.end) - Math.max(b.start, r.start) >= span / 2)\n );\n}\nvar SUPERBUBBLE_SEGMENTS = 40;\nfunction formatBp(bp) {\n if (bp >= 1e4) {\n return `${(bp / 1e3).toFixed(0)} kb`;\n }\n if (bp >= 1e3) {\n return `${(bp / 1e3).toFixed(1)} kb`;\n }\n return `${bp} bp`;\n}\nfunction formatBpRange(shortest, longest) {\n const low = formatBp(shortest);\n const high = formatBp(longest);\n const unit = high.slice(high.indexOf(\" \"));\n return low.endsWith(unit) ? `${low.slice(0, -unit.length)}\\u2013${high}` : `${low}\\u2013${high}`;\n}\nfunction routes(count) {\n if (count >= SATURATED_PATH_COUNT) {\n return \"\\u22652.1B routes\";\n }\n if (count >= 1e5) {\n return `${(count / 1e3).toFixed(0)}k routes`;\n }\n return `${count} routes`;\n}\nfunction classifyBubble(b, repeats = []) {\n const c = classifyShape(b, repeats);\n return b.partial ? { ...c, label: `${c.label}, partial` } : c;\n}\nfunction classifyShape(b, repeats) {\n const refSpan = b.end - b.start;\n const {\n shortestAlleleLength: shortest,\n longestAlleleLength: longest,\n pathCount,\n segmentCount,\n inversion\n } = b;\n const range = formatBpRange(shortest, longest);\n if (segmentCount >= SUPERBUBBLE_SEGMENTS) {\n return {\n kind: \"superbubble\",\n label: `${range} superbubble, ${segmentCount} segments, ${routes(pathCount)}${inversion ? \", inv\" : \"\"}`\n };\n }\n if (inversion) {\n return { kind: \"inversion\", label: `${formatBp(longest)} inv` };\n }\n const repeat = longest !== shortest ? coveringRepeat(b, repeats) : void 0;\n if (repeat) {\n const name = repeat.name ? ` (${repeat.name})` : \"\";\n return {\n kind: \"repeat\",\n label: `${range} repeat array${name}, ${routes(pathCount)}`\n };\n }\n const alleles = pathCount > 2 ? `, ${pathCount} alleles` : \"\";\n if (shortest === longest && shortest === refSpan) {\n return refSpan <= 1 ? { kind: \"snp\", label: \"SNP\" } : { kind: \"substitution\", label: `${formatBp(refSpan)} sub` };\n }\n if (refSpan === 0 || shortest === refSpan) {\n return {\n kind: \"insertion\",\n label: `\\u2264${formatBp(longest - refSpan)} ins${alleles}`\n };\n }\n if (longest === refSpan) {\n return {\n kind: \"deletion\",\n label: `${formatBp(refSpan - shortest)} del${alleles}`\n };\n }\n return {\n kind: \"complex\",\n label: `${formatBp(refSpan)} ref \\u2192 ${range}, ${pathCount} alleles`\n };\n}\nvar BUBBLE_KIND_COLORS = {\n snp: \"#5b6b7a\",\n substitution: \"#5b6b7a\",\n insertion: \"#2f8fd6\",\n deletion: \"#c94040\",\n inversion: \"#e07b00\",\n repeat: \"#8e3fbf\",\n superbubble: \"#8e3fbf\",\n complex: \"#8e3fbf\"\n};\nvar BUBBLE_KIND_NAMES = {\n snp: \"SNP\",\n substitution: \"substitution\",\n insertion: \"insertion\",\n deletion: \"deletion\",\n inversion: \"inversion\",\n repeat: \"repeat array\",\n superbubble: \"superbubble\",\n complex: \"site\"\n};\nfunction bubbleSegmentIds(b) {\n return b.segments.split(\",\").filter(Boolean);\n}\n\nexport {\n formatBp,\n classifyBubble,\n BUBBLE_KIND_COLORS,\n BUBBLE_KIND_NAMES,\n bubbleSegmentIds\n};\n", "import {\n RAMP_GRADIENT_CSS,\n RAMP_GRADIENT_STOPS,\n rampHueCss,\n rampStops\n} from \"./chunk-6ZNQJ5ZD.js\";\nimport {\n REFERENCE_RAMP_ALT_CSS\n} from \"./chunk-HBEKUQO4.js\";\nimport {\n LABEL_CHAR_PX\n} from \"./chunk-AB35TJST.js\";\nimport {\n el\n} from \"./chunk-NNODIW4U.js\";\nimport {\n ROW_HEIGHT_PX\n} from \"./chunk-CPMHA4W5.js\";\n\n// src/layout/walkRowDraw.ts\nvar ON_REFERENCE = \"#2f8fd6\";\nvar OFF_REFERENCE = \"#8e3fbf\";\nvar OUTSIDE_CUT = \"#bdbdbd\";\nvar GENE_INK = \"#1c1c22\";\nvar BAR_PX = 12;\nvar GAP_PX = 4;\nvar LABELLED_ROW_PX = 12;\nvar MIN_TILED_BAR_PX = 6;\nvar MIN_TILE_PX = 3;\nfunction kb(bp) {\n return `${(bp / 1e3).toFixed(bp < 1e4 ? 1 : 0)} kb`;\n}\nfunction units(bp, unit) {\n return unit ? ` \\u2248 ${Math.round(bp / unit)} units` : \"\";\n}\nfunction walkRowReadout(row, reference, unit, call) {\n const { bp, gapBp, complete } = row;\n if (!reference) {\n return `${kb(bp)}${units(bp, unit)}`;\n }\n const delta = bp - reference.bp;\n const against = delta === 0 ? \"\" : ` (${delta > 0 ? \"+\" : \"\\u2212\"}${kb(Math.abs(delta))})`;\n const outside = gapBp > 0 ? ` \\xB7 ${kb(gapBp)} outside the cut` : \"\";\n const called = call ? ` \\xB7 called ${kb(call.bp)}${call.spanningReads === 0 ? \" \\xB7 no spanning read\" : \"\"}` : \"\";\n return `${kb(bp)}${units(bp, unit)}${against}${outside}${complete ? \"\" : \" \\xB7 partial walk\"}${called}`;\n}\nfunction readoutPlacement(text, endX, width) {\n const x = endX + 6;\n const fits = x + text.length * LABEL_CHAR_PX < width;\n return fits ? { x, anchor: \"start\", halo: false } : { x: endX - 6, anchor: \"end\", halo: true };\n}\nfunction unitTicks(bp, unit, pxPerBp) {\n if (unit * pxPerBp < MIN_TILE_PX) {\n return [];\n }\n const ticks = [];\n for (let k = unit; k < bp; k += unit) {\n ticks.push(k);\n }\n return ticks;\n}\nfunction runPaint(run, ramp) {\n if (run.gap) {\n return { fill: OUTSIDE_CUT };\n }\n if (!ramp) {\n return { fill: run.onReference ? ON_REFERENCE : OFF_REFERENCE };\n }\n if (run.referenceStart === void 0) {\n return { fill: REFERENCE_RAMP_ALT_CSS };\n }\n const stops = rampStops({ ...run, start: run.referenceStart }, ramp);\n return stops.length === 1 ? { fill: rampHueCss(stops[0]) } : { stops: stops.map(rampHueCss) };\n}\nfunction alongRow(axis, start, end) {\n return axis.reversed ? { start: axis.start - end, end: axis.start - start } : { start: start - axis.start, end: end - axis.start };\n}\nfunction rowSpan(axis, bp) {\n return axis.reversed ? { start: axis.start - bp, end: axis.start } : { start: axis.start, end: axis.start + bp };\n}\nfunction genesOnRow(row, genes) {\n const contig = row.axis?.contig;\n return genes.filter(\n (g) => g.refName === contig || g.refName.endsWith(`#${contig}`)\n );\n}\nfunction placeRowGenes(rows, byRow) {\n const placed = /* @__PURE__ */ new Map();\n for (const row of rows) {\n const genes = byRow.get(row.name);\n if (!row.axis || !genes) {\n continue;\n }\n const axis = row.axis;\n const clip = ({ start, end }) => ({\n start: Math.max(0, start),\n end: Math.min(row.bp, end)\n });\n placed.set(\n row.name,\n genes.map((g) => ({\n name: g.name,\n ...clip(alongRow(axis, g.start, g.end)),\n exons: g.exons.map((e) => clip(alongRow(axis, e.start, e.end))).filter((e) => e.end > e.start)\n })).filter((g) => g.end > g.start).sort((a, b) => a.start - b.start)\n );\n }\n return placed;\n}\nvar GENE_FONT_PX = 9;\nvar GENE_CHAR_PX = 5.2;\nvar MIN_LETTERED_BAR_PX = 8;\nvar genePad = (rowPx, barPx) => Math.min(2, (rowPx - barPx) / 2 - 1);\nfunction boxesGenes(rowPx, barPx) {\n return genePad(rowPx, barPx) >= 1;\n}\nfunction rowGeneBoxes(genes, X, y, { rowPx = ROW_HEIGHT_PX, barPx = BAR_PX } = {}) {\n if (!boxesGenes(rowPx, barPx)) {\n return [];\n }\n const pad = genePad(rowPx, barPx);\n const boxes = genes.map((g) => {\n const x = X(g.start);\n return {\n g,\n x,\n w: Math.max(2, X(g.end) - x)\n };\n });\n const taken = [];\n const named = new Set(\n (barPx >= MIN_LETTERED_BAR_PX ? [...boxes] : []).sort((a, b) => a.w - b.w).filter(({ g, x, w }) => {\n const half = g.name.length * GENE_CHAR_PX / 2;\n const at = [x + w / 2 - half, x + w / 2 + half];\n if (2 * half > w + 6 || taken.some(([a, b]) => at[0] < b + 2 && at[1] > a - 2)) {\n return false;\n }\n taken.push(at);\n return true;\n })\n );\n return boxes.map((box) => ({\n name: box.g.name,\n x: box.x,\n y: y - barPx / 2 - pad,\n w: box.w,\n h: barPx + 2 * pad,\n exons: box.g.exons.map((e) => ({\n x: X(e.start),\n w: Math.max(1, X(e.end) - X(e.start))\n })),\n label: named.has(box) ? { x: box.x + box.w / 2, y: y + 3, size: GENE_FONT_PX } : void 0\n }));\n}\nvar rowsText = (n) => `${n} row${n === 1 ? \"\" : \"s\"}`;\nfunction walkRowsKey(bars, o = {}) {\n const entries = [\n {\n swatch: o.ramp ? { kind: \"bar\", fill: o.rampCss ?? RAMP_GRADIENT_CSS, ramp: true } : { kind: \"bar\", fill: ON_REFERENCE },\n label: `on ${bars.reference.label}'s path`\n },\n {\n swatch: {\n kind: \"bar\",\n fill: o.ramp ? REFERENCE_RAMP_ALT_CSS : OFF_REFERENCE\n },\n label: `off ${bars.reference.label}'s path`\n }\n ];\n if ([bars.reference, ...bars.rows].some((row) => row.gapBp > 0)) {\n entries.push({\n swatch: { kind: \"gap\", fill: OUTSIDE_CUT },\n label: \"walked outside the cut\"\n });\n }\n if (o.genes?.crowded) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"genes left out: too many rows to box them in\",\n note: true\n });\n } else if (o.genes) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: \"genes, each row's own annotation\"\n });\n if (o.genes.untracked) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no gene track for ${rowsText(o.genes.untracked)}`,\n note: true\n });\n }\n if (o.genes.unplaced) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `no contig coordinates for ${rowsText(o.genes.unplaced)}`,\n note: true\n });\n }\n if (o.genes.unread) {\n entries.push({\n swatch: { kind: \"gene\" },\n label: `genes not read for the last ${rowsText(o.genes.unread)}`,\n note: true\n });\n }\n }\n return entries;\n}\nvar CALL_TICK = \"#111\";\nvar UNBACKED_TICK = \"#9e9e9e\";\nvar DISAGREES = \"#c62828\";\nfunction callTickInk(call) {\n return call.agrees === false ? DISAGREES : call.spanningReads === 0 ? UNBACKED_TICK : CALL_TICK;\n}\nfunction walkRowsKeyTree(entries, x, y, idPrefix = \"walk-key\") {\n let at = 0;\n const parts = entries.flatMap((e, i) => {\n const rampId = `${idPrefix}-ramp-${i}`;\n const ramp = !e.note && e.swatch.kind === \"bar\" && e.swatch.ramp ? el(\n \"linearGradient\",\n { id: rampId },\n ...RAMP_GRADIENT_STOPS.map(\n (s) => el(\"stop\", { offset: s.offset, \"stop-color\": s.color })\n )\n ) : void 0;\n const swatch = e.note ? void 0 : e.swatch.kind === \"gene\" ? el(\"rect\", {\n x: at,\n y: 5,\n width: 18,\n height: 8,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }) : el(\"rect\", {\n x: at,\n y: e.swatch.kind === \"gap\" ? 7 : 5,\n width: 18,\n height: e.swatch.kind === \"gap\" ? GAP_PX : 8,\n rx: 2,\n fill: ramp ? `url(#${rampId})` : e.swatch.fill\n });\n const text = el(\n \"text\",\n {\n x: e.note ? at : at + 23,\n y: 13,\n \"font-style\": e.note ? \"italic\" : void 0,\n fill: e.note ? \"#666\" : void 0\n },\n e.label\n );\n at += (e.note ? 0 : 23) + e.label.length * LABEL_CHAR_PX + 16;\n return [ramp, swatch, text].filter((p) => p !== void 0);\n });\n return {\n width: at,\n tree: el(\n \"g\",\n {\n transform: `translate(${x} ${y})`,\n \"font-family\": \"Helvetica, Arial, sans-serif\",\n \"font-size\": 11\n },\n ...parts\n )\n };\n}\nfunction rowPitch(count, room, minRowPx = 0) {\n const fit = room / Math.max(1, count);\n const rowPx = Math.max(\n minRowPx,\n Math.min(ROW_HEIGHT_PX, fit >= 1 ? Math.floor(fit) : fit)\n );\n return {\n rowPx,\n barPx: rowPx <= 3 ? rowPx : Math.max(3, Math.round(rowPx * 0.6)),\n labelled: rowPx >= LABELLED_ROW_PX,\n readouts: rowPx >= LABELLED_ROW_PX\n };\n}\nfunction coalesceRuns(runs, pxPerBp) {\n const minBp = 1 / pxPerBp;\n const out = [];\n let bucket = [];\n const flush = () => {\n if (bucket.length === 0) {\n return;\n }\n if (bucket.length === 1) {\n out.push(bucket[0]);\n } else {\n let on = 0;\n let off = 0;\n for (const r of bucket) {\n if (r.onReference) {\n on += r.bp;\n } else {\n off += r.bp;\n }\n }\n const onReference = on >= off;\n const lead = bucket.find((r) => r.onReference === onReference);\n out.push({\n start: bucket[0].start,\n bp: on + off,\n onReference,\n referenceStart: onReference ? lead.referenceStart : void 0,\n ...lead.reversed ? { reversed: true } : {}\n });\n }\n bucket = [];\n };\n let held = 0;\n for (const run of runs) {\n if (run.gap || run.bp >= minBp) {\n flush();\n held = 0;\n out.push(run);\n continue;\n }\n bucket.push(run);\n held += run.bp;\n if (held >= minBp) {\n flush();\n held = 0;\n }\n }\n flush();\n return out;\n}\nfunction geneTree(box, y, barPx) {\n return el(\n \"g\",\n { class: \"row-gene\", \"data-testid\": \"graph-walk-gene\" },\n el(\"title\", {}, box.name),\n ...box.exons.map(\n (e) => el(\"rect\", {\n x: e.x,\n y: y - barPx / 2,\n width: e.w,\n height: barPx,\n fill: GENE_INK,\n opacity: 0.35\n })\n ),\n el(\"rect\", {\n x: box.x,\n y: box.y,\n width: box.w,\n height: box.h,\n fill: \"none\",\n stroke: GENE_INK,\n \"stroke-width\": 1.5\n }),\n box.label && el(\n \"text\",\n {\n x: box.label.x,\n y: box.label.y,\n \"font-family\": \"sans-serif\",\n \"font-size\": box.label.size,\n \"font-weight\": 600,\n \"text-anchor\": \"middle\",\n fill: GENE_INK,\n stroke: \"white\",\n \"stroke-width\": 2.5,\n \"paint-order\": \"stroke\"\n },\n box.name\n )\n );\n}\nfunction walkRowsTree(bars, frame, o = {}) {\n const X = (bp) => bp * frame.scaleX + frame.translateX;\n const rowPx = frame.rowPx ?? ROW_HEIGHT_PX;\n const barPx = frame.barPx ?? BAR_PX;\n const overhang = Math.min(3, Math.max(0, (rowPx - barPx) / 2));\n const Y = (row) => row * rowPx * frame.scaleY + frame.translateY;\n const { origin, unit, reference, rows } = bars;\n const along = (offset) => X(origin + offset);\n const prefix = o.idPrefix ?? \"walkrow\";\n const rowTree = (row, i) => {\n const y = Y(i);\n if (y < -barPx || y > frame.height + barPx) {\n return void 0;\n }\n const runs = coalesceRuns(row.runs, frame.scaleX).flatMap((run) => {\n const paint = runPaint(run, o.ramp);\n const h = run.gap ? Math.min(GAP_PX, barPx) : barPx;\n const id = `${prefix}-${i}-${run.start}`;\n const rect = el(\"rect\", {\n x: along(run.start),\n y: y - h / 2,\n width: Math.max(1, run.bp * frame.scaleX),\n height: h,\n fill: \"stops\" in paint ? `url(#${id})` : paint.fill\n });\n return \"stops\" in paint ? [\n el(\n \"linearGradient\",\n { id },\n ...paint.stops.map(\n (color, k) => el(\"stop\", {\n offset: k / (paint.stops.length - 1),\n \"stop-color\": color\n })\n )\n ),\n rect\n ] : [rect];\n });\n const ticks = unit && barPx >= MIN_TILED_BAR_PX ? unitTicks(row.bp, unit, frame.scaleX).map(\n (k) => el(\"line\", {\n x1: along(k),\n x2: along(k),\n y1: y - barPx / 2,\n y2: y + barPx / 2,\n stroke: \"white\",\n \"stroke-width\": 1\n })\n ) : [];\n const { call } = row;\n const text = walkRowReadout(\n row,\n i === 0 ? void 0 : reference,\n unit,\n call\n );\n const at = readoutPlacement(text, along(row.bp), frame.width);\n const readouts = frame.readouts ?? true;\n return el(\n \"g\",\n {\n \"data-testid\": i === 0 ? \"graph-walk-reference\" : \"graph-walk-row\"\n },\n ...runs,\n ...ticks,\n ...rowGeneBoxes(o.rowGenes?.get(row.name) ?? [], along, y, {\n rowPx,\n barPx\n }).map((box) => geneTree(box, y, barPx)),\n call && el(\"rect\", {\n \"data-testid\": \"graph-walk-call\",\n x: along(call.bp) - 1,\n y: y - barPx / 2 - overhang,\n width: 2,\n height: barPx + 2 * overhang,\n fill: callTickInk(call)\n }),\n readouts && el(\n \"text\",\n {\n x: at.x,\n y: y + 4,\n \"font-family\": \"sans-serif\",\n \"font-size\": 11,\n fill: call?.agrees === false ? DISAGREES : \"#333\",\n stroke: at.halo ? \"white\" : void 0,\n \"stroke-width\": at.halo ? 3 : void 0,\n \"paint-order\": \"stroke\",\n \"text-anchor\": at.anchor\n },\n text\n )\n );\n };\n return el(\"g\", {}, ...[reference, ...rows].map(rowTree));\n}\n\nexport {\n ON_REFERENCE,\n OFF_REFERENCE,\n OUTSIDE_CUT,\n GENE_INK,\n BAR_PX,\n GAP_PX,\n LABELLED_ROW_PX,\n kb,\n walkRowReadout,\n readoutPlacement,\n unitTicks,\n runPaint,\n alongRow,\n rowSpan,\n genesOnRow,\n placeRowGenes,\n boxesGenes,\n rowGeneBoxes,\n walkRowsKey,\n CALL_TICK,\n UNBACKED_TICK,\n DISAGREES,\n callTickInk,\n walkRowsKeyTree,\n rowPitch,\n coalesceRuns,\n walkRowsTree\n};\n", "import {\n alongRow,\n boxesGenes,\n rowPitch\n} from \"./chunk-V3MD3IZB.js\";\nimport {\n LABEL_CHAR_PX\n} from \"./chunk-AB35TJST.js\";\nimport {\n el\n} from \"./chunk-NNODIW4U.js\";\nimport {\n pathOrigin\n} from \"./chunk-ST2IBUAN.js\";\n\n// src/layout/walkStrip.ts\nfunction walkStripApplies(o) {\n return o.walkStrip && o.mode.drawsNodes && !o.drawsPicture && !o.popped && !o.host && o.walks > 1;\n}\nfunction cutsWholeWalks(mode, o) {\n return mode.wholeWalks || o.walkStrip && !o.host;\n}\nvar PAD_PX = 6;\nvar WALK_STRIP_CEILING_PX = 260;\nvar LABEL_FONT_PX = 11;\nvar MIN_ROW_PX = 3;\nvar READOUT_ROOM = 1.3;\nvar MARK_INK = \"#111\";\nvar TICK_PX = 3;\nfunction stripMarks(graph, rows, node) {\n const visits = graph.pathVisits?.get(node.name) ?? [];\n const marks = [];\n for (const row of rows) {\n const axis = row.axis;\n if (!axis) {\n continue;\n }\n const path = pathOrigin(row.name).name;\n for (const v of visits) {\n if (v.path !== path) {\n continue;\n }\n const { start, end } = alongRow(axis, v.start, v.start + node.length);\n if (end > 0 && start < row.bp) {\n marks.push({ row: row.name, start, bp: end - start });\n }\n }\n }\n return marks;\n}\nvar spanCache = /* @__PURE__ */ new WeakMap();\nfunction spansOf(graph, name) {\n let byName = spanCache.get(graph);\n if (!byName) {\n byName = /* @__PURE__ */ new Map();\n spanCache.set(graph, byName);\n }\n if (byName.has(name)) {\n return byName.get(name);\n }\n const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));\n const pieces = (graph.paths ?? []).filter((p) => p.name === name);\n let spans;\n if (pieces.every((p) => p.start !== void 0)) {\n spans = { ids: [], starts: [], ends: [] };\n for (const piece of [...pieces].sort((a, b) => a.start - b.start)) {\n let pos = piece.start;\n for (const id of piece.nodeIds) {\n const len = lengthOf.get(id) ?? 0;\n spans.ids.push(id);\n spans.starts.push(pos);\n spans.ends.push(pos + len);\n pos += len;\n }\n }\n }\n byName.set(name, spans);\n return spans;\n}\nfunction segmentAt(graph, row, offset, pxPerBp) {\n const axis = row.axis;\n const spans = axis && spansOf(graph, row.name);\n if (!axis || !spans || offset < 0 || offset > row.bp) {\n return void 0;\n }\n const at = axis.reversed ? axis.start - offset : axis.start + offset;\n const tol = 0.5 / pxPerBp;\n const bar = axis.reversed ? { start: axis.start - row.bp, end: axis.start } : { start: axis.start, end: axis.start + row.bp };\n const from = Math.max(at - tol, bar.start);\n const to = Math.min(at + tol, bar.end);\n let lo = 0;\n let hi = spans.starts.length;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n if (spans.ends[mid] <= from) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n let best;\n let bestLen = -1;\n let bestHolds = false;\n for (let i = lo; i < spans.starts.length && spans.starts[i] < to; i++) {\n const len = spans.ends[i] - spans.starts[i];\n const holds = spans.starts[i] <= at && at < spans.ends[i];\n if (len > bestLen || len === bestLen && holds && !bestHolds) {\n bestLen = len;\n best = spans.ids[i];\n bestHolds = holds;\n }\n }\n return best;\n}\nfunction walkStripFrame(bars, o) {\n const maxHeight = o.maxHeight ?? WALK_STRIP_CEILING_PX;\n const labelPx = o.labelPx ?? Math.max(...[bars.reference, ...bars.rows].map((r) => r.label.length)) * LABEL_CHAR_PX + 16;\n const count = bars.rows.length + 1;\n const { rowPx, barPx, labelled, readouts } = rowPitch(\n count,\n maxHeight - 2 * PAD_PX,\n MIN_ROW_PX\n );\n const longest = Math.max(bars.reference.bp, ...bars.rows.map((r) => r.bp), 1);\n const left = labelled ? labelPx : PAD_PX;\n const usable = Math.max(1, o.width - left - PAD_PX);\n const scaleX = usable / (longest * (readouts ? READOUT_ROOM : 1));\n return {\n scaleX,\n scaleY: 1,\n translateX: left - bars.origin * scaleX,\n translateY: PAD_PX + rowPx / 2,\n width: o.width,\n height: count * rowPx + 2 * PAD_PX,\n rowPx,\n barPx,\n readouts,\n labelled,\n boxesGenes: boxesGenes(rowPx, barPx)\n };\n}\nfunction stripRowAt(bars, frame, x, y) {\n const i = Math.round((y - frame.translateY) / frame.rowPx);\n const row = [bars.reference, ...bars.rows][i];\n const offset = (x - frame.translateX) / frame.scaleX - bars.origin;\n return row && i >= 0 && offset >= 0 && offset <= row.bp ? { index: i, row, offset } : void 0;\n}\nfunction walkMarksTree(bars, frame, marks) {\n const index = new Map(\n [bars.reference, ...bars.rows].map((row, i) => [row.name, i])\n );\n const X = (offset) => (bars.origin + offset) * frame.scaleX + frame.translateX;\n return el(\n \"g\",\n { \"data-testid\": \"graph-walk-marks\" },\n ...marks.flatMap((m) => {\n const i = index.get(m.row);\n if (i === void 0) {\n return [];\n }\n const y = i * frame.rowPx + frame.translateY;\n const x = X(m.start);\n const w = Math.max(2, m.bp * frame.scaleX);\n const tick = (top) => el(\"rect\", { x, y: top, width: w, height: TICK_PX, fill: MARK_INK });\n return [\n tick(y - frame.barPx / 2 - TICK_PX - 1),\n tick(y + frame.barPx / 2 + 1)\n ];\n })\n );\n}\nfunction walkStripLabelsTree(bars, frame, bold = /* @__PURE__ */ new Set()) {\n return el(\n \"g\",\n { \"font-family\": \"sans-serif\", \"font-size\": LABEL_FONT_PX, fill: \"#333\" },\n ...(frame.labelled ? [bars.reference, ...bars.rows] : []).map(\n (row, i) => el(\n \"text\",\n {\n x: 6,\n y: i * frame.rowPx + frame.translateY + 4,\n \"font-weight\": bold.has(row.name) ? 600 : void 0\n },\n row.label\n )\n )\n );\n}\nfunction stripGeneGaps(frame, rowGenes, gaps) {\n if (!rowGenes?.size) {\n return void 0;\n }\n return frame.boxesGenes ? gaps : { untracked: 0, unread: 0, ...gaps, crowded: true };\n}\n\nexport {\n walkStripApplies,\n cutsWholeWalks,\n WALK_STRIP_CEILING_PX,\n stripMarks,\n segmentAt,\n walkStripFrame,\n stripRowAt,\n walkMarksTree,\n walkStripLabelsTree,\n stripGeneGaps\n};\n", "// src/renderer/canvas.ts\nvar MAX_DPR = 2;\nvar MAX_CANVAS_DIM_PX = 8192;\nfunction getDpr() {\n return typeof devicePixelRatio === \"undefined\" ? 1 : Math.min(devicePixelRatio, MAX_DPR);\n}\nvar warnedCanvasClamp = false;\nfunction backingPx(cssSize, dpr, axis) {\n const value = Math.round(cssSize * dpr);\n if (value > MAX_CANVAS_DIM_PX) {\n if (!warnedCanvasClamp) {\n warnedCanvasClamp = true;\n console.warn(\n `Canvas ${axis} ${value}px exceeds the safe limit ${MAX_CANVAS_DIM_PX}px and was clamped`\n );\n }\n return MAX_CANVAS_DIM_PX;\n }\n return value;\n}\nfunction syncCanvasSize(canvas, width, height) {\n const dpr = getDpr();\n const pw = backingPx(width, dpr, \"width\");\n const ph = backingPx(height, dpr, \"height\");\n if (canvas.width !== pw || canvas.height !== ph) {\n canvas.width = pw;\n canvas.height = ph;\n }\n const cssWidth = `${width}px`;\n const cssHeight = `${height}px`;\n if (canvas.style.width !== cssWidth) {\n canvas.style.width = cssWidth;\n }\n if (canvas.style.height !== cssHeight) {\n canvas.style.height = cssHeight;\n }\n}\n\nexport {\n MAX_DPR,\n MAX_CANVAS_DIM_PX,\n getDpr,\n syncCanvasSize\n};\n", "import {\n syncCanvasSize\n} from \"./chunk-4BYTEJGW.js\";\nimport {\n abgrToCssRgba,\n brightenAbgr,\n normalizedRgbToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\n\n// src/renderer/Canvas2DRenderer.ts\nvar Canvas2DRenderer = class {\n constructor(canvas) {\n this.transform = null;\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n this.highlightFactor = 1;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Canvas 2D context not available\");\n }\n this.canvas = canvas;\n this.ctx = ctx;\n }\n setErrorHandler(_handler) {\n }\n releaseOffscreenTargets() {\n }\n // Not a local `width * devicePixelRatio`: syncCanvasSize clamps the backing\n // store at MAX_CANVAS_DIM_PX, reads the ratio through `getDpr()` so this\n // agrees with the transform the model builds, and writes the css size\n // independently of the backing size.\n resize(width, height) {\n syncCanvasSize(this.canvas, width, height);\n }\n uploadGeometry(batch) {\n this.batch = batch;\n this.highlightedEdge = null;\n }\n setNodeHighlights(factors) {\n this.nodeHighlights = factors;\n }\n setEdgeHighlight(edgeIndex, factor) {\n this.highlightedEdge = edgeIndex;\n this.highlightFactor = factor;\n }\n updateTransform(transform) {\n this.transform = transform;\n }\n render(clearColor) {\n const t = this.transform;\n if (!t) {\n return;\n }\n const ctx = this.ctx;\n const { width, height } = ctx.canvas;\n if (clearColor[3] < 1) {\n ctx.clearRect(0, 0, width, height);\n }\n ctx.fillStyle = normalizedRgbToCssRgba(\n [clearColor[0], clearColor[1], clearColor[2]],\n clearColor[3]\n );\n ctx.fillRect(0, 0, width, height);\n const batch = this.batch;\n if (!batch) {\n return;\n }\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n this.renderEdges(batch);\n this.renderNodes(batch);\n this.renderArrows(batch);\n }\n renderEdges(batch) {\n const t = this.transform;\n const ctx = this.ctx;\n const hl = this.highlightedEdge === null ? void 0 : batch.edgeCurveRuns.get(this.highlightedEdge);\n for (const { color, items } of groupByPaint(batch.edgeCurves, (e, i) => ({\n color: inRun(hl, i) ? brightenAbgr(e.color, this.highlightFactor) : e.color,\n weight: e.thickness,\n last: inRun(hl, i)\n }))) {\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const e of items) {\n const first = e.curves[0];\n ctx.moveTo(\n first.x0 * t.scaleX + t.translateX,\n first.y0 * t.scaleY + t.translateY\n );\n for (const c of e.curves) {\n ctx.bezierCurveTo(\n c.cx0 * t.scaleX + t.translateX,\n c.cy0 * t.scaleY + t.translateY,\n c.cx1 * t.scaleX + t.translateX,\n c.cy1 * t.scaleY + t.translateY,\n c.x1 * t.scaleX + t.translateX,\n c.y1 * t.scaleY + t.translateY\n );\n }\n }\n ctx.stroke();\n }\n }\n renderNodes(batch) {\n const t = this.transform;\n const ctx = this.ctx;\n const lifted = /* @__PURE__ */ new Map();\n for (const [nodeId, factor] of this.nodeHighlights) {\n const run = batch.nodeStrokeRuns.get(nodeId);\n if (run) {\n for (let i = run.start; i < run.start + run.count; i++) {\n lifted.set(i, factor);\n }\n }\n }\n for (const { color, items } of groupByPaint(batch.nodeStrokes, (s, i) => {\n const factor = lifted.get(i);\n return {\n color: factor === void 0 ? s.color : brightenAbgr(s.color, factor),\n weight: s.thickness,\n last: factor !== void 0\n };\n })) {\n ctx.strokeStyle = abgrToCssRgba(color);\n ctx.lineWidth = items[0].thickness * 2 * t.dpr;\n ctx.beginPath();\n for (const s of items) {\n const p0 = s.points[0];\n ctx.moveTo(\n p0.x * t.scaleX + t.translateX,\n p0.y * t.scaleY + t.translateY\n );\n for (let i = 1, l = s.points.length; i < l; i++) {\n const p = s.points[i];\n ctx.lineTo(\n p.x * t.scaleX + t.translateX,\n p.y * t.scaleY + t.translateY\n );\n }\n }\n ctx.stroke();\n }\n }\n renderArrows(batch) {\n const t = this.transform;\n const ctx = this.ctx;\n const hl = this.highlightedEdge === null ? void 0 : batch.arrowRuns.get(this.highlightedEdge);\n for (const { color, items } of groupByPaint(batch.arrows, (a, i) => ({\n color: inRun(hl, i) ? brightenAbgr(a.color, this.highlightFactor) : a.color,\n weight: 0,\n last: inRun(hl, i)\n }))) {\n ctx.fillStyle = abgrToCssRgba(color);\n ctx.beginPath();\n for (const a of items) {\n const [tip, left, notch, right] = arrowheadOutline(a, t);\n ctx.moveTo(tip.x, tip.y);\n ctx.lineTo(left.x, left.y);\n ctx.lineTo(notch.x, notch.y);\n ctx.lineTo(right.x, right.y);\n ctx.closePath();\n }\n ctx.fill();\n }\n }\n dispose() {\n this.batch = null;\n this.nodeHighlights = /* @__PURE__ */ new Map();\n this.highlightedEdge = null;\n }\n};\nvar ARROW_NOTCH = 0.25;\nfunction arrowheadOutline(a, t) {\n const ux = Math.cos(a.angle);\n const uy = Math.sin(a.angle);\n const tipX = a.x * t.scaleX + t.translateX;\n const tipY = a.y * t.scaleY + t.translateY;\n const length = a.length * t.dpr;\n const halfWidth = a.halfWidth * t.dpr;\n const backX = tipX - ux * length;\n const backY = tipY - uy * length;\n const notchBack = length * (1 - ARROW_NOTCH);\n return [\n { x: tipX, y: tipY },\n { x: backX - uy * halfWidth, y: backY + ux * halfWidth },\n { x: tipX - ux * notchBack, y: tipY - uy * notchBack },\n { x: backX + uy * halfWidth, y: backY - ux * halfWidth }\n ];\n}\nfunction inRun(run, i) {\n return run !== void 0 && i >= run.start && i < run.start + run.count;\n}\nfunction groupByPaint(items, paintOf) {\n const groups = /* @__PURE__ */ new Map();\n const deferred = /* @__PURE__ */ new Map();\n for (let i = 0, l = items.length; i < l; i++) {\n const item = items[i];\n const { color, weight, last } = paintOf(item, i);\n const into = last ? deferred : groups;\n const key = `${color}:${weight}`;\n const group = into.get(key);\n if (group) {\n group.items.push(item);\n } else {\n into.set(key, { color, items: [item] });\n }\n }\n return [...groups.values(), ...deferred.values()];\n}\n\nexport {\n Canvas2DRenderer,\n arrowheadOutline\n};\n", "import {\n formatBp,\n groupDigits\n} from \"./chunk-3ZZSX5HN.js\";\n\n// src/walkKey.ts\nfunction rangeText(contig, start, end) {\n const s = Math.round(start);\n const e = Math.round(end);\n return `${contig ? `${contig}:` : \"\"}${groupDigits(s)}-${groupDigits(e)} (${formatBp(e - s)})`;\n}\nfunction walkKey(walk, reference) {\n const { field } = walk.encoding;\n const own = walk.range ? rangeText(walk.range.contig, walk.range.start, walk.range.end) : void 0;\n const scale = field === \"progress\" ? own : field === \"reference\" && reference ? rangeText(reference.name, reference.start, reference.end) : void 0;\n const spanned = walk.range ? walk.range.end - walk.range.start : walk.bp;\n const outside = spanned - walk.bp;\n return {\n delta: walk.referenceBp === void 0 || spanned === walk.referenceBp ? \"\" : ` ${spanned > walk.referenceBp ? \"+\" : \"\\u2212\"}${formatBp(Math.abs(spanned - walk.referenceBp))}`,\n outside: outside > 0 ? `, ${formatBp(outside)} outside the cut` : \"\",\n reversed: walk.reversedBp > 0 ? `, ${formatBp(walk.reversedBp)} reversed` : \"\",\n shades: field !== \"walk\",\n scale,\n hover: scale === own ? void 0 : own\n };\n}\nfunction walkPosition(walk, nodeId, length) {\n const progress = walk.progress.get(nodeId);\n const range = walk.range;\n if (progress === void 0 || !range) {\n return void 0;\n }\n const start = Math.round(\n range.start + progress * (range.end - range.start) - length / 2\n );\n return `${range.contig}:${groupDigits(start)}-${groupDigits(start + length)}`;\n}\n\nexport {\n rangeText,\n walkKey,\n walkPosition\n};\n", "import {\n formatBp\n} from \"./chunk-3ZZSX5HN.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/tubeMap/axis.ts\nfunction referenceBoxes(graph, layout) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const byRefName = /* @__PURE__ */ new Map();\n layout.nodes.forEach((node) => {\n const graphNode = nodeById.get(node.name);\n if (node.order >= 0 && graphNode && isBackbone(graphNode)) {\n const { refName, start } = graphNode.stable;\n const boxes = byRefName.get(refName) ?? byRefName.set(refName, []).get(refName);\n boxes.push({\n bp0: start,\n bp1: start + node.sequenceLength,\n x0: node.x,\n x1: node.x + node.pixelWidth\n });\n }\n });\n for (const boxes of byRefName.values()) {\n boxes.sort((a, b) => a.bp0 - b.bp0);\n }\n return byRefName;\n}\nfunction tubeX(boxes, bp, isEnd = false) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n const bp1 = boxes[mid].bp1;\n if (isEnd ? bp1 < bp : bp1 <= bp) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n const box = boxes[lo];\n if (bp <= box.bp0) {\n return box.x0;\n }\n const span = box.bp1 - box.bp0;\n return span > 0 ? box.x0 + (Math.min(bp, box.bp1) - box.bp0) / span * (box.x1 - box.x0) : box.x0;\n}\nfunction tubeSpan(boxes, start, end) {\n const a = tubeX(boxes, start);\n const b = tubeX(boxes, end, true);\n return { x0: Math.min(a, b), x1: Math.max(a, b) };\n}\nfunction rulerBoxes(byRefName) {\n let best;\n for (const boxes of byRefName.values()) {\n if (!best || boxes.length > best.length) {\n best = boxes;\n }\n }\n return best;\n}\nvar TICK_PX = 5;\nvar LABEL_GAP_PX = 10;\nvar TARGET_TICK_PX = 110;\nvar MIN_BRACKET_PX = 3;\nfunction rulerInk(darkMode) {\n return darkMode ? \"#b0b0b8\" : \"#55555c\";\n}\nfunction niceStep(raw) {\n const pow = 10 ** Math.floor(Math.log10(raw));\n const m = raw / pow;\n return (m <= 1 ? 1 : m <= 2 ? 2 : m <= 5 ? 5 : 10) * pow;\n}\nfunction placeLabels(candidates) {\n const placed = [];\n for (const a of candidates) {\n if (placed.every(\n (b) => Math.abs(a.at - b.at) >= (a.width + b.width) / 2 + LABEL_GAP_PX\n )) {\n placed.push(a);\n }\n }\n return placed.map(({ text, at }) => ({ text, at }));\n}\nfunction scaleMarks(boxes, x, width, measure) {\n const first = boxes[0];\n const last = boxes.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const from = x(first.x0);\n const to = x(last.x1);\n const bpSpan = last.bp1 - first.bp0;\n if (to <= from || bpSpan <= 0) {\n return void 0;\n }\n const step = niceStep(bpSpan / (to - from) * TARGET_TICK_PX);\n const ticks = [];\n const positions = [];\n for (let bp = Math.ceil(first.bp0 / step) * step; bp <= last.bp1; bp += step) {\n const sx = Math.round(x(tubeX(boxes, bp))) + 0.5;\n if (sx >= 0 && sx <= width) {\n ticks.push(sx);\n const text = bp.toLocaleString(\"en-US\");\n positions.push({ text, at: sx, width: measure(text) });\n }\n }\n return {\n spans: [{ x0: from, x1: to }],\n ticks,\n labels: placeLabels(positions)\n };\n}\nfunction boxMarks(boxes, x, width, measure) {\n const shown = boxes.map((box) => ({ box, s0: x(box.x0), s1: x(box.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width);\n const first = shown[0];\n const last = shown.at(-1);\n if (!first || !last) {\n return void 0;\n }\n const label = (text, at) => ({\n text,\n at,\n width: measure(text)\n });\n const position = (bp, at) => label(bp.toLocaleString(\"en-US\"), at);\n const spans = [];\n const ticks = [];\n const lengths = [];\n const boundaries = [];\n for (const { box, s0, s1 } of shown) {\n spans.push({ x0: s0, x1: s1 });\n ticks.push(Math.round(s0) + 0.5);\n if (s1 - s0 >= MIN_BRACKET_PX) {\n ticks.push(Math.round(s1) + 0.5);\n }\n const length = label(formatBp(box.bp1 - box.bp0), (s0 + s1) / 2);\n if (length.width <= s1 - s0) {\n lengths.push(length);\n }\n if (box !== first.box) {\n boundaries.push(position(box.bp0, s0));\n }\n }\n const ends = [\n position(first.box.bp0, first.s0),\n position(last.box.bp1, last.s1)\n ];\n return {\n spans,\n ticks,\n labels: placeLabels([...ends, ...lengths, ...boundaries])\n };\n}\nfunction rulerMarks(boxes, x, width, measure, referenceAxis = false) {\n return (referenceAxis ? scaleMarks : boxMarks)(boxes, x, width, measure);\n}\nfunction drawTubeMapRuler(ctx, boxes, frame, top, referenceAxis = false) {\n const { x, width, darkMode } = frame;\n ctx.font = \"10px sans-serif\";\n const marks = rulerMarks(\n boxes,\n x,\n width,\n (text) => ctx.measureText(text).width,\n referenceAxis\n );\n if (!marks) {\n return;\n }\n const ink = rulerInk(darkMode);\n const y = top + 0.5;\n ctx.strokeStyle = ink;\n ctx.fillStyle = ink;\n ctx.lineWidth = 1;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.beginPath();\n for (const { x0, x1 } of marks.spans) {\n ctx.moveTo(Math.max(0, x0), y);\n ctx.lineTo(Math.min(width, x1), y);\n }\n for (const sx of marks.ticks) {\n ctx.moveTo(sx, top);\n ctx.lineTo(sx, top + TICK_PX);\n }\n ctx.stroke();\n for (const { text, at } of marks.labels) {\n ctx.fillText(text, at, top + TICK_PX + 2);\n }\n}\n\nexport {\n referenceBoxes,\n tubeX,\n tubeSpan,\n rulerBoxes,\n rulerInk,\n rulerMarks,\n drawTubeMapRuler\n};\n", "import {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/tubeMap/connectors.ts\nfunction referenceNodes(graph, layout) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const out = [];\n layout.nodes.forEach((node) => {\n const graphNode = nodeById.get(node.name);\n if (node.order >= 0 && graphNode && isBackbone(graphNode)) {\n out.push({\n node: node.name,\n bp0: graphNode.stable.start,\n bp1: graphNode.stable.start + node.sequenceLength,\n x0: node.x,\n x1: node.x + node.pixelWidth\n });\n }\n });\n return out;\n}\nfunction tubeMapConnectors(nodes, bpToScreen, tubeToScreen, width) {\n const out = [];\n for (const n of nodes) {\n const bottom0 = tubeToScreen(n.x0);\n const bottom1 = tubeToScreen(n.x1);\n if (bottom1 >= 0 && bottom0 <= width) {\n out.push({\n node: n.node,\n top0: bpToScreen(n.bp0),\n top1: bpToScreen(n.bp1),\n bottom0,\n bottom1\n });\n }\n }\n return out;\n}\nvar HIT_SLOP_PX = 3;\nfunction connectorAt(connectors, zoneBottom, sx, sy) {\n if (zoneBottom <= 0 || sy < 0 || sy > zoneBottom) {\n return void 0;\n }\n const t = sy / zoneBottom;\n let hit;\n let best = HIT_SLOP_PX;\n for (const c of connectors) {\n const a = c.top0 + (c.bottom0 - c.top0) * t;\n const b = c.top1 + (c.bottom1 - c.top1) * t;\n const dist = Math.max(0, Math.min(a, b) - sx, sx - Math.max(a, b));\n if (dist < best) {\n best = dist;\n hit = c.node;\n }\n }\n return hit;\n}\nfunction band(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n ctx.lineTo(c.bottom0, bottom);\n ctx.closePath();\n}\nfunction sides(ctx, c, bottom) {\n ctx.moveTo(c.top0, 0);\n ctx.lineTo(c.bottom0, bottom);\n ctx.moveTo(c.top1, 0);\n ctx.lineTo(c.bottom1, bottom);\n}\nfunction drawTubeMapConnectors(ctx, connectors, bottom, {\n highlightNode,\n darkMode\n}) {\n if (bottom <= 0 || connectors.length === 0) {\n return;\n }\n const ink = darkMode ? \"255,255,255\" : \"0,0,0\";\n ctx.beginPath();\n for (const c of connectors) {\n band(ctx, c, bottom);\n }\n ctx.fillStyle = `rgba(${ink},0.07)`;\n ctx.fill();\n ctx.beginPath();\n for (const c of connectors) {\n sides(ctx, c, bottom);\n }\n ctx.strokeStyle = `rgba(${ink},0.35)`;\n ctx.lineWidth = 0.5;\n ctx.stroke();\n const lit = connectors.find((c) => c.node === highlightNode);\n if (lit) {\n ctx.beginPath();\n band(ctx, lit, bottom);\n ctx.fillStyle = \"rgba(255,192,203,0.5)\";\n ctx.fill();\n ctx.beginPath();\n sides(ctx, lit, bottom);\n ctx.strokeStyle = \"#ff0000\";\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n}\n\nexport {\n referenceNodes,\n tubeMapConnectors,\n connectorAt,\n drawTubeMapConnectors\n};\n", "// src/tubeMap/mismatches.ts\nimport { forward, getXCoordinateOfBaseWithinNode } from \"@jbrowse/tubemap-core\";\nfunction readMismatches(read, layout) {\n const marks = [];\n const entries = read.sequenceNew ?? [];\n entries.forEach((entry, i) => {\n const nodeIndex = layout.nodeMap.get(forward(entry.nodeName));\n const node = nodeIndex === void 0 ? void 0 : layout.nodes[nodeIndex];\n let pathIndex = i;\n while (pathIndex < read.path.length && read.path[pathIndex].node !== nodeIndex) {\n pathIndex += 1;\n }\n const y = read.path[pathIndex]?.y;\n if (node && y !== void 0) {\n const base = { readId: read.id, y, height: read.width, nodeY: node.y };\n const at = (pos) => getXCoordinateOfBaseWithinNode(node, pos);\n for (const mm of entry.mismatches) {\n const x0 = at(mm.pos);\n if (x0 !== null) {\n if (mm.type === \"insertion\") {\n const softClip = i === 0 && mm.pos === read.firstNodeOffset || i === entries.length - 1 && mm.pos === read.finalNodeCoverLength;\n marks.push({\n ...base,\n kind: \"insertion\",\n x: x0,\n seq: mm.seq,\n softClip\n });\n } else if (mm.type === \"deletion\" && mm.length !== void 0) {\n const x1 = at(mm.pos + mm.length);\n if (x1 !== null) {\n marks.push({ ...base, kind: \"deletion\", x0, x1 });\n }\n } else if (mm.type === \"substitution\" && mm.seq !== void 0) {\n const x1 = at(mm.pos + mm.seq.length);\n if (x1 !== null) {\n marks.push({ ...base, kind: \"substitution\", x0, x1, seq: mm.seq });\n }\n }\n }\n }\n }\n });\n return marks;\n}\nfunction tubeMapMismatches(layout) {\n return layout.reads.flatMap((read) => readMismatches(read, layout));\n}\n\nexport {\n tubeMapMismatches\n};\n", "import {\n tubeMapMismatches\n} from \"./chunk-733L2TS6.js\";\nimport {\n readColor\n} from \"./chunk-TEDQJPMI.js\";\n\n// src/tubeMap/draw.ts\nimport { curvePaths, nodeOutlinePath } from \"@jbrowse/tubemap-core\";\nfunction parsePath(d) {\n const tokens = d.trim().split(/[\\s,]+/);\n const commands = [];\n let i = 0;\n const num = () => Number(tokens[i++]);\n while (i < tokens.length) {\n const op = tokens[i++];\n if (op === \"M\" || op === \"L\") {\n commands.push({ op, x: num(), y: num() });\n } else if (op === \"H\") {\n commands.push({ op, x: num() });\n } else if (op === \"V\") {\n commands.push({ op, y: num() });\n } else if (op === \"Q\") {\n commands.push({ op, x1: num(), y1: num(), x: num(), y: num() });\n } else if (op === \"C\") {\n commands.push({\n op,\n x1: num(),\n y1: num(),\n x2: num(),\n y2: num(),\n x: num(),\n y: num()\n });\n } else if (op === \"Z\") {\n commands.push({ op });\n }\n }\n return commands;\n}\nfunction extentOf(commands) {\n let x0 = Infinity;\n let x1 = -Infinity;\n for (const c of commands) {\n if (\"x\" in c) {\n x0 = Math.min(x0, c.x);\n x1 = Math.max(x1, c.x);\n }\n if (\"x1\" in c) {\n x0 = Math.min(x0, c.x1);\n x1 = Math.max(x1, c.x1);\n }\n }\n return { x0, x1 };\n}\nfunction shapeOf(d, color, track) {\n const commands = parsePath(d);\n return { commands, color, track, ...extentOf(commands) };\n}\nfunction trackColors(layout, pathColors) {\n return new Map(\n layout.tracks.map((track) => [\n track.id,\n track.type === \"read\" ? readColor(track) : pathColors[track.id]\n ])\n );\n}\nfunction layerOf(layout, type, colors) {\n const { shapes } = layout;\n const colorOf = (s) => colors.get(s.id);\n const trackOf = (s) => type === \"haplotype\" ? s.id : void 0;\n const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({\n color: colorOf(r),\n track: trackOf(r),\n x0: r.xStart,\n x1: r.xEnd + 1,\n y0: r.yStart,\n y1: r.yEnd + 1\n }));\n const curves = curvePaths(shapes.curves, type).map(\n (c) => shapeOf(c.path, colorOf(c), trackOf(c))\n );\n const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), trackOf(c)));\n return { rects, shapes: [...curves, ...corners] };\n}\nfunction tubeMapPicture({\n layout,\n pathColors\n}) {\n const colors = trackColors(layout, pathColors);\n const nodes = [];\n layout.nodes.forEach((node) => {\n if (node.order >= 0) {\n const commands = parsePath(nodeOutlinePath(node));\n nodes.push({ name: node.name, commands, ...extentOf(commands) });\n }\n });\n return {\n bounds: layout.bounds,\n layers: [\n layerOf(layout, \"haplotype\", colors),\n layerOf(layout, \"read\", colors)\n ],\n nodes,\n mismatches: tubeMapMismatches(layout).filter(\n (m) => m.kind !== \"insertion\" || !m.softClip\n )\n };\n}\nfunction trace(ctx, commands, x, y) {\n let cx = 0;\n let cy = 0;\n for (const c of commands) {\n switch (c.op) {\n case \"M\":\n cx = c.x;\n cy = c.y;\n ctx.moveTo(x(cx), y(cy));\n break;\n case \"L\":\n cx = c.x;\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"H\":\n cx = c.x;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"V\":\n cy = c.y;\n ctx.lineTo(x(cx), y(cy));\n break;\n case \"Q\":\n cx = c.x;\n cy = c.y;\n ctx.quadraticCurveTo(x(c.x1), y(c.y1), x(cx), y(cy));\n break;\n case \"C\":\n cx = c.x;\n cy = c.y;\n ctx.bezierCurveTo(x(c.x1), y(c.y1), x(c.x2), y(c.y2), x(cx), y(cy));\n break;\n case \"Z\":\n ctx.closePath();\n break;\n }\n }\n}\nfunction fillByColor(ctx, items, visible, colorOf, addTo) {\n const byColor = /* @__PURE__ */ new Map();\n for (const item of items) {\n if (visible(item)) {\n const color = colorOf(item);\n const list = byColor.get(color);\n if (list) {\n list.push(item);\n } else {\n byColor.set(color, [item]);\n }\n }\n }\n for (const list of byColor.values()) {\n ctx.fillStyle = colorOf(list[0]);\n ctx.beginPath();\n for (const item of list) {\n addTo(item);\n }\n ctx.fill();\n }\n}\nvar FULL_OUTLINE_PX = 12;\nvar MIN_OUTLINE_ALPHA = 0.15;\nfunction outlineAlpha(screenWidth) {\n return Math.max(MIN_OUTLINE_ALPHA, Math.min(1, screenWidth / FULL_OUTLINE_PX));\n}\nvar NODE_TINT_ALPHA = 0.55;\nfunction drawTubeMap(ctx, picture, frame) {\n const { x, y, width } = frame;\n const visible = (item) => x(item.x1) >= 0 && x(item.x0) <= width;\n const colorOf = (item) => item.track !== void 0 && frame.tubeColors?.[item.track] || item.color;\n ctx.globalAlpha = 1;\n for (const layer of picture.layers) {\n fillByColor(ctx, layer.rects, visible, colorOf, (r) => {\n const left = x(r.x0);\n const top = y(r.y0);\n ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);\n });\n fillByColor(ctx, layer.shapes, visible, colorOf, (s) => {\n trace(ctx, s.commands, x, y);\n });\n }\n const stroke = frame.darkMode ? \"#d0d0d0\" : \"#000000\";\n const fill = frame.darkMode ? \"rgba(40,40,40,0.4)\" : \"rgba(255,255,255,0.4)\";\n ctx.lineWidth = 2 * Math.max(0.25, Math.min(1, frame.yScale));\n for (const node of picture.nodes) {\n if (visible(node)) {\n const lit = node.name === frame.highlightNode;\n ctx.beginPath();\n trace(ctx, node.commands, x, y);\n const tint = lit ? void 0 : frame.nodeColors?.get(node.name);\n ctx.fillStyle = lit ? \"rgba(255,192,203,0.5)\" : tint ?? fill;\n ctx.strokeStyle = lit ? \"#ff0000\" : stroke;\n ctx.globalAlpha = tint ? NODE_TINT_ALPHA : 1;\n ctx.fill();\n ctx.globalAlpha = lit ? 1 : outlineAlpha(x(node.x1) - x(node.x0));\n ctx.stroke();\n ctx.globalAlpha = 1;\n }\n }\n drawMismatches(ctx, picture.mismatches, frame);\n}\nvar MISMATCH_FONT_PX = 12;\nvar MIN_MISMATCH_FONT_PX = 6;\nfunction mismatchesLegible(yScale) {\n return MISMATCH_FONT_PX * yScale >= MIN_MISMATCH_FONT_PX;\n}\nfunction mismatchOnScreen(m, { x, width }) {\n const [x0, x1] = m.kind === \"insertion\" ? [m.x, m.x] : [m.x0, m.x1];\n return x(x1) >= 0 && x(x0) <= width;\n}\nfunction drawMismatches(ctx, marks, frame) {\n const { x, y, yScale, darkMode } = frame;\n if (!mismatchesLegible(yScale) || marks.length === 0) {\n return;\n }\n const fontPx = MISMATCH_FONT_PX * yScale;\n ctx.fillStyle = \"grey\";\n ctx.beginPath();\n for (const m of marks) {\n if (m.kind === \"deletion\" && mismatchOnScreen(m, frame)) {\n const left = x(m.x0);\n const top = y(m.y);\n ctx.rect(left, top, x(m.x1) - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n ctx.font = `${fontPx}px monospace`;\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = darkMode ? \"#ffffff\" : \"#000000\";\n for (const m of marks) {\n if (!mismatchOnScreen(m, frame)) {\n continue;\n }\n if (m.kind === \"substitution\") {\n ctx.fillText(m.seq, x(m.x0) + 1, y(m.y + m.height));\n } else if (m.kind === \"insertion\") {\n ctx.fillText(\"*\", x(m.x) - 3, y(m.y + m.height));\n }\n }\n}\n\nexport {\n parsePath,\n trackColors,\n tubeMapPicture,\n drawTubeMap,\n mismatchesLegible,\n mismatchOnScreen\n};\n", "import {\n tubeSpan\n} from \"./chunk-DRA7733Q.js\";\n\n// src/tubeMap/genes.ts\nfunction tubeMapGenes(byRefName, genes) {\n const out = [];\n for (const gene of genes) {\n const boxes = byRefName.get(gene.refName);\n const first = boxes?.[0];\n const last = boxes?.at(-1);\n if (!boxes || !first || !last) {\n continue;\n }\n const start = Math.max(gene.start, first.bp0);\n const end = Math.min(gene.end, last.bp1);\n if (end <= start) {\n continue;\n }\n out.push({\n gene,\n ...tubeSpan(boxes, start, end),\n exons: gene.exons.filter((e) => e.end > start && e.start < end).map(\n (e) => tubeSpan(boxes, Math.max(e.start, start), Math.min(e.end, end))\n )\n });\n }\n return out;\n}\nvar GENE_ROW_PX = 22;\nvar MAX_GENE_ROWS = 4;\nvar EXON_PX = 8;\nvar NAME_FONT = \"11px sans-serif\";\nvar NAME_GAP_PX = 8;\nfunction tubeMapGeneRows(genes) {\n const edges = genes.flatMap((g) => [\n { x: g.x0, step: 1 },\n { x: g.x1, step: -1 }\n ]).sort((a, b) => a.x - b.x || a.step - b.step);\n let depth = 0;\n let most = 0;\n for (const { step } of edges) {\n depth += step;\n most = Math.max(most, depth);\n }\n return Math.min(MAX_GENE_ROWS, most);\n}\nfunction drawTubeMapGenes(ctx, genes, frame, bottom, top = 0) {\n const { x, width, darkMode } = frame;\n const rows = Math.max(1, Math.floor((bottom - top) / GENE_ROW_PX));\n const rowEnds = [];\n const ink = darkMode ? \"#e0e0e6\" : \"#1c1c22\";\n ctx.font = NAME_FONT;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"alphabetic\";\n ctx.fillStyle = ink;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1;\n const placed = genes.map((g) => ({ g, s0: x(g.x0), s1: x(g.x1) })).filter(({ s0, s1 }) => s1 >= 0 && s0 <= width).sort((a, b) => a.s0 - b.s0);\n for (const { g, s0, s1 } of placed) {\n const arrow = g.gene.strand > 0 ? \" \\u2192\" : g.gene.strand < 0 ? \"\\u2190 \" : \"\";\n const label = g.gene.strand < 0 ? `${arrow}${g.gene.name}` : `${g.gene.name}${arrow}`;\n const mid = (Math.max(s0, 0) + Math.min(s1, width)) / 2;\n const half = ctx.measureText(label).width / 2;\n const left = Math.min(s0, mid - half);\n const right = Math.max(s1, mid + half);\n let row = rowEnds.findIndex((end) => end + NAME_GAP_PX <= left);\n if (row === -1) {\n row = Math.min(rowEnds.length, rows - 1);\n }\n rowEnds[row] = Math.max(rowEnds[row] ?? -Infinity, right);\n const glyphY = bottom - row * GENE_ROW_PX - EXON_PX / 2;\n ctx.beginPath();\n ctx.moveTo(s0, glyphY + 0.5);\n ctx.lineTo(s1, glyphY + 0.5);\n ctx.stroke();\n for (const e of g.exons) {\n const e0 = x(e.x0);\n ctx.fillRect(e0, glyphY - EXON_PX / 2, Math.max(1, x(e.x1) - e0), EXON_PX);\n }\n ctx.fillText(label, mid, glyphY - EXON_PX / 2 - 2);\n }\n}\n\nexport {\n tubeMapGenes,\n GENE_ROW_PX,\n tubeMapGeneRows,\n drawTubeMapGenes\n};\n", "import {\n LIFT_BACKDROP_CSS,\n computeColorSchemeRange,\n getNodeColor\n} from \"./chunk-HBEKUQO4.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-G2FD7S3C.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/referenceStrip.ts\nvar REFERENCE_STRIP_PX = 12;\nvar REFERENCE_STRIP_ZONE_PX = REFERENCE_STRIP_PX + 8;\nvar OVERHANG_PX = 8;\nvar OVERHANG_CAP_PX = OVERHANG_PX + 3;\nvar MIN_STAGGER_PX = 12;\nfunction referenceStripBlocks(graph, {\n colorScheme,\n referenceRamp,\n walks\n}) {\n const range = { ...computeColorSchemeRange(graph), referenceRamp };\n const out = [];\n graph.nodes.forEach((node, index) => {\n if (isBackbone(node)) {\n const colors = walks ? walks.map((w) => {\n const lane = w.colors.get(node.id);\n return lane === void 0 ? LIFT_BACKDROP_CSS : abgrToCssRgba(lane);\n }) : [abgrToCssRgba(getNodeColor(node, index, colorScheme, range))];\n out.push({\n node: node.id,\n bp0: node.stable.start,\n bp1: node.stable.start + node.length,\n colors,\n faded: colors.includes(LIFT_BACKDROP_CSS)\n });\n }\n });\n return out.sort((a, b) => a.bp0 - b.bp0);\n}\nfunction span(frame, bp0, bp1) {\n const a = bp0 * frame.scale + frame.translateX;\n const b = bp1 * frame.scale + frame.translateX;\n return a < b ? [a, b] : [b, a];\n}\nvar HIT_SLOP_PX = 2;\nfunction stripOverhang(blocks, frame, width) {\n const a = -frame.translateX / frame.scale;\n const b = (width - frame.translateX) / frame.scale;\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n let below = 0;\n let above = 0;\n for (const block of blocks) {\n below += Math.max(0, Math.min(block.bp1, lo) - block.bp0);\n above += Math.max(0, block.bp1 - Math.max(block.bp0, hi));\n }\n return frame.scale >= 0 ? { left: Math.round(below), right: Math.round(above) } : { left: Math.round(above), right: Math.round(below) };\n}\nfunction stripBlockAt(blocks, frame, sx, sy) {\n if (sy < 0 || sy > REFERENCE_STRIP_PX + HIT_SLOP_PX) {\n return void 0;\n }\n let hit;\n let best = HIT_SLOP_PX;\n for (const b of blocks) {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const dist = Math.max(0, x0 - sx, sx - x1);\n if (dist <= best) {\n best = dist;\n hit = b.node;\n }\n }\n return hit;\n}\nfunction nodeAnchor(segments, toScreen) {\n const p = segments?.[Math.floor(segments.length / 2)];\n return p ? toScreen(p) : void 0;\n}\nfunction stripPixels(blocks, frame, width, dpr) {\n const placed = blocks.map((b) => {\n const [x0, x1] = span(frame, b.bp0, b.bp1);\n const px0 = Math.round(x0 * dpr);\n return {\n colors: b.colors,\n x0,\n px0,\n px1: Math.max(Math.round(x1 * dpr), px0 + 1)\n };\n }).filter((b) => b.px1 > 0 && b.px0 < width * dpr).sort((a, b) => a.x0 - b.x0);\n const out = [];\n let claimed = -Infinity;\n const tierEnds = [-Infinity, -Infinity];\n for (const { colors, px0, px1 } of placed) {\n const start = Math.max(px0, claimed);\n if (px1 > start) {\n const tier = tierEnds[0] < start ? 0 : 1;\n tierEnds[tier] = px1;\n out.push({ colors, x0: start / dpr, x1: px1 / dpr, tier });\n claimed = px1;\n }\n }\n const covered = out.length > 0 ? out.at(-1).x1 - out[0].x0 : 0;\n return covered >= out.length * MIN_STAGGER_PX ? out : out.map(({ tier: _, ...b }) => b);\n}\nfunction drawOverhang(ctx, edgeX, inward, ink) {\n const capX = inward > 0 ? edgeX : edgeX - OVERHANG_CAP_PX;\n ctx.clearRect(capX, 0, OVERHANG_CAP_PX, REFERENCE_STRIP_PX);\n const tipX = edgeX + inward;\n const baseX = tipX + inward * OVERHANG_PX;\n ctx.beginPath();\n ctx.moveTo(tipX, REFERENCE_STRIP_PX / 2);\n ctx.lineTo(baseX, 0);\n ctx.lineTo(baseX, REFERENCE_STRIP_PX);\n ctx.closePath();\n ctx.fillStyle = ink;\n ctx.fill();\n}\nfunction rowEdge(row, rows, dpr) {\n return Math.round(row * REFERENCE_STRIP_PX * dpr / rows) / dpr;\n}\nfunction drawReferenceStrip(ctx, blocks, frame, {\n width,\n lit,\n darkMode,\n dpr = 1\n}) {\n const ink = darkMode ? \"#ffffff\" : \"#18181c\";\n ctx.clearRect(0, 0, width, REFERENCE_STRIP_ZONE_PX);\n for (const b of stripPixels(blocks, frame, width, dpr)) {\n const { tier } = b;\n const staggered = tier !== void 0 && b.colors.length === 1;\n const rows = staggered ? 2 : b.colors.length;\n b.colors.forEach((color, i) => {\n const row = staggered ? tier : i;\n const y0 = rowEdge(row, rows, dpr);\n ctx.fillStyle = color;\n ctx.fillRect(b.x0, y0, b.x1 - b.x0, rowEdge(row + 1, rows, dpr) - y0);\n });\n }\n const overhang = stripOverhang(blocks, frame, width);\n if (overhang.left > 0) {\n drawOverhang(ctx, 0, 1, ink);\n }\n if (overhang.right > 0) {\n drawOverhang(ctx, width, -1, ink);\n }\n if (lit) {\n const [x0, x1] = span(frame, lit.start, lit.end);\n const w = Math.max(x1 - x0, 3);\n const left = (x0 + x1) / 2 - w / 2;\n ctx.strokeStyle = ink;\n ctx.lineWidth = 1.5;\n ctx.strokeRect(left, 0.75, w, REFERENCE_STRIP_PX - 1.5);\n if (lit.anchor) {\n ctx.beginPath();\n ctx.moveTo(left + w / 2, REFERENCE_STRIP_PX);\n ctx.lineTo(lit.anchor.x, lit.anchor.y);\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n }\n}\n\nexport {\n REFERENCE_STRIP_PX,\n REFERENCE_STRIP_ZONE_PX,\n referenceStripBlocks,\n stripOverhang,\n stripBlockAt,\n nodeAnchor,\n stripPixels,\n drawReferenceStrip\n};\n", "import {\n isBackbone\n} from \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/tubeMap/deviations.ts\nfunction boxesOf(graph, layout) {\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const boxes = [];\n layout.nodes.forEach((node, index) => {\n const g = nodeById.get(node.name);\n if (node.order >= 0 && g && isBackbone(g)) {\n const bp0 = g.stable.start;\n boxes.push({ bp0, bp1: bp0 + node.sequenceLength, index, node });\n }\n });\n return boxes.sort((a, b) => a.bp0 - b.bp0);\n}\nfunction boxAt(boxes, bp, visited) {\n let lo = 0;\n let hi = boxes.length - 1;\n while (lo < hi) {\n const mid = lo + hi + 1 >> 1;\n if (boxes[mid].bp0 <= bp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return [boxes[lo], boxes[lo - 1]].find(\n (box) => box && visited.has(box.index) && box.bp0 <= bp && bp <= box.bp1\n );\n}\nfunction deviationMarks(graph, layout, deviations) {\n const boxes = boxesOf(graph, layout);\n const marks = [];\n for (const track of layout.tracks) {\n const devs = track.name ? deviations.get(track.name) : void 0;\n if (devs?.length) {\n const visited = /* @__PURE__ */ new Map();\n for (const segment of track.path) {\n if (segment.node !== null && segment.y !== void 0 && !visited.has(segment.node)) {\n visited.set(segment.node, segment.y);\n }\n }\n for (const d of devs) {\n const box = boxAt(boxes, d.start, visited);\n if (box) {\n const { node, bp0, bp1 } = box;\n const at = (bp) => node.x + (Math.min(bp, bp1) - bp0) / (bp1 - bp0) * node.pixelWidth;\n marks.push({\n x0: at(d.start),\n x1: at(d.end),\n y: visited.get(box.index),\n height: track.width\n });\n }\n }\n }\n }\n return marks;\n}\nfunction deviationInk(darkMode) {\n return darkMode ? \"rgba(255,255,255,0.9)\" : \"rgba(0,0,0,0.8)\";\n}\nfunction drawDeviationMarks(ctx, marks, { x, y, width, darkMode }) {\n if (marks.length === 0) {\n return;\n }\n ctx.fillStyle = deviationInk(darkMode);\n ctx.beginPath();\n for (const m of marks) {\n const left = x(m.x0);\n const right = Math.max(x(m.x1), left + 1);\n if (right >= 0 && left <= width) {\n const top = y(m.y);\n ctx.rect(left, top, right - left, y(m.y + m.height) - top);\n }\n }\n ctx.fill();\n}\nexport {\n deviationInk,\n deviationMarks,\n drawDeviationMarks\n};\n", "import type { RepeatCall } from './repeatFeatures'\n\n// Which genotyped allele belongs to which haplotype walk. A VCF states a\n// sample's alleles in genotype order, which is the genotyper's own order and\n// carries no correspondence to the assembly's haplotype numbering \u2014 TRGTdb's\n// ABCA7 record, for one, lists them shortest first. So the walks and the\n// alleles are paired by length instead: the pairing whose total difference is\n// smallest, which for lengths on a line is the non-crossing one.\n//\n// A walk that does not reach both flanking reference nodes is measured whole\n// rather than across the array, and an allele no read spanned is a copy of the\n// one that was called. Neither states a length for this array, so they pair\n// last and take no verdict \u2014 pairing them first let a walk that stops inside\n// the array take the allele that fit one spanning it, and the spanning walk\n// then read as a disagreement.\n\nexport interface WalkCall extends RepeatCall {\n // undefined where the walk and the allele are not both measurements\n agrees?: boolean\n}\n\n// Every walk/call pair over the 94 HPRC samples TRGT genotyped at the ABCA7\n// VNTR is either within 8% of its allele or more than 14% from it, so any\n// threshold across that gap separates them the same way.\nexport const CALL_TOLERANCE = 0.1\n\nfunction agrees(walkBp: number, callBp: number) {\n return Math.abs(callBp - walkBp) <= CALL_TOLERANCE * Math.max(walkBp, callBp)\n}\n\n// Pair two ascending lists of lengths, leaving out the surplus of whichever is\n// longer. `out[i]` is the index in `calls` that `walks[i]` took.\nfunction nearest(walks: number[], calls: number[]) {\n const W = walks.length\n const C = calls.length\n const cost = Array.from({ length: W + 1 }, () => new Array(C + 1).fill(0))\n const paired = Array.from({ length: W + 1 }, () =>\n new Array<boolean>(C + 1).fill(false),\n )\n for (let i = W - 1; i >= 0; i--) {\n for (let j = C - 1; j >= 0; j--) {\n const together = Math.abs(walks[i]! - calls[j]!) + cost[i + 1]![j + 1]!\n const dropWalk = W - i > C - j ? cost[i + 1]![j]! : Infinity\n const dropCall = C - j > W - i ? cost[i]![j + 1]! : Infinity\n cost[i]![j] = Math.min(together, dropWalk, dropCall)\n paired[i]![j] = cost[i]![j] === together\n }\n }\n const out = new Array<number | undefined>(W).fill(undefined)\n for (let i = 0, j = 0; i < W && j < C;) {\n if (paired[i]![j]) {\n out[i++] = j++\n } else if (W - i > C - j) {\n i++\n } else {\n j++\n }\n }\n return out\n}\n\nfunction byLength<T>(items: T[], bp: (item: T) => number) {\n return items\n .map((item, i) => ({ item, i }))\n .sort((a, b) => bp(a.item) - bp(b.item))\n}\n\nconst backed = (call: RepeatCall) => call.spanningReads !== 0\n\nfunction scored(row: { bp: number; complete: boolean }, call: RepeatCall) {\n return {\n ...call,\n agrees: row.complete && backed(call) ? agrees(row.bp, call.bp) : undefined,\n }\n}\n\n// A phased genotype names its walk's haplotype outright. The rest go by\n// length: the walks that span the array against the alleles reads spanned,\n// then everything else against what those two left. That decides the\n// ambiguous cases on merit: which walk carries the one allele a lone spanning\n// read supports, and which allele a walk that stops inside the array is drawn\n// against.\nfunction pairSample<\n R extends { bp: number; complete: boolean; haplotype?: number },\n>(rows: R[], calls: RepeatCall[]) {\n const out = new Map<number, WalkCall>()\n const taken = new Set<RepeatCall>()\n rows.forEach((row, i) => {\n const call = calls.find(\n c => c.haplotype !== undefined && c.haplotype === row.haplotype,\n )\n if (call) {\n taken.add(call)\n out.set(i, scored(row, call))\n }\n })\n const unphased = calls.filter(call => call.haplotype === undefined)\n const ranked = byLength(rows, r => r.bp)\n const stages = [\n [ranked.filter(r => r.item.complete), unphased.filter(backed)],\n [ranked, unphased],\n ] as const\n for (const [pool, group] of stages) {\n const free = pool.filter(r => !out.has(r.i))\n const open = byLength(\n group.filter(call => !taken.has(call)),\n call => call.bp,\n )\n nearest(\n free.map(r => r.item.bp),\n open.map(c => c.item.bp),\n ).forEach((pick, k) => {\n if (pick !== undefined) {\n const row = free[k]!\n const call = open[pick]!.item\n taken.add(call)\n out.set(row.i, scored(row.item, call))\n }\n })\n }\n return out\n}\n\nexport function withCalls<\n R extends {\n sample: string\n bp: number\n complete: boolean\n haplotype?: number\n },\n>(rows: R[], calls: Record<string, RepeatCall[]> | undefined) {\n if (!calls) {\n return rows as (R & { call?: WalkCall })[]\n }\n const paired = new Map<R, WalkCall>()\n const bySample = new Map<string, R[]>()\n for (const row of rows) {\n bySample.set(row.sample, [...(bySample.get(row.sample) ?? []), row])\n }\n for (const [sample, group] of bySample) {\n const called = calls[sample]\n if (called) {\n for (const [i, call] of pairSample(group, called)) {\n paired.set(group[i]!, call)\n }\n }\n }\n return rows.map(row => ({ ...row, call: paired.get(row) }))\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6\"\n}), 'Settings');"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["require_SvgIcon", "__commonJSMin", "exports", "module", "require_mobx", "__commonJSMin", "exports", "module", "require_groupKeys", "__commonJSMin", "exports", "module", "import_SvgIcon", "rampHueCss", "hue", "rampHue", "bp", "domain", "frac", "REFERENCE_RAMP_MAX_HUE", "HUE_STOP_DEG", "rampStops", "start", "reversed", "low", "high", "n", "_", "i", "RAMP_GRADIENT_STOPS", "RAMP_GRADIENT_CSS", "s", "el", "tag", "attrs", "children", "c", "escapeText", "s", "escapeAttr", "serializeEl", "node", "v", "k", "EXON_COLOR", "EXON_GAP_PX", "EXON_LINE_PX", "MIN_LANE_PX", "exonStretches", "pins", "halfWidthPx", "lift", "pathOf", "d", "inkPx", "nodeId", "own", "pin", "exonOutlineTree", "stretches", "o", "stroke", "color", "width", "el", "FALLBACK_CELL_SIZE", "meanExtentCellSize", "extentTotal", "count", "rowPitchOf", "boxes", "distinct", "min", "max", "box", "cellSizeFrom", "extentX", "extentY", "x", "resolveCellSize", "given", "getOrCreateCell", "cells", "cx", "cy", "row", "cell", "addToGrid", "cellSize", "minX", "minY", "maxX", "maxY", "entry", "cx0", "cx1", "cy0", "cy1", "queryGrid", "y", "radiusX", "radiusY", "results", "seen", "SpatialIndex", "nodePositions", "nodeId", "segments", "i", "seg", "next", "b", "EdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "version", "routes", "stranded", "baseEdgeCurves", "ei", "edge", "fromSegments", "toSegments", "curves", "curveBounds", "numPaths", "padX", "padY", "o", "pathRibbonOffsets", "distanceToSegment", "px", "py", "x1", "y1", "x2", "y2", "dx", "dy", "lenSq", "t", "distanceToCubicBezier", "cx1", "cy1", "cx2", "cy2", "minDist", "samples", "lastX", "lastY", "i", "u", "bx", "by", "distanceToBezierCurve", "c", "distanceToEdgeCurves", "curves", "yToX", "d", "nodeCache", "getSpatialIndex", "nodePositions", "version", "cached", "index", "SpatialIndex", "edgeCache", "getEdgeSpatialIndex", "graph", "drawPaths", "axis", "deletions", "routes", "stranded", "EdgeSpatialIndex", "MIN_NODE_REACH_PX", "findHoveredNode", "graphX", "graphY", "ink", "yToXOf", "reach", "queryReach", "candidates", "hovered", "best", "nodeId", "segmentIdx", "segments", "dist", "segmentMeetsBox", "a", "b", "box", "t0", "t1", "p", "q", "nodesUnderBox", "screen", "hits", "line", "findHoveredEdge", "hiddenEdges", "deletionRoutes", "edgeThreshold", "edgeIndex", "edgeIdx", "edge", "fromSegments", "toSegments", "numPaths", "baseCurves", "offset", "pathRibbonOffsets", "translateCurves", "HALO_FACTOR", "LEGEND_INSET_PX", "ROUTE_STACK", "GENE_PIN_DROP_PX", "GENE_STACK", "TOPMOST_BASELINE", "LABEL_PX", "LABEL_PAD", "geneCoverageNote", "pin", "length", "per", "unit", "amount", "bp", "geneLabelCandidates", "pins", "screen", "contigThickness", "nodesUnder", "ink", "byExtent", "x", "y", "note", "box", "id", "items", "extent", "a", "b", "layoutLabels", "m", "width", "height", "translateX", "translateY", "scaleX", "scaleY", "frame", "p", "reserved", "label", "rowLabelBox", "stripPx", "LABEL_CHAR_PX", "take", "occupancy", "onRows", "rowsTop", "r", "halo", "byBubble", "h", "bubbles", "placeLabels", "baseline", "genes", "nodesUnderBox", "sizeCandidates", "sizeLabelCandidates", "deletionLabels", "placeSizeLabels", "routes", "route", "nodeLabels", "nodeLabelBudget", "nodeOwnLocation", "node", "isAnchored", "anchoredNodeLocation", "panSNSample", "panSNHaplotype", "panSNContig", "widestCluster", "spans", "maxGap", "sorted", "a", "b", "best", "current", "span", "groupKey", "loc", "contributingAssemblies", "graph", "groups", "key", "group", "bySample", "candidate", "existing", "resolveLocationAssembly", "resolve", "resolveContributors", "contributors", "c", "sample", "locString", "locLabel", "import_jsx_runtime", "CompareArrows_default", "_jsx", "import_jsx_runtime", "HighlightAlt_default", "_jsx", "import_jsx_runtime", "LineStyle_default", "_jsx", "LINEAR_LABEL", "SYNTENY_LABEL", "NO_SYNTENY_TRACK", "oneOrMany", "label", "icon", "entries", "entryLabel", "onSelect", "disabledHelpText", "nameTheOnlyEntry", "first", "empty", "entry", "graphLaunchMenuItems", "contributors", "syntenyTracks", "onShowLinear", "onShowSynteny", "widest", "LineStyle_default", "c", "locLabel", "CompareArrows_default", "track", "nodeLaunchMenuItems", "own", "reference", "highlight", "onHighlight", "HighlightAlt_default", "target", "canonicalStrand", "node", "stepName", "strand", "stepStarts", "lengths", "total", "starts", "head", "i", "tail", "j", "mismatchesByStep", "record", "byStep", "stepAt", "pos2", "atEnd", "s", "start", "length", "add", "mismatch", "list", "last", "pos", "op", "parseCs", "at", "left", "take", "tubeMapReads", "graph", "records", "firstId", "nodeByName", "n", "reads", "nodes", "step", "kept", "first", "mismatches", "names", "lastLength", "k", "FORWARD_READ_COLORS", "REVERSE_READ_COLORS", "readColor", "read", "colors", "parsePanSN", "refName", "parts", "haplotype", "collectRun", "seed", "byId", "adj", "claimed", "members", "anchors", "queue", "id", "node", "neighborId", "neighbor", "REFERENCE_RANK", "anchorSpan", "sorted", "b", "first", "last", "start", "end", "runDistances", "entry", "m", "dist", "member", "reach", "known", "runOffsets", "ordered", "a", "rank", "i", "offsets", "offset", "projectAlleles", "graph", "isAnchored", "n", "buildNeighbors", "alleles", "span", "max", "MIN_DELETION_BP", "MIN_ALLELE_SPAN_FRACTION", "placeOffReference", "graph", "span", "rowY", "positions", "minSpan", "alleles", "projectAlleles", "byId", "n", "alleleDeletions", "allele", "skipped", "drawn", "scale", "nodeId", "i", "node", "offset", "even", "at", "bp", "y", "neighbors", "buildNeighbors", "queue", "fromId", "fromEnd", "nextId", "next", "contributingSamples", "graph", "keep", "carried", "node", "isOffReference", "sample", "parsePanSN", "held", "row", "a", "b", "sampleRowLayout", "region", "backbone", "backboneNodes", "samples", "span", "referenceSpan", "rowOf", "s", "i", "nodePositions", "backbonePositions", "spareRow", "alleleDeletions", "placeOffReference", "stable", "ROW_HEIGHT_PX", "rowLabels", "emptyTrackShapes", "NOT_SAMPLES", "parsePanSN", "name", "sample", "haplotype", "contig", "DEBUG", "debugLog", "args", "READ_FACET_FIELDS", "FACET_FIELDS", "layersFrom", "layers", "coarsenedReadView", "showReads", "hasReads", "coarsen", "stat", "banded", "statOf", "data", "layer", "configFrom", "options", "emptyState", "config", "emptyTrackShapes", "layoutTubeMap", "inputNodes", "inputTracks", "inputReads", "topology", "layoutTopology", "placeTubeMap", "measurements", "arrangeTopology", "everything", "place", "node", "i", "placeSubset", "selectTracks", "selectReads", "tracks", "reads", "bandIdBase", "measured", "state", "read", "t", "straightenTrack", "generateNodeMap", "generateTrackIndexSequences", "generateNodeWidth", "generateNodeSuccessors", "generateNodeOrder", "reverseReversedReads", "mergeNodes", "generateNodeDegree", "switchNodeOrientation", "getMaxOrder", "mappingQualityCutoff", "focusReadNames", "facet", "focus", "facetHoldsRead", "references", "track", "kept", "sampleOf", "parsePanSN", "place", "topology", "tracks", "reads", "x", "bandIdBase", "state", "emptyState", "node", "i", "track", "read", "layers", "ignoreStrand", "haplotypeBandIdBase", "COARSENED_ID_BASE", "haplotypeBands", "statOf", "bandHaplotypes", "calculateTrackWidth", "generateLaneAssignment", "generateReadOnlyNodeAttributes", "readBands", "buildCoarsenedSyntheticBands", "coarsened", "data", "unit", "banding", "reverseReversedReads", "generateTrackIndexSequences", "b", "placeReads", "generateNodeXCoords", "generateSVGShapesFromPath", "debugLog", "getImageDimensions", "isReverse", "nodeName", "forward", "reverse", "flip", "isForwardIndex", "n", "straightenTrack", "index", "nodesToInvert", "visitedForward", "visit", "sequence", "j", "getReverseComplement", "orderY", "setMapToMax", "step", "map", "key", "value", "existing", "READ_WIDTH", "assignReadsToNodes", "idx", "firstNode", "element", "pathIdx", "elemNode", "basicPath", "sortedNodes", "compareNodesByOrder", "sets", "layer", "source", "set", "orderedSets", "topMargin", "placeReadSet", "bottomY", "calculateBottomY", "elementsWithoutNode", "len", "prevSegment", "lastValidPrev", "seg", "nextSegment", "firstValidNext", "previousVisitToNode", "nextVisitToNode", "betweenCycleReverseTraversal", "compareNoNodeReads", "segment", "toPlace", "incomingReads", "readID", "outgoingReads", "internalReads", "startY", "incomingKeys", "entry", "path", "decisionStep", "foundY", "k", "y", "compareIncomingReadKeys", "currentY", "occupiedUntil", "readElement", "setOccupiedUntil", "maxY", "a", "compareReadOutgoingSegmentsByGoingTo", "occupiedFrom", "firstNodeOffset", "occUntil", "incReadElementIndices", "incRead", "incReadPathElement", "compareInternalReads", "readIdx", "currentRead", "finalNodeCoverLength", "heightIncrease", "adjustVertically3", "pathIndex", "readA", "readB", "segmentA", "segmentB", "prevNodeA", "prevNodeB", "aPrev", "bPrev", "aReverse", "bReverse", "readIndexA", "pathIndexA", "readIndexB", "pathIndexB", "previousValidYA", "previousValidYB", "lastPathIndexA", "lastPathIndexB", "initialNodeA", "initialNodeB", "nodeA", "nodeB", "nextNodeIdx", "beginDiff", "compareTrackByInitialOrdering", "trackA", "trackB", "pathA", "pathB", "AIndex", "BIndex", "trackAOrder", "trackBOrder", "idxA", "idxB", "aFirst", "bFirst", "aLast", "bLast", "pass", "order", "isForward", "currentNodeIndex", "currentNodeIsForward", "currentNode", "previousNode", "previousNodeIsForward", "pos", "sequenceNew", "reverseMismatches", "nodeByName", "temp", "firstLen", "lastLen", "mismatches", "sequenceLength", "mm", "mirroredMismatch", "span", "COMPLEMENT", "s", "result", "tracksOrReads", "signedIndexOf", "signed", "NODE_HORIZONTAL_SLACK", "bounds", "generateNodeMap", "nodeMap", "generateNodeSuccessors", "successorSets", "predecessorSets", "addEdges", "current", "follower", "generateNodeOrderOfSingleTrack", "forwardOrder", "backwardOrder", "minOrder", "nodeIndex", "increaseOrderForAllNodes", "generateNodeOrderTrackBeginning", "anchorIndex", "anchorSeqVal", "currentOrder", "increment", "UNREACHABLE_ORDER", "fillUnassignedOrders", "orders", "filled", "generateNodeOrder", "modifiedSequence", "rightIndex", "leftIndex", "tracksAndReads", "reachability", "uninvert", "increaseOrderForSuccessors", "isSuccessor", "finalOrders", "first", "second", "scratch", "stamp", "generation", "stack", "childIndex", "getMaxOrder", "max", "v", "amount", "startingNode", "tabuNode", "newOrder", "increasedOrders", "queue", "head", "currentNodeOrder", "successor", "predecessor", "generateNodeDegree", "switchNodeOrientation", "switchNodeOrientationForPaths", "paths", "pivotPath", "scores", "onPivot", "indexSequence", "last", "prevOrder", "nextOrder", "vote", "currentX", "nextX", "extra", "calculateExtraSpace", "leftSideEdges", "rightSideEdges", "fallAngleAdjustment", "prevSeg", "yDifference", "prevSegmentPerOrderPerTrack", "assignmentByOrderAndNode", "trackNo", "segmentNumber", "addToAssignment", "generateSingleLaneAssignment", "segmentID", "assignment", "getIdealLanesAndCoords", "currentLane", "potentialAdjustmentValues", "prevNameIsNull", "prevTrack", "compareByIdealLane", "adjustVertically", "verticalAdjustment", "minAdjustmentCost", "moveBy", "cost", "getVerticalAdjustmentCost", "adjustBy", "assignmentNode", "aNode", "allAreFour", "NARROW_WIDTH", "WIDE_WIDTH", "getReadXStart", "offset", "clampedXCoordinateOfBaseWithinNode", "getReadXEnd", "cover", "getXCoordinateOfBaseWithinNode", "base", "nodeLeftX", "nodeRightX", "nodePixelCoordinatesInX", "clamped", "xStart", "xEnd", "yStart", "yEnd", "orderStartX", "orderEndX", "generateTurnaround", "buildCoarsenedSyntheticBands", "state", "source", "unit", "firstId", "COARSENED_ID_BASE", "edges", "total", "span", "edgeKey", "s", "d", "ignoreStrand", "sourceIndex", "item", "weight", "seq", "i", "sSigned", "dSigned", "srcNode", "dstNode", "key", "existing", "maxEdgeCount", "e", "BAND_MIN_WIDTH", "READ_WIDTH", "BAND_MAX_WIDTH", "widthForCount", "c", "synthetic", "edge", "id", "share", "shareText", "formatShare", "crossingsText", "label", "srcLen", "DEBUG", "tallestName", "tallestH", "n", "debugLog", "bandHaplotypes", "rulerIndex", "t", "refIndex", "ref", "refDuplicates", "refSigns", "firstVisitSigns", "altHaplotypes", "_", "walk", "orientedLike", "bands", "agreement", "visit", "sign", "flip", "signs", "node", "count", "MIN_BEND_WIDTH", "generateTurnaround", "dir", "x", "yStart", "yEnd", "trackWidth", "trackID", "order", "type", "trackName", "extra", "offset", "apex", "radius", "stem", "yTop", "yBottom", "stubNear", "stubFar", "horizontal", "segTop", "inner", "outer", "nodePixelCoordinatesInX", "nodeLeftX", "nodeRightX", "generateNodeWidth", "charWidth", "TRACK_END", "noNeighbors", "nodeCount", "addNeighbor", "neighbors", "index", "neighbor", "soleNeighbor", "mergeNodes", "pred", "succ", "signedIndexOf", "nodeName", "signed", "forward", "isReverse", "track", "sequence", "isHaplotype", "last", "previous", "current", "next", "absorbed", "mergeableWithPred", "origin", "start", "end", "head", "donor", "mergeableWithSucc", "read", "entries", "shift", "mergedSequence", "mergedEntries", "carried", "mismatches", "by", "mismatch", "name", "merged", "reverse", "kept", "predecessor", "successor", "groupBy", "items", "key", "groups", "item", "k", "group", "compareCurvesByXYStartValue", "a", "b", "curveEnds", "curve", "compareTuples", "i", "d", "curvePaths", "curves", "type", "groupedCurves", "curveGroup", "adjustValue", "adjustIncrement", "xAdjusted", "xNextAdjusted", "nodeOutlinePath", "node", "x", "y", "visitStrands", "graph", "strands", "segment", "visits", "visit", "key", "list", "tubeMapTracks", "nodeById", "n", "paths", "path", "index", "reference", "p", "pathOrigin", "visitName", "seen", "sequence", "id", "node", "k", "strand", "canonicalStrand", "stepName", "tubeMapNodes", "hasTubeMapPaths", "STACK_PX", "MIN_TUBE_PX", "MAX_TUBE_PX", "tubeWidth", "trackCount", "runTubeMap", "tracks", "reads", "tubeMapReads", "tubeColor", "pathGreyCssColor", "pathCssColor", "pathColors", "_", "i", "layout", "layoutTubeMap", "drawnNodes", "nodes", "centreline", "yOffset", "x0", "x1", "y", "extentOf", "tubeMapLayout", "run", "nodePositions", "minY", "maxY", "tubeMapColumns", "byOrder", "columns", "end", "order", "a", "b", "bp0", "bp1", "graphNode", "isBackbone", "first", "c", "column", "pathsReachBackbone", "tubeMapReferenceLayout", "rankRows", "graph", "present", "node", "a", "b", "r", "i", "anchoredLayout", "region", "backbone", "backboneNodes", "span", "referenceSpan", "rows", "nodePositions", "backbonePositions", "alleleDeletions", "placeOffReference", "ROW_HEIGHT_PX", "rowLabels", "rank", "row", "GUTTER", "LANE_PX", "ROW_HEIGHT_PX", "nodeWidth", "node", "compare", "a", "b", "compareKeys", "UNREACHED", "referenceOrder", "graph", "byId", "n", "key", "orderKeys", "placeByWalks", "backbone", "isNode", "startOf", "next", "prev", "i", "head", "insertAfter", "at", "id", "after", "insertBefore", "before", "path", "rising", "falling", "last", "start", "ids", "from", "leading", "lead", "placed", "placeBySearch", "adjacent", "queue", "ka", "kb", "nb", "searched", "sided", "seed", "run", "farHalf", "hops", "deadEnd", "touchesLeft", "other", "k", "e", "isBackbone", "rank", "layerGraph", "order", "isRef", "preds", "succs", "link", "layerOf", "l", "p", "s", "minSucc", "t", "lo", "hi", "layers", "orderedLayout", "layer", "layerWidth", "w", "layerX", "x", "y", "free", "ideal", "taken", "lane", "d", "nodePositions", "cx", "ny", "sampleOf", "path", "panSNSample", "labelOf", "stepsOf", "pieces", "lengthOf", "steps", "end", "piece", "bp", "sum", "id", "stepSpans", "spans", "pos", "len", "sliceBetween", "span", "region", "flanked", "i0", "i1", "bestEnd", "bestStart", "i", "s", "ids", "filterSamples", "rows", "samples", "r", "a", "b", "walkRows", "graph", "unit", "paths", "isReference", "p", "pathOrigin", "referencePieces", "first", "others", "walks", "n", "referenceStart", "cut", "rowOf", "ordered", "complete", "from", "to", "contig", "panSNContig", "axis", "runs", "offReferenceBp", "gapBp", "step", "last", "at", "forward", "backward", "READOUT_ROOM", "walkRowsExtent", "walks", "pitch", "ROW_HEIGHT_PX", "longest", "row", "walkRowLabels", "rows", "layout", "i", "walkRowLayout", "graph", "region", "backbone", "backboneNodes", "walkRows", "overWindow", "n", "overlapsWindow", "nodePositions", "backbonePositions", "rowLabels", "FORCE_LAYOUT_LABEL", "hasBackbone", "graph", "isBackbone", "hasWalks", "hasTubeMapBackbone", "hasTubeMapPaths", "hasAlleles", "isOffReference", "LAYOUT_MODES", "anchoredLayout", "sampleRowLayout", "walkRowLayout", "orderedLayout", "tubeMapLayout", "tubeMapReferenceLayout", "LAYOUT_MODE_VALUES", "m", "modeUsesLayoutEngine", "value", "layoutModeByValue", "FACET_GAP_PX", "FACET_TITLE_PX", "FACET_PAD_PX", "MIN_FACET_PANEL_PX", "facetGrid", "count", "bounds", "pixelRows", "width", "room", "columns", "tile", "across", "rows", "panelWidth", "panelRoom", "fitX", "fitY", "scale", "drawn", "height", "best", "grid", "FACET_FIELDS", "facetSettingOf", "facet", "raw", "domainFirst", "names", "domain", "rank", "name", "i", "listed", "a", "b", "facetCells", "by", "wrapOrder", "wrap", "places", "sample", "haplotype", "contig", "n", "p", "cells", "import_groupKeys", "SECTION_HEADER_PX", "parseSamplesTsv", "text", "head", "lines", "columns", "rows", "line", "name", "values", "i", "metadataColumns", "row", "key", "groupByOf", "value", "field", "domain", "d", "haplotypes", "n", "r", "groupWalkRows", "table", "valueOf", "groups", "group", "first", "sections", "members", "section", "s", "sectionPlacement", "rowPx", "sectionOf", "k", "rowY", "y", "best", "lo", "hi", "shift", "REPEAT_GROWTH", "coveringRepeat", "b", "repeats", "span", "growth", "r", "SUPERBUBBLE_SEGMENTS", "formatBp", "bp", "formatBpRange", "shortest", "longest", "low", "high", "unit", "routes", "count", "SATURATED_PATH_COUNT", "classifyBubble", "c", "classifyShape", "refSpan", "pathCount", "segmentCount", "inversion", "range", "repeat", "name", "alleles", "BUBBLE_KIND_COLORS", "BUBBLE_KIND_NAMES", "bubbleSegmentIds", "ON_REFERENCE", "OFF_REFERENCE", "OUTSIDE_CUT", "GENE_INK", "BAR_PX", "GAP_PX", "LABELLED_ROW_PX", "MIN_TILED_BAR_PX", "MIN_TILE_PX", "kb", "bp", "units", "unit", "walkRowReadout", "row", "reference", "call", "gapBp", "complete", "delta", "against", "outside", "called", "readoutPlacement", "text", "endX", "width", "x", "LABEL_CHAR_PX", "unitTicks", "pxPerBp", "ticks", "k", "runPaint", "run", "ramp", "REFERENCE_RAMP_ALT_CSS", "stops", "rampStops", "rampHueCss", "alongRow", "axis", "start", "end", "rowSpan", "placeRowGenes", "rows", "byRow", "placed", "row", "genes", "axis", "clip", "start", "end", "g", "alongRow", "e", "b", "GENE_FONT_PX", "GENE_CHAR_PX", "MIN_LETTERED_BAR_PX", "genePad", "rowPx", "barPx", "boxesGenes", "rowGeneBoxes", "X", "y", "ROW_HEIGHT_PX", "BAR_PX", "pad", "boxes", "x", "taken", "named", "a", "w", "half", "at", "box", "rowsText", "n", "walkRowsKey", "bars", "o", "entries", "RAMP_GRADIENT_CSS", "ON_REFERENCE", "REFERENCE_RAMP_ALT_CSS", "OFF_REFERENCE", "OUTSIDE_CUT", "CALL_TICK", "UNBACKED_TICK", "DISAGREES", "callTickInk", "call", "walkRowsKeyTree", "idPrefix", "parts", "i", "rampId", "ramp", "el", "RAMP_GRADIENT_STOPS", "s", "swatch", "GENE_INK", "GAP_PX", "text", "LABEL_CHAR_PX", "p", "rowPitch", "count", "room", "minRowPx", "fit", "LABELLED_ROW_PX", "coalesceRuns", "runs", "pxPerBp", "minBp", "out", "bucket", "flush", "on", "off", "r", "onReference", "lead", "held", "run", "geneTree", "walkRowsTree", "frame", "bp", "overhang", "Y", "origin", "unit", "reference", "along", "offset", "prefix", "rowTree", "paint", "runPaint", "h", "id", "rect", "color", "k", "ticks", "MIN_TILED_BAR_PX", "unitTicks", "walkRowReadout", "readoutPlacement", "readouts", "walkStripApplies", "o", "cutsWholeWalks", "mode", "PAD_PX", "WALK_STRIP_CEILING_PX", "LABEL_FONT_PX", "MIN_ROW_PX", "READOUT_ROOM", "MARK_INK", "TICK_PX", "stripMarks", "graph", "rows", "node", "visits", "marks", "row", "axis", "path", "pathOrigin", "v", "start", "end", "alongRow", "spanCache", "spansOf", "name", "byName", "lengthOf", "n", "pieces", "p", "spans", "piece", "b", "pos", "id", "len", "segmentAt", "offset", "pxPerBp", "at", "tol", "bar", "from", "to", "lo", "hi", "mid", "best", "bestLen", "bestHolds", "i", "holds", "walkStripFrame", "bars", "maxHeight", "labelPx", "r", "LABEL_CHAR_PX", "count", "rowPx", "barPx", "labelled", "readouts", "rowPitch", "longest", "left", "scaleX", "boxesGenes", "stripRowAt", "frame", "x", "y", "walkMarksTree", "index", "X", "el", "m", "w", "tick", "top", "walkStripLabelsTree", "bold", "stripGeneGaps", "rowGenes", "gaps", "MAX_DPR", "MAX_CANVAS_DIM_PX", "getDpr", "warnedCanvasClamp", "backingPx", "cssSize", "dpr", "axis", "value", "syncCanvasSize", "canvas", "width", "height", "pw", "ph", "cssWidth", "cssHeight", "Canvas2DRenderer", "canvas", "ctx", "_handler", "width", "height", "syncCanvasSize", "batch", "factors", "edgeIndex", "factor", "transform", "clearColor", "normalizedRgbToCssRgba", "hl", "color", "items", "groupByPaint", "e", "i", "inRun", "brightenAbgr", "abgrToCssRgba", "first", "lifted", "nodeId", "run", "s", "p0", "p", "a", "tip", "left", "notch", "right", "arrowheadOutline", "ARROW_NOTCH", "ux", "uy", "tipX", "tipY", "length", "halfWidth", "backX", "backY", "notchBack", "paintOf", "groups", "deferred", "l", "item", "weight", "last", "into", "key", "group", "rangeText", "contig", "start", "end", "e", "groupDigits", "formatBp", "walkKey", "walk", "reference", "field", "own", "scale", "spanned", "outside", "walkPosition", "nodeId", "length", "progress", "range", "referenceBoxes", "graph", "layout", "nodeById", "n", "byRefName", "node", "graphNode", "isBackbone", "refName", "start", "boxes", "a", "b", "tubeX", "bp", "isEnd", "lo", "hi", "mid", "bp1", "box", "span", "tubeSpan", "end", "rulerBoxes", "best", "TICK_PX", "LABEL_GAP_PX", "TARGET_TICK_PX", "MIN_BRACKET_PX", "rulerInk", "darkMode", "niceStep", "raw", "pow", "m", "placeLabels", "candidates", "placed", "text", "at", "scaleMarks", "x", "width", "measure", "first", "last", "from", "to", "bpSpan", "step", "ticks", "positions", "sx", "boxMarks", "shown", "s0", "s1", "label", "position", "spans", "lengths", "boundaries", "length", "formatBp", "ends", "rulerMarks", "referenceAxis", "drawTubeMapRuler", "ctx", "frame", "top", "marks", "ink", "y", "x0", "x1", "referenceNodes", "graph", "layout", "nodeById", "n", "out", "node", "graphNode", "isBackbone", "tubeMapConnectors", "nodes", "bpToScreen", "tubeToScreen", "width", "bottom0", "bottom1", "HIT_SLOP_PX", "connectorAt", "connectors", "zoneBottom", "sx", "sy", "t", "hit", "best", "c", "a", "b", "dist", "band", "ctx", "bottom", "sides", "drawTubeMapConnectors", "highlightNode", "darkMode", "ink", "lit", "readMismatches", "read", "layout", "marks", "entries", "entry", "i", "nodeIndex", "forward", "node", "pathIndex", "y", "base", "at", "pos", "getXCoordinateOfBaseWithinNode", "mm", "x0", "softClip", "x1", "tubeMapMismatches", "parsePath", "d", "tokens", "commands", "i", "num", "op", "extentOf", "x0", "x1", "c", "shapeOf", "color", "track", "trackColors", "layout", "pathColors", "readColor", "layerOf", "type", "colors", "shapes", "colorOf", "s", "trackOf", "rects", "r", "curves", "curvePaths", "corners", "tubeMapPicture", "nodes", "node", "nodeOutlinePath", "tubeMapMismatches", "m", "trace", "ctx", "x", "y", "cx", "cy", "fillByColor", "items", "visible", "addTo", "byColor", "item", "list", "FULL_OUTLINE_PX", "MIN_OUTLINE_ALPHA", "outlineAlpha", "screenWidth", "NODE_TINT_ALPHA", "drawTubeMap", "picture", "frame", "width", "layer", "left", "top", "stroke", "fill", "lit", "tint", "drawMismatches", "MISMATCH_FONT_PX", "MIN_MISMATCH_FONT_PX", "mismatchesLegible", "yScale", "mismatchOnScreen", "marks", "darkMode", "fontPx", "tubeMapGenes", "byRefName", "genes", "out", "gene", "boxes", "first", "last", "start", "end", "tubeSpan", "e", "GENE_ROW_PX", "MAX_GENE_ROWS", "EXON_PX", "NAME_FONT", "NAME_GAP_PX", "tubeMapGeneRows", "edges", "g", "a", "b", "depth", "most", "step", "drawTubeMapGenes", "ctx", "frame", "bottom", "top", "x", "width", "darkMode", "rows", "rowEnds", "ink", "placed", "s0", "s1", "arrow", "label", "mid", "half", "left", "right", "row", "glyphY", "e0", "REFERENCE_STRIP_PX", "REFERENCE_STRIP_ZONE_PX", "OVERHANG_PX", "OVERHANG_CAP_PX", "MIN_STAGGER_PX", "referenceStripBlocks", "graph", "colorScheme", "referenceRamp", "walks", "range", "computeColorSchemeRange", "out", "node", "index", "isBackbone", "colors", "w", "lane", "LIFT_BACKDROP_CSS", "abgrToCssRgba", "getNodeColor", "a", "b", "span", "frame", "bp0", "bp1", "HIT_SLOP_PX", "stripOverhang", "blocks", "width", "lo", "hi", "below", "above", "block", "stripBlockAt", "sx", "sy", "hit", "best", "x0", "x1", "dist", "nodeAnchor", "segments", "toScreen", "p", "stripPixels", "dpr", "placed", "px0", "claimed", "tierEnds", "px1", "start", "tier", "_", "drawOverhang", "ctx", "edgeX", "inward", "ink", "capX", "tipX", "baseX", "rowEdge", "row", "rows", "drawReferenceStrip", "lit", "darkMode", "staggered", "color", "i", "y0", "overhang", "left", "boxesOf", "graph", "layout", "nodeById", "n", "boxes", "node", "index", "g", "isBackbone", "bp0", "a", "b", "boxAt", "bp", "visited", "lo", "hi", "mid", "box", "deviationMarks", "deviations", "marks", "track", "devs", "segment", "d", "bp1", "at", "deviationInk", "darkMode", "drawDeviationMarks", "ctx", "x", "y", "width", "m", "left", "right", "top", "agrees", "walkBp", "callBp", "nearest", "walks", "calls", "W", "C", "cost", "paired", "i", "j", "together", "dropWalk", "dropCall", "out", "byLength", "items", "bp", "item", "a", "b", "backed", "call", "scored", "row", "pairSample", "rows", "taken", "c", "unphased", "ranked", "r", "stages", "pool", "group", "free", "open", "pick", "k", "withCalls", "bySample", "sample", "called", "import_jsx_runtime", "Settings_default", "_jsx"]
|
|
7
|
+
}
|