jbrowse-plugin-msaview 5.2.0 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/MsaViewPanel/model.d.ts +9 -11
  2. package/dist/MsaViewPanel/model.js +7 -0
  3. package/dist/MsaViewPanel/model.test.js +3 -0
  4. package/dist/chunks/AboutDialog-HCCCEJ6V.js +2 -0
  5. package/dist/chunks/{AboutDialog-IRBPUPJK.js.map → AboutDialog-HCCCEJ6V.js.map} +4 -4
  6. package/dist/chunks/AnnotationFileDialog-CPJ4X7XW.js +2 -0
  7. package/dist/chunks/AnnotationFileDialog-CPJ4X7XW.js.map +7 -0
  8. package/dist/chunks/ExportSVGDialog-YUFLYBYW.js +2 -0
  9. package/dist/chunks/ExportSVGDialog-YUFLYBYW.js.map +7 -0
  10. package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js → FeatureDialog-NBDB5SWU.js} +1 -1
  11. package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js.map → FeatureDialog-NBDB5SWU.js.map} +1 -1
  12. package/dist/chunks/HelpDialog-UCUYPCOI.js +2 -0
  13. package/dist/chunks/HelpDialog-UCUYPCOI.js.map +7 -0
  14. package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js → LaunchMsaViewDialog-HGL6P4E4.js} +2 -2
  15. package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js.map → LaunchMsaViewDialog-HGL6P4E4.js.map} +1 -1
  16. package/dist/chunks/{MetadataDialog-KZWQFRF7.js → MetadataDialog-DSA3545E.js} +2 -2
  17. package/dist/chunks/{MetadataDialog-KZWQFRF7.js.map → MetadataDialog-DSA3545E.js.map} +1 -1
  18. package/dist/chunks/MsaViewPanel-XSXFJWWY.js +2 -0
  19. package/dist/chunks/{MsaViewPanel-RUZAKFCB.js.map → MsaViewPanel-XSXFJWWY.js.map} +1 -1
  20. package/dist/chunks/{TrackInfoDialog-IFIG77WO.js → TrackInfoDialog-YXCIGFYM.js} +2 -2
  21. package/dist/chunks/{TrackInfoDialog-IFIG77WO.js.map → TrackInfoDialog-YXCIGFYM.js.map} +1 -1
  22. package/dist/chunks/{TreeNodeInfoDialog-VRCVIF26.js → TreeNodeInfoDialog-QCWDJTM4.js} +2 -2
  23. package/dist/chunks/{TreeNodeInfoDialog-VRCVIF26.js.map → TreeNodeInfoDialog-QCWDJTM4.js.map} +1 -1
  24. package/dist/chunks/{chunk-NI3VGKQP.js → chunk-2XCUSA22.js} +2 -2
  25. package/dist/chunks/{chunk-GIHMPOCO.js → chunk-35FWLG3N.js} +1 -1
  26. package/dist/chunks/{chunk-GIHMPOCO.js.map → chunk-35FWLG3N.js.map} +1 -1
  27. package/dist/chunks/{chunk-F3EC6OCO.js → chunk-5OSSOQH4.js} +1 -1
  28. package/dist/chunks/{chunk-F3EC6OCO.js.map → chunk-5OSSOQH4.js.map} +1 -1
  29. package/dist/chunks/{chunk-GDFVLZYX.js → chunk-666BV764.js} +2 -2
  30. package/dist/chunks/{chunk-GDFVLZYX.js.map → chunk-666BV764.js.map} +1 -1
  31. package/dist/chunks/{chunk-YUKJI2AH.js → chunk-AQ2THRTR.js} +2 -2
  32. package/dist/chunks/{chunk-YUKJI2AH.js.map → chunk-AQ2THRTR.js.map} +1 -1
  33. package/dist/chunks/chunk-ASUKJX5J.js +2 -0
  34. package/dist/chunks/chunk-ASUKJX5J.js.map +7 -0
  35. package/dist/chunks/chunk-FFHB7WP7.js +18 -0
  36. package/dist/chunks/chunk-FFHB7WP7.js.map +7 -0
  37. package/dist/chunks/{chunk-YOTSFJMU.js → chunk-GAY2PLS6.js} +1 -1
  38. package/dist/chunks/{chunk-YOTSFJMU.js.map → chunk-GAY2PLS6.js.map} +1 -1
  39. package/dist/chunks/chunk-JDQUBCHM.js +2 -0
  40. package/dist/chunks/chunk-JDQUBCHM.js.map +7 -0
  41. package/dist/chunks/{chunk-IBBQUV2I.js → chunk-KSCGTF4R.js} +1 -1
  42. package/dist/chunks/{chunk-IBBQUV2I.js.map → chunk-KSCGTF4R.js.map} +1 -1
  43. package/dist/chunks/{chunk-6YFCSBEE.js → chunk-NLAW2OYS.js} +2 -2
  44. package/dist/chunks/{chunk-6YFCSBEE.js.map → chunk-NLAW2OYS.js.map} +1 -1
  45. package/dist/chunks/{chunk-ZCT7RD24.js → chunk-QQKPT6EL.js} +2 -2
  46. package/dist/chunks/{chunk-H6IQBAW7.js → chunk-WMDOEOAH.js} +2 -2
  47. package/dist/chunks/{chunk-H6IQBAW7.js.map → chunk-WMDOEOAH.js.map} +1 -1
  48. package/dist/chunks/chunk-XTQQNBQ5.js +2 -0
  49. package/dist/chunks/chunk-XTQQNBQ5.js.map +7 -0
  50. package/dist/chunks/chunk-XXCNVFGP.js +11 -0
  51. package/dist/chunks/chunk-XXCNVFGP.js.map +7 -0
  52. package/dist/chunks/chunk-ZQSWX57C.js +2 -0
  53. package/dist/chunks/chunk-ZQSWX57C.js.map +7 -0
  54. package/dist/chunks/{dist-CMWKVHC7.js → dist-GXYZN4ZR.js} +2 -2
  55. package/dist/chunks/{dist-CMWKVHC7.js.map → dist-GXYZN4ZR.js.map} +3 -3
  56. package/dist/chunks/dist-GZKCGB2N.js +2 -0
  57. package/dist/chunks/{model-VE7IYWNU.js → model-36HCIOZJ.js} +3 -3
  58. package/dist/chunks/model-36HCIOZJ.js.map +7 -0
  59. package/dist/chunks/renderToSvg-5DMIQ72S.js +2 -0
  60. package/dist/jbrowse-plugin-msaview.esm.js +2 -2
  61. package/dist/jbrowse-plugin-msaview.esm.js.map +2 -2
  62. package/dist/version.d.ts +1 -1
  63. package/dist/version.js +1 -1
  64. package/package.json +18 -18
  65. package/src/MsaViewPanel/model.test.ts +4 -0
  66. package/src/MsaViewPanel/model.ts +8 -0
  67. package/src/version.ts +1 -1
  68. package/dist/chunks/AboutDialog-IRBPUPJK.js +0 -2
  69. package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js +0 -2
  70. package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js.map +0 -7
  71. package/dist/chunks/ExportSVGDialog-TYYPI6VB.js +0 -2
  72. package/dist/chunks/ExportSVGDialog-TYYPI6VB.js.map +0 -7
  73. package/dist/chunks/MsaViewPanel-RUZAKFCB.js +0 -2
  74. package/dist/chunks/chunk-NMYD2GWF.js +0 -18
  75. package/dist/chunks/chunk-NMYD2GWF.js.map +0 -7
  76. package/dist/chunks/chunk-QQ5LZUIO.js +0 -11
  77. package/dist/chunks/chunk-QQ5LZUIO.js.map +0 -7
  78. package/dist/chunks/chunk-QUWPHTZQ.js +0 -2
  79. package/dist/chunks/chunk-QUWPHTZQ.js.map +0 -7
  80. package/dist/chunks/dist-R73J3CC3.js +0 -2
  81. package/dist/chunks/model-VE7IYWNU.js.map +0 -7
  82. package/dist/chunks/renderToSvg-VDXAB7TT.js +0 -2
  83. /package/dist/chunks/{chunk-NI3VGKQP.js.map → chunk-2XCUSA22.js.map} +0 -0
  84. /package/dist/chunks/{chunk-ZCT7RD24.js.map → chunk-QQKPT6EL.js.map} +0 -0
  85. /package/dist/chunks/{dist-R73J3CC3.js.map → dist-GZKCGB2N.js.map} +0 -0
  86. /package/dist/chunks/{renderToSvg-VDXAB7TT.js.map → renderToSvg-5DMIQ72S.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["global-externals:mobx", "global-externals:react-dom", "global-externals:react-dom/client", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/renderToSvg.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/getVisibleLeaves.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/minimap/MinimapSVG.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/DragHandle.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/useDragScroll.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/tileColor.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/msaRaster.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/minimap/minimapLayout.ts", "../../node_modules/.pnpm/colord@2.10.0/node_modules/colord/index.mjs", "../../node_modules/.pnpm/colord@2.10.0/node_modules/colord/plugins/a11y.mjs", "../../node_modules/.pnpm/colord@2.10.0/node_modules/colord/plugins/names.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/util.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/drawFeatureSpans.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/renderBoxFeatureCanvasBlock.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/setFontSize.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/overlayColors.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/renderHighlights.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/domainBandCursor.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/visibleColRange.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/msa/renderMSABlock.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/rowpanels/headerLayout.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/rowpanels/renderFeaturePanel.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/rowpanels/renderStrip.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/rowpanels/renderRowPanel.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/columnCounts.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/sequenceLogo.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tracks/drawTracks.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tree/ScaleBarSVG.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/measureTextCanvas.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tree/cladeBrackets.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tree/ellipsize.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/hierarchy.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tree/renderTreeCanvas.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/components/tree/renderTreeOverview.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_a4121c98828e538e8b3708814bbfe622/node_modules/react-msaview/src/renderToStaticMarkup.ts"],
4
+ "sourcesContent": ["module.exports = JBrowseExports[\"mobx\"];", "module.exports = JBrowseExports[\"react-dom\"];", "module.exports = JBrowseExports[\"react-dom/client\"];", "/* eslint-disable react-refresh/only-export-components */\nimport React from 'react'\n\nimport { when } from 'mobx'\n\nimport { visibleRowRange } from './components/getVisibleLeaves.ts'\nimport MinimapSVG from './components/minimap/MinimapSVG.tsx'\nimport { legendRows } from './components/msa/legendRows.ts'\nimport { rasterApplies, rasterImageHref } from './components/msa/msaRaster.ts'\nimport { renderBoxFeatureCanvasBlock } from './components/msa/renderBoxFeatureCanvasBlock.ts'\nimport { renderPersistentHighlights } from './components/msa/renderHighlights.ts'\nimport { renderMSABlock } from './components/msa/renderMSABlock.ts'\nimport { visibleColRange } from './components/msa/visibleColRange.ts'\nimport { headerRunsAcross } from './components/rowpanels/headerLayout.ts'\nimport { renderRowPanels } from './components/rowpanels/renderRowPanel.ts'\nimport { renderAllTracks } from './components/tracks/drawTracks.ts'\nimport ScaleBarSVG from './components/tree/ScaleBarSVG.tsx'\nimport { cladeLabelBoxes } from './components/tree/cladeBrackets.ts'\nimport { ellipsize } from './components/tree/ellipsize.ts'\nimport { renderTreeCanvas } from './components/tree/renderTreeCanvas.ts'\nimport { renderTreeOverview } from './components/tree/renderTreeOverview.ts'\nimport { treeScaleBarHeight } from './constants.ts'\nimport {\n LEGEND_CHAR_W,\n LEGEND_FONT,\n LEGEND_PAD,\n LEGEND_ROW_H,\n LEGEND_SWATCH,\n LEGEND_TEXT_X,\n exportPageSize,\n getLayout,\n legendHeight,\n} from './exportLayout.ts'\nimport { measureTextCanvas } from './measureTextCanvas.ts'\nimport { renderToStaticMarkup, svgSafeColors } from './renderToStaticMarkup.ts'\nimport { outlineColor } from './util.ts'\n\nimport type { ExportSvgOptions, Layout } from './exportLayout.ts'\nimport type { MsaViewModel } from './model.ts'\nimport type { Context as ContextType } from '@jbrowse/svgcanvas'\nimport type { Theme } from '@mui/material'\n\nexport type { ExportSvgOptions } from './exportLayout.ts'\n\nexport async function renderToSvg(model: MsaViewModel, opts: ExportSvgOptions) {\n // dataInitialized stays false while the model holds a load error, so waiting\n // on it alone would never settle\n await when(() => model.dataInitialized || !!model.error)\n if (model.error) {\n throw model.error\n }\n const { Context } = await import('@jbrowse/svgcanvas')\n // Each svgcanvas layer is already serialized SVG, and React would have to\n // parse it into a second DOM only for the export to serialize it back out.\n // The layers register themselves here instead, and their markup is spliced\n // into the page as strings.\n const layers = new Map<string, ContextType>()\n const markup = renderToStaticMarkup(\n <MsaSvg\n model={model}\n theme={opts.theme}\n Context={Context}\n layout={getLayout(model, opts)}\n layers={layers}\n />,\n )\n // innerHTML serializes as HTML, and an XML parser rejects its &nbsp;\n return svgSafeColors(\n markup.replaceAll(/<g data-layer=\"([^\"]+)\"><\\/g>/g, (match, id: string) => {\n const ctx = layers.get(id)\n return ctx ? `<g id=\"${id}\">${ctx.getSvg().innerHTML}</g>` : match\n }),\n ).replaceAll('&nbsp;', '&#160;')\n}\n\nfunction MsaSvg({\n model,\n theme,\n Context,\n layout,\n layers,\n}: {\n model: MsaViewModel\n theme: Theme\n Context: typeof ContextType\n layout: Layout\n layers: LayerMap\n}) {\n const { width, trackHeight, includeMinimap, legendWidth, topHeight } = layout\n const { effectiveTreeAreaWidth, rowPanelsWidth } = model\n const { width: totalWidth, height } = exportPageSize(model, layout)\n const legendTop = topHeight\n const props = { Context, model, theme, layout, layers }\n\n const body = (\n <>\n {trackHeight > 0 ? <TrackRendering {...props} /> : null}\n <g\n transform={trackHeight > 0 ? `translate(0 ${trackHeight})` : undefined}\n >\n <CoreRendering {...props} />\n </g>\n </>\n )\n\n return (\n <svg\n width={totalWidth}\n height={height}\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\n viewBox={`0 0 ${totalWidth} ${height}`}\n // the canvas layers name sans-serif on each glyph; the legend, labels\n // and headers inherit it here instead of an editor's default serif\n fontFamily=\"sans-serif\"\n >\n {/* every layer below draws in the theme's colors, so the page has to be\n the theme's background too -- a hardcoded white one turns a dark-theme\n export into white text on white */}\n <rect\n width=\"100%\"\n height=\"100%\"\n fill={theme.palette.background.default}\n />\n {topHeight > 0 ? (\n <>\n {includeMinimap ? (\n <g\n id=\"minimap-panel\"\n transform={`translate(${effectiveTreeAreaWidth + rowPanelsWidth} 0)`}\n >\n <MinimapSVG model={model} theme={theme} />\n </g>\n ) : null}\n <RowPanelHeadersSVG\n model={model}\n theme={theme}\n bandHeight={topHeight}\n />\n {model.showTreeOverview ? (\n <TreeOverviewSVG\n model={model}\n theme={theme}\n Context={Context}\n layers={layers}\n />\n ) : null}\n <TreeScaleBarSVG model={model} theme={theme} />\n <g transform={`translate(0 ${topHeight})`}>{body}</g>\n </>\n ) : (\n body\n )}\n {legendWidth > 0 ? (\n <g id=\"legend-panel\" transform={`translate(${width} ${legendTop})`}>\n <LegendSVG model={model} theme={theme} width={legendWidth} />\n </g>\n ) : null}\n </svg>\n )\n}\n\n// The tree overview in the top band, over the tree column, where the live view\n// puts it. It is part of the figure rather than chrome: the inset is what says\n// where the focused clade sits in the whole tree.\nfunction TreeOverviewSVG({\n model,\n theme,\n Context,\n layers,\n}: {\n model: MsaViewModel\n theme: Theme\n Context: typeof ContextType\n layers: LayerMap\n}) {\n const { effectiveTreeAreaWidth, overviewHeight, id } = model\n const ctx = new Context(effectiveTreeAreaWidth, overviewHeight)\n renderTreeOverview({\n model,\n ctx,\n theme,\n width: effectiveTreeAreaWidth,\n height: overviewHeight,\n })\n return (\n <ClipGroup\n panelId=\"tree-overview\"\n clipId={`tree-overview-${id}`}\n width={effectiveTreeAreaWidth}\n height={overviewHeight}\n ctx={ctx}\n layers={layers}\n />\n )\n}\n\n// The branch-length scale bar under the tree overview, where the live view puts\n// it (see TreeRuler). A phylogram whose branch lengths are drawn to a scale\n// nothing states is a figure a reader cannot measure, so the export carries the\n// bar even though it is chrome on screen.\nfunction TreeScaleBarSVG({\n model,\n theme,\n}: {\n model: MsaViewModel\n theme: Theme\n}) {\n const { marginLeft, treeScaleBar: bar, treeOverviewHeight } = model\n if (!bar) {\n return null\n }\n return (\n <g id=\"tree-scalebar\">\n <ScaleBarSVG\n bar={bar}\n marginLeft={marginLeft}\n y={treeOverviewHeight + treeScaleBarHeight}\n color={theme.palette.text.primary}\n />\n </g>\n )\n}\n\n// Each strip's header over the column it names, turned on its side, where the\n// live view puts it (see RowPanelHeaders). The baseline runs up the figure, so\n// the name sits to the left of it, the way TrackLabelsSVG offsets a horizontal\n// baseline by a third of the font size.\nfunction RowPanelHeadersSVG({\n model,\n theme,\n bandHeight,\n}: {\n model: MsaViewModel\n theme: Theme\n bandHeight: number\n}) {\n const { resolvedRowPanels, effectiveTreeAreaWidth, fontSize } = model\n const y = bandHeight - 4\n return resolvedRowPanels.length === 0 ? null : (\n <g id=\"rowpanel-headers\">\n {resolvedRowPanels.map(panel => {\n const across = headerRunsAcross(panel.width)\n const size = across ? fontSize : Math.min(fontSize, panel.width)\n const center = effectiveTreeAreaWidth + panel.offsetX + panel.width / 2\n const x = across ? center : center + size / 3\n const room = across ? panel.width : y - LEGEND_PAD\n return size < 5 ? null : (\n <text\n key={panel.id}\n x={x}\n y={y}\n {...(across\n ? { textAnchor: 'middle' }\n : { transform: `rotate(-90 ${x} ${y})` })}\n fontSize={size}\n fill={theme.palette.text.primary}\n >\n {\n ellipsize(t => measureTextCanvas(t, size), panel.header, room)\n .text\n }\n </text>\n )\n })}\n </g>\n )\n}\n\n// Each bracket's label in the gutter beside its bar, where the live view puts\n// it (see CladeLabels). The canvas layer draws the bar; a label longer than the\n// gutter or the clade is clipped, since text that overruns runs off the figure.\n// cladeGutterWidth sizes the gutter with the same measureTextCanvas, so a label\n// the gutter holds keeps every character.\nfunction CladeLabelsSVG({\n model,\n theme,\n offsetY,\n}: {\n model: MsaViewModel\n theme: Theme\n offsetY: number\n}) {\n const { fontSize } = model\n const boxes = cladeLabelBoxes(model)\n return boxes.length === 0 ? null : (\n <g id=\"clade-labels\">\n {boxes.map(box => {\n const top = box.top - offsetY\n const x = box.horizontal ? box.left : box.left + fontSize\n const y = box.horizontal\n ? top + box.height / 2 + fontSize / 3\n : top + box.height\n return (\n <text\n key={box.key}\n x={x}\n y={y}\n transform={box.horizontal ? undefined : `rotate(-90 ${x} ${y})`}\n fontSize={fontSize}\n fill={box.color ?? theme.palette.text.primary}\n >\n {\n ellipsize(\n t => measureTextCanvas(t, fontSize),\n box.label,\n box.horizontal ? box.width : box.height,\n ).text\n }\n </text>\n )\n })}\n </g>\n )\n}\n\n// the color keys drawn as a reserved column to the right of the alignment,\n// mirroring the on-screen AnnotationLegend overlay\nfunction LegendSVG({\n model,\n theme,\n width,\n}: {\n model: MsaViewModel\n theme: Theme\n width: number\n}) {\n const rows = legendRows(model.legends)\n const boxHeight = legendHeight(rows)\n // the column is capped at LEGEND_MAX_W, so a name too long for it has to be\n // clipped here -- text that overruns the reserved width runs off the figure\n const room = width - LEGEND_TEXT_X - LEGEND_PAD\n return (\n <g>\n <rect\n x={0}\n y={0}\n width={width - 4}\n height={boxHeight}\n fill={theme.palette.background.paper}\n stroke={theme.palette.divider}\n rx={2}\n />\n {rows.map((row, i) => {\n const y = LEGEND_PAD + i * LEGEND_ROW_H\n return (\n <g key={row.key}>\n {row.color ? (\n <rect\n x={LEGEND_PAD}\n y={y}\n width={LEGEND_SWATCH}\n height={LEGEND_SWATCH}\n fill={row.color}\n stroke={outlineColor(row.color)}\n />\n ) : null}\n <text\n x={row.color ? LEGEND_TEXT_X : LEGEND_PAD}\n y={y + LEGEND_SWATCH - 1}\n fontSize={LEGEND_FONT}\n fontWeight={row.color ? undefined : 'bold'}\n fill={theme.palette.text.primary}\n >\n {ellipsize(t => t.length * LEGEND_CHAR_W, row.label, room).text}\n </text>\n </g>\n )\n })}\n </g>\n )\n}\n\ntype LayerMap = Map<string, ContextType>\n\ninterface LayerProps {\n model: MsaViewModel\n theme: Theme\n layout: Layout\n Context: typeof ContextType\n layers: LayerMap\n}\n\nfunction CoreRendering({ model, theme, layout, Context, layers }: LayerProps) {\n const { contentHeight, offsetX, offsetY, msaAreaWidth } = layout\n const { effectiveTreeAreaWidth, rowPanelsWidth, id } = model\n\n const treeCtx = new Context(effectiveTreeAreaWidth, contentHeight)\n renderTreeCanvas({\n model,\n theme,\n ctx: treeCtx,\n offsetY,\n blockSizeYOverride: contentHeight,\n highResScaleFactorOverride: 1,\n })\n\n const rowPanelsCtx = rowPanelsWidth\n ? new Context(rowPanelsWidth, contentHeight)\n : undefined\n if (rowPanelsCtx) {\n renderRowPanels({\n model,\n theme,\n ctx: rowPanelsCtx,\n offsetY,\n blockSizeYOverride: contentHeight,\n highResScaleFactorOverride: 1,\n })\n }\n\n const raster = rasterBackground({ model, theme, layout })\n\n const msaCtx = new Context(msaAreaWidth, contentHeight)\n renderBoxFeatureCanvasBlock({\n model,\n theme,\n ctx: msaCtx,\n offsetX,\n offsetY,\n // the overlay culls bands to this width; without it the export falls back\n // to the on-screen 500px block size and drops every band past it\n blockSizeXOverride: msaAreaWidth,\n blockSizeYOverride: contentHeight,\n highResScaleFactorOverride: 1,\n })\n renderMSABlock({\n model,\n theme,\n ctx: msaCtx,\n offsetX,\n offsetY,\n blockSizeXOverride: msaAreaWidth,\n blockSizeYOverride: contentHeight,\n highResScaleFactorOverride: 1,\n rasterTiles: !!raster,\n })\n msaCtx.resetTransform()\n renderPersistentHighlights({\n ctx: msaCtx,\n model,\n theme,\n offsetX,\n offsetY,\n width: msaAreaWidth,\n height: contentHeight,\n })\n\n return (\n <>\n <ClipGroup\n panelId=\"tree-panel\"\n clipId={`tree-${id}`}\n width={effectiveTreeAreaWidth}\n height={contentHeight}\n ctx={treeCtx}\n layers={layers}\n />\n <CladeLabelsSVG model={model} theme={theme} offsetY={offsetY} />\n {rowPanelsCtx ? (\n <ClipGroup\n panelId=\"rowpanels-panel\"\n clipId={`rowpanels-${id}`}\n width={rowPanelsWidth}\n height={contentHeight}\n transform={`translate(${effectiveTreeAreaWidth} 0)`}\n ctx={rowPanelsCtx}\n layers={layers}\n />\n ) : null}\n <ClipGroup\n panelId=\"msa-panel\"\n clipId={`msa-${id}`}\n width={msaAreaWidth}\n height={contentHeight}\n transform={`translate(${effectiveTreeAreaWidth + rowPanelsWidth} 0)`}\n ctx={msaCtx}\n layers={layers}\n underlay={raster}\n />\n </>\n )\n}\n\n/**\n * The alignment background as a single <image>, wherever the live canvas\n * draws the raster.\n *\n * The vector path's <rect> per cell exhausts the heap on a real alignment. The\n * image is one pixel per cell, and image-rendering keeps the upscaled cell\n * edges hard, so it matches the rects pixel for pixel.\n */\nfunction rasterBackground({\n model,\n theme,\n layout,\n}: {\n model: MsaViewModel\n theme: Theme\n layout: Layout\n}) {\n const { contentHeight, offsetX, offsetY, msaAreaWidth } = layout\n const { colWidth, rowHeight } = model\n if (!rasterApplies(model)) {\n return undefined\n }\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: msaAreaWidth,\n colWidth,\n })\n const { yStart, yEnd } = visibleRowRange({\n model,\n offsetY,\n blockSizeY: contentHeight,\n })\n const numCols = Math.min(xEnd, model.numColumns) - xStart\n const numRows = Math.min(yEnd, model.numRows) - yStart\n const href = rasterImageHref({\n model,\n theme,\n col0: xStart,\n row0: yStart,\n numCols,\n numRows,\n })\n return href ? (\n <image\n href={href}\n x={xStart * colWidth - offsetX}\n y={yStart * rowHeight - offsetY}\n width={numCols * colWidth}\n height={numRows * rowHeight}\n imageRendering=\"pixelated\"\n preserveAspectRatio=\"none\"\n />\n ) : undefined\n}\n\nfunction TrackRendering({ model, theme, layout, Context, layers }: LayerProps) {\n const { trackHeight, offsetX, msaAreaWidth } = layout\n const { effectiveTreeAreaWidth, rowPanelsWidth, id } = model\n\n const ctx = new Context(msaAreaWidth, trackHeight)\n renderAllTracks({\n model,\n ctx,\n theme,\n offsetX,\n blockSizeXOverride: msaAreaWidth,\n highResScaleFactorOverride: 1,\n })\n\n return (\n <>\n <TrackLabelsSVG model={model} theme={theme} />\n <g transform={`translate(${effectiveTreeAreaWidth + rowPanelsWidth} 0)`}>\n <ClipGroup\n panelId=\"tracks-panel\"\n clipId={`tracks-${id}`}\n width={msaAreaWidth}\n height={trackHeight}\n ctx={ctx}\n layers={layers}\n />\n </g>\n </>\n )\n}\n\n// Each track's name in the tree-width column beside it, where the live view puts\n// it (see TrackLabel). Without these the figure has an unlabeled bar chart and\n// an unlabeled logo, and nothing says which is which.\nfunction TrackLabelsSVG({\n model,\n theme,\n}: {\n model: MsaViewModel\n theme: Theme\n}) {\n const { turnedOnTracks, effectiveTreeAreaWidth, fontSize, drawLabels } = model\n if (!drawLabels) {\n return null\n }\n const labels = turnedOnTracks.map((track, i) => {\n const { id, name, height } = track.model\n const size = Math.min(height, fontSize)\n const top = turnedOnTracks\n .slice(0, i)\n .reduce((acc, t) => acc + t.model.height, 0)\n // pinned to the top of the track, as the live view's flex row pins it\n return { id, name, size, baseline: top + size * 0.8 }\n })\n return (\n <>\n {labels.map(({ id, name, size, baseline }) => {\n return size < 5 ? null : (\n <text\n key={id}\n x={effectiveTreeAreaWidth - 4}\n y={baseline}\n fontSize={size}\n textAnchor=\"end\"\n fill={theme.palette.text.primary}\n >\n {name}\n </text>\n )\n })}\n </>\n )\n}\n\n// Clips a svgcanvas Context to its box and leaves a placeholder for renderToSvg\n// to splice the layer's own markup into. `underlay` draws beneath that markup,\n// inside the same clip, for the parts of a layer React emits directly.\n//\n// `panelId` names the spliced group in the output, the same name in every\n// export, so a figure can be taken apart in Illustrator or svgutils. `clipId`\n// carries the model id, which keeps two viewers on one page from colliding.\nfunction ClipGroup({\n panelId,\n clipId,\n width,\n height,\n transform,\n ctx,\n layers,\n underlay,\n}: {\n panelId: string\n clipId: string\n width: number\n height: number\n transform?: string\n ctx: ContextType\n layers: LayerMap\n underlay?: React.ReactNode\n}) {\n layers.set(panelId, ctx)\n return (\n <>\n <defs>\n <clipPath id={clipId}>\n <rect x={0} y={0} width={width} height={height} />\n </clipPath>\n </defs>\n <g clipPath={`url(#${clipId})`} transform={transform}>\n {underlay}\n <g data-layer={panelId} />\n </g>\n </>\n )\n}\n", "import type { MsaViewModel } from '../model.ts'\n\n// The half-open range of rows [yStart, yEnd) whose leaves intersect a block of\n// height blockSizeY at vertical offset offsetY, padded by one row on each side.\n// Y-axis counterpart to visibleColRange.\nexport function visibleRowRange({\n model,\n offsetY,\n blockSizeY,\n}: {\n model: MsaViewModel\n offsetY: number\n blockSizeY: number\n}) {\n const { rowHeight } = model\n return {\n yStart: Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight)),\n yEnd: Math.max(\n 0,\n Math.ceil((offsetY + blockSizeY + rowHeight) / rowHeight),\n ),\n }\n}\n\n// The leaves in that range.\nexport function getVisibleLeaves({\n model,\n offsetY,\n blockSizeY,\n}: {\n model: MsaViewModel\n offsetY: number\n blockSizeY: number\n}) {\n const { yStart, yEnd } = visibleRowRange({ model, offsetY, blockSizeY })\n return model.leaves.slice(yStart, yEnd)\n}\n", "import React from 'react'\n\nimport { scrollbarThumbFill } from '../DragHandle.tsx'\nimport { canvasHref, msaThumbnail } from '../msa/msaRaster.ts'\nimport { MINIMAP_BAR_HEIGHT, getMinimapLayout } from './minimapLayout.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { Theme } from '@mui/material'\n\n// The static counterpart to Minimap, for the SVG export. renderToSvg drives it\n// through renderToStaticMarkup, so it reads the model once and never re-renders\n// -- no observer wrapper.\nexport default function MinimapSVG({\n model,\n theme,\n}: {\n model: MsaViewModel\n theme: Theme\n}) {\n const { msaCanvasWidth } = model\n const { s, w, polygonPoints } = getMinimapLayout(model)\n // the same downsampled alignment the live minimap draws behind its thumb;\n // undefined wherever a canvas cannot be read back, leaving a bare outline\n const href = canvasHref(\n msaThumbnail({ model, theme, height: MINIMAP_BAR_HEIGHT }),\n )\n\n return (\n <>\n {href ? (\n <image\n href={href}\n x={0}\n y={0}\n width={msaCanvasWidth}\n height={MINIMAP_BAR_HEIGHT}\n preserveAspectRatio=\"none\"\n />\n ) : null}\n <rect\n x={0}\n y={0}\n width={msaCanvasWidth}\n height={MINIMAP_BAR_HEIGHT}\n stroke={theme.palette.text.secondary}\n fill=\"none\"\n />\n <rect\n x={Math.max(0, s)}\n y={0}\n width={w}\n height={MINIMAP_BAR_HEIGHT}\n fill={scrollbarThumbFill}\n stroke={theme.palette.text.secondary}\n />\n <g transform={`translate(0 ${MINIMAP_BAR_HEIGHT})`}>\n <polygon fill={scrollbarThumbFill} points={polygonPoints} />\n </g>\n </>\n )\n}\n", "import React, { useState } from 'react'\n\nimport { useTheme } from '@mui/material'\n\nimport { useDragScroll } from '../useDragScroll.ts'\n\nimport type { Theme } from '@mui/material'\n\nexport const scrollbarThumbFill = 'rgba(66,119,127,0.3)'\n\n// the model's resizeHandleWidth feeds the layout, so a divider keeps its drawn\n// width and widens its target with this much invisible margin each side\nconst hitSlop = 4\n\n// The scroll thumbs (minimap, vertical scrollbar) and the resize dividers are\n// one widget -- press, drag along an axis, report the pixel delta -- differing\n// only in the affordance they present, so the variant carries the whole\n// difference rather than a second copy of the drag wiring.\nconst variants: Record<\n 'thumb' | 'resizer',\n {\n fill: (theme: Theme) => string\n fillHovered: (theme: Theme) => string\n cursor: (axis: 'x' | 'y') => string\n position: React.CSSProperties['position']\n zIndex?: number\n }\n> = {\n thumb: {\n fill: () => scrollbarThumbFill,\n fillHovered: () => 'rgba(66,119,127,0.6)',\n cursor: () => 'pointer',\n position: 'absolute',\n zIndex: 100,\n },\n resizer: {\n fill: theme =>\n theme.palette.mode === 'dark'\n ? theme.palette.grey[800]\n : 'rgba(200,200,200)',\n fillHovered: theme =>\n theme.palette.mode === 'dark'\n ? theme.palette.grey[600]\n : 'rgba(150,150,150)',\n cursor: axis => (axis === 'x' ? 'ew-resize' : 'ns-resize'),\n position: 'relative',\n },\n}\n\n/**\n * A handle dragged along a single axis. `getStart` is read at mousedown and\n * handed back to `onDrag` alongside the pixel delta since, so a caller only\n * supplies the dimension it drives and where the handle sits.\n *\n * Memoize `onDrag` (useCallback) so the document listeners are not re-attached\n * on every render.\n */\nexport default function DragHandle({\n axis,\n variant,\n getStart,\n onDrag,\n style,\n}: {\n axis: 'x' | 'y'\n variant: keyof typeof variants\n getStart: () => number\n onDrag: (delta: number, startValue: number) => void\n style: React.CSSProperties\n}) {\n const theme = useTheme()\n const [hovered, setHovered] = useState(false)\n const { startDrag } = useDragScroll(axis, onDrag)\n const { fill, fillHovered, cursor, position, zIndex } = variants[variant]\n\n return (\n <div\n {...(variant === 'resizer' && {\n role: 'separator',\n 'aria-orientation': axis === 'x' ? 'vertical' : 'horizontal',\n })}\n onMouseEnter={() => {\n setHovered(true)\n }}\n onMouseLeave={() => {\n setHovered(false)\n }}\n onMouseDown={event => {\n startDrag(event, getStart())\n }}\n style={{\n position,\n zIndex,\n cursor: cursor(axis),\n background: hovered ? fillHovered(theme) : fill(theme),\n ...style,\n }}\n >\n {variant === 'resizer' ? (\n <div\n style={{\n position: 'absolute',\n zIndex: 101,\n ...(axis === 'x'\n ? { top: 0, bottom: 0, left: -hitSlop, right: -hitSlop }\n : { left: 0, right: 0, top: -hitSlop, bottom: -hitSlop }),\n }}\n />\n ) : null}\n </div>\n )\n}\n", "import { useEffect, useRef, useState } from 'react'\n\n/**\n * Tracks a mouse drag along a single axis and reports the scroll delta on each\n * animation frame. Shared by the horizontal Minimap and the VerticalScrollbar.\n *\n * `onScroll` is invoked with the pixel delta since drag start and the scroll\n * offset captured when the drag began. Memoize it (useCallback) so the document\n * listeners are not re-attached on every render.\n */\nexport function useDragScroll(\n axis: 'x' | 'y',\n onScroll: (delta: number, startScroll: number) => void,\n) {\n const scheduled = useRef(false)\n const [mouseDown, setMouseDown] = useState<{\n client: number\n startScroll: number\n }>()\n\n useEffect(() => {\n if (mouseDown !== undefined) {\n const { client: startClient, startScroll } = mouseDown\n function onMove(event: MouseEvent) {\n if (!scheduled.current) {\n scheduled.current = true\n requestAnimationFrame(() => {\n const client = axis === 'x' ? event.clientX : event.clientY\n onScroll(client - startClient, startScroll)\n scheduled.current = false\n })\n }\n }\n function onUp() {\n setMouseDown(undefined)\n }\n document.addEventListener('mousemove', onMove)\n document.addEventListener('mouseup', onUp)\n return () => {\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', onUp)\n }\n }\n }, [axis, onScroll, mouseDown])\n\n return {\n dragging: mouseDown !== undefined,\n startDrag: (event: React.MouseEvent, startScroll: number) => {\n setMouseDown({\n client: axis === 'x' ? event.clientX : event.clientY,\n startScroll,\n })\n },\n }\n}\n", "import type { MsaViewModel } from '../../model.ts'\n\n// Per-cell tile color for the active scheme, resolved once per block. Reading\n// only the active scheme's column table leaves the other per-column table\n// uncomputed.\nexport function tileColorFn(model: MsaViewModel) {\n const { dynamicColorSchemeName } = model\n if (dynamicColorSchemeName === 'clustalx_protein_dynamic') {\n const { colClustalX } = model\n return (col: number, letter: string) => colClustalX[col]![letter]\n }\n if (dynamicColorSchemeName === 'percent_identity_dynamic') {\n const { colConsensus } = model\n return (col: number, letter: string) => {\n const consensus = colConsensus[col]!\n return letter === consensus.letter ? consensus.color : undefined\n }\n }\n const { colorScheme } = model\n return (_col: number, letter: string) => colorScheme[letter]\n}\n\n// The table the active scheme colors from: a dynamic scheme's per-column table,\n// or the letter table of a static scheme or a `customColorScheme` map. A cache\n// of rendered colors keys on its identity plus the scheme name.\nexport function tileColorTable(model: MsaViewModel) {\n const { dynamicColorSchemeName } = model\n if (dynamicColorSchemeName === 'clustalx_protein_dynamic') {\n return model.colClustalX\n }\n if (dynamicColorSchemeName === 'percent_identity_dynamic') {\n return model.colConsensus\n }\n return model.colorScheme\n}\n", "import { tileColorFn, tileColorTable } from './tileColor.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { Theme } from '@mui/material'\n\n// One raster tile holds this many cells on a side. A tile costs ~10ms to build\n// and ~1MB to hold, and is then drawn at any zoom for ~1ms, so the cache only\n// has to be large enough to cover a screen without thrashing.\nexport const rasterTileSize = 512\nconst maxCachedTiles = 64\nconst maxThumbnailColumns = 2000\nconst maxColorCacheEntries = 4096\n\nexport type RasterCanvas = HTMLCanvasElement | OffscreenCanvas\ntype RasterCtx = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D\n\nexport interface RasterSpec {\n rowNames: string[]\n columns: Map<string, string>\n relativeTo: string | undefined\n colorAt: (col: number, letter: string) => string | undefined\n bg: string\n hover: string\n}\n\nconst littleEndian = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1\n\nfunction packRgba(r: number, g: number, b: number, a: number) {\n return littleEndian\n ? ((a << 24) | (b << 16) | (g << 8) | r) >>> 0\n : ((r << 24) | (g << 16) | (b << 8) | a) >>> 0\n}\n\nlet scratch: RasterCtx | null | undefined\nconst colorCache = new Map<string, number>()\n\n/**\n * CSS color string -> the packed pixel an ImageData holds for it. Painting a 1x1\n * canvas and reading it back parses hex, rgb(), hsl() and named colors; the\n * cache resolves each distinct color once per session.\n */\nexport function cssColorToPixel(css: string) {\n const hit = colorCache.get(css)\n if (hit !== undefined) {\n return hit\n }\n if (scratch === undefined) {\n scratch = makeRasterCanvas(1, 1)?.ctx ?? null\n }\n let packed = 0\n if (scratch) {\n scratch.clearRect(0, 0, 1, 1)\n scratch.fillStyle = css\n scratch.fillRect(0, 0, 1, 1)\n const [r = 0, g = 0, b = 0, a = 0] = scratch.getImageData(0, 0, 1, 1).data\n packed = packRgba(r, g, b, a)\n }\n if (colorCache.size >= maxColorCacheEntries) {\n colorCache.clear()\n }\n colorCache.set(css, packed)\n return packed\n}\n\nfunction cellPixelFn(spec: RasterSpec, toPixel: (css: string) => number) {\n const { columns, relativeTo, colorAt, bg, hover } = spec\n const bgPixel = toPixel(bg)\n const hoverPixel = toPixel(hover)\n const reference = relativeTo ? columns.get(relativeTo) : undefined\n return (name: string, col: number, letter: string) => {\n if (reference && name !== relativeTo && letter === reference[col]) {\n return hoverPixel\n }\n const color = colorAt(col, letter)\n return color === undefined ? bgPixel : toPixel(color)\n }\n}\n\n/**\n * Packs a rectangle of the alignment into one pixel per cell, in `rowNames`\n * order, ready to hand to putImageData. Cells past the end of a row, and rows\n * with no sequence, stay transparent, as in the per-cell painter.\n *\n * `colStep`/`rowStep` sample every nth cell, which fits a whole alignment into\n * the minimap's 12px bar. `colSpan`/`rowSpan` average each block of that many\n * cells into one pixel, so a zoom below a device pixel per column still shows\n * every column's color without blending neighbouring rows.\n */\nexport function rasterPixels({\n spec,\n col0,\n row0,\n width,\n height,\n colStep = 1,\n rowStep = 1,\n colSpan = 1,\n rowSpan = 1,\n toPixel = cssColorToPixel,\n out = new Uint32Array(width * height),\n}: {\n spec: RasterSpec\n col0: number\n row0: number\n width: number\n height: number\n colStep?: number\n rowStep?: number\n colSpan?: number\n rowSpan?: number\n toPixel?: (css: string) => number\n out?: Uint32Array\n}) {\n if (colSpan > 1 || rowSpan > 1) {\n averagePixels({\n spec,\n col0,\n row0,\n width,\n height,\n colSpan,\n rowSpan,\n toPixel,\n out,\n })\n return out\n }\n const { rowNames, columns } = spec\n const cellPixel = cellPixelFn(spec, toPixel)\n\n for (let r = 0; r < height; r++) {\n const name = rowNames[row0 + r * rowStep]\n if (name === undefined) {\n break\n }\n const str = columns.get(name)\n if (!str) {\n continue\n }\n const base = r * width\n for (let c = 0; c < width; c++) {\n const col = col0 + c * colStep\n const letter = str[col]\n if (letter === undefined) {\n break\n }\n out[base + c] = cellPixel(name, col, letter)\n }\n }\n return out\n}\n\nfunction averagePixels({\n spec,\n col0,\n row0,\n width,\n height,\n colSpan,\n rowSpan,\n toPixel,\n out,\n}: {\n spec: RasterSpec\n col0: number\n row0: number\n width: number\n height: number\n colSpan: number\n rowSpan: number\n toPixel: (css: string) => number\n out: Uint32Array\n}) {\n const { rowNames, columns } = spec\n const cellPixel = cellPixelFn(spec, toPixel)\n const cells = colSpan * rowSpan\n const rShift = littleEndian ? 0 : 24\n const gShift = littleEndian ? 8 : 16\n const bShift = littleEndian ? 16 : 8\n const aShift = littleEndian ? 24 : 0\n const names: string[] = []\n const strs: string[] = []\n\n for (let r = 0; r < height; r++) {\n names.length = 0\n strs.length = 0\n for (let dr = 0; dr < rowSpan; dr++) {\n const name = rowNames[row0 + r * rowSpan + dr]\n const str = name === undefined ? undefined : columns.get(name)\n if (name !== undefined && str) {\n names.push(name)\n strs.push(str)\n }\n }\n const base = r * width\n for (let c = 0; c < width; c++) {\n // premultiplied, so a cell past the end of a row dilutes the alpha of its\n // pixel rather than darkening its color\n let sumR = 0\n let sumG = 0\n let sumB = 0\n let sumA = 0\n for (let i = 0; i < strs.length; i++) {\n const str = strs[i]!\n const name = names[i]!\n for (let dc = 0; dc < colSpan; dc++) {\n const col = col0 + c * colSpan + dc\n const letter = str[col]\n if (letter === undefined) {\n break\n }\n const p = cellPixel(name, col, letter)\n const a = (p >>> aShift) & 255\n sumR += ((p >>> rShift) & 255) * a\n sumG += ((p >>> gShift) & 255) * a\n sumB += ((p >>> bShift) & 255) * a\n sumA += a\n }\n }\n out[base + c] =\n sumA === 0\n ? 0\n : packRgba(\n Math.round(sumR / sumA),\n Math.round(sumG / sumA),\n Math.round(sumB / sumA),\n Math.round(sumA / cells),\n )\n }\n }\n}\n\nfunction usableRasterCtx(ctx: unknown): ctx is RasterCtx {\n const c = ctx as Record<string, unknown> | null\n return (\n !!c &&\n typeof c.createImageData === 'function' &&\n typeof c.putImageData === 'function' &&\n typeof c.getImageData === 'function' &&\n typeof c.clearRect === 'function' &&\n typeof c.fillRect === 'function'\n )\n}\n\n/**\n * A canvas off the page, an OffscreenCanvas where there is one, with its 2d\n * context, or undefined where the context fails `usable` (jsdom has none).\n */\nexport function makeOffscreenCanvas<Ctx>(\n width: number,\n height: number,\n usable: (ctx: unknown) => ctx is Ctx,\n settings?: CanvasRenderingContext2DSettings,\n) {\n const canvas =\n typeof OffscreenCanvas !== 'undefined'\n ? new OffscreenCanvas(width, height)\n : typeof document !== 'undefined'\n ? Object.assign(document.createElement('canvas'), { width, height })\n : undefined\n const ctx = canvas?.getContext('2d', settings)\n return usable(ctx) ? { canvas: canvas as RasterCanvas, ctx } : undefined\n}\n\nfunction makeRasterCanvas(width: number, height: number) {\n return makeOffscreenCanvas(width, height, usableRasterCtx, {\n willReadFrequently: true,\n })\n}\n\nfunction paint(\n width: number,\n height: number,\n fill: (out: Uint32Array) => void,\n) {\n const made = makeRasterCanvas(width, height)\n if (!made) {\n return undefined\n }\n const image = made.ctx.createImageData(width, height)\n fill(new Uint32Array(image.data.buffer))\n made.ctx.putImageData(image, 0, 0)\n return made.canvas\n}\n\nlet supported: boolean | undefined\n\n/**\n * Whether the alignment background comes from the raster: true with\n * background coloring on, the domain overlay off, and a 2d context that reads\n * back, which jsdom lacks. renderMSABlock paints each cell otherwise.\n */\nexport function rasterApplies(\n model: Pick<MsaViewModel, 'actuallyShowDomains' | 'bgColor'>,\n) {\n supported ??= !!makeRasterCanvas(1, 1)\n return !model.actuallyShowDomains && model.bgColor && supported\n}\n\ninterface RasterCache {\n keys: unknown[]\n spec: RasterSpec\n numColumns: number\n numRows: number\n tiles: Map<string, RasterCanvas>\n thumbnail?: { height: number; canvas: RasterCanvas | undefined }\n}\n\nconst caches = new WeakMap<object, RasterCache>()\n\n// Everything a cell's color depends on; a change to any of them starts a fresh\n// cache.\nfunction rasterKeys(model: MsaViewModel, theme: Theme) {\n return [\n model.columns,\n model.leaves,\n model.colorSchemeName,\n model.customColorScheme,\n tileColorTable(model),\n model.relativeTo,\n theme.palette.action.hover,\n theme.palette.background.default,\n ]\n}\n\nfunction getCache(model: MsaViewModel, theme: Theme) {\n const keys = rasterKeys(model, theme)\n const prev = caches.get(model)\n if (prev && keys.every((key, i) => key === prev.keys[i])) {\n return prev\n }\n const next: RasterCache = {\n keys,\n spec: {\n rowNames: model.leaves.map(node => node.data.name),\n columns: model.columns,\n relativeTo: model.relativeTo,\n colorAt: tileColorFn(model),\n bg: theme.palette.background.default,\n hover: theme.palette.action.hover,\n },\n numColumns: model.numColumns,\n numRows: model.numRows,\n tiles: new Map(),\n }\n caches.set(model, next)\n return next\n}\n\n// Cells averaged into one tile pixel along an axis: the smallest power of two\n// that brings a pixel back to at least one device pixel. Powers of two keep the\n// number of distinct tile sets a zoom sweep builds to a handful.\nfunction cellsPerPixel(devicePixelsPerCell: number) {\n return devicePixelsPerCell >= 1\n ? 1\n : 2 ** Math.ceil(Math.log2(1 / devicePixelsPerCell))\n}\n\nfunction getTile({\n cache,\n tileRow,\n tileCol,\n colSpan,\n rowSpan,\n}: {\n cache: RasterCache\n tileRow: number\n tileCol: number\n colSpan: number\n rowSpan: number\n}) {\n const key = `${colSpan}_${rowSpan}_${tileRow}_${tileCol}`\n const hit = cache.tiles.get(key)\n if (hit) {\n // re-inserting makes this the newest entry: a Map iterates in insertion\n // order, so its first key is the least recently used one\n cache.tiles.delete(key)\n cache.tiles.set(key, hit)\n return hit\n }\n const col0 = tileCol * rasterTileSize * colSpan\n const row0 = tileRow * rasterTileSize * rowSpan\n const width = Math.min(\n rasterTileSize,\n Math.ceil((cache.numColumns - col0) / colSpan),\n )\n const height = Math.min(\n rasterTileSize,\n Math.ceil((cache.numRows - row0) / rowSpan),\n )\n if (width <= 0 || height <= 0) {\n return undefined\n }\n const canvas = paint(width, height, out => {\n rasterPixels({\n spec: cache.spec,\n col0,\n row0,\n width,\n height,\n colSpan,\n rowSpan,\n out,\n })\n })\n if (!canvas) {\n return undefined\n }\n cache.tiles.set(key, canvas)\n for (const stale of cache.tiles.keys()) {\n if (cache.tiles.size <= maxCachedTiles) {\n break\n }\n cache.tiles.delete(stale)\n }\n return canvas\n}\n\n/**\n * Paints the alignment background of one MSA block from cached\n * one-pixel-per-cell tiles. The tiles do not depend on the zoom level, so a zoom\n * frame costs a handful of drawImage calls. A fillRect per visible cell measured\n * 885ms per block at the minimum column width.\n *\n * Below a device pixel per cell the tiles average cells together, per axis.\n * The browser's image smoothing blurs both axes, which turns every row\n * boundary into a gradient at fit-to-width, where only the columns are narrow.\n */\nexport function drawMsaRaster({\n ctx,\n model,\n theme,\n offsetX,\n offsetY,\n}: {\n ctx: CanvasRenderingContext2D\n model: MsaViewModel\n theme: Theme\n offsetX: number\n offsetY: number\n}) {\n const { colWidth, rowHeight, blockSize, highResScaleFactor } = model\n const cache = getCache(model, theme)\n const colSpan = cellsPerPixel(colWidth * highResScaleFactor)\n const rowSpan = cellsPerPixel(rowHeight * highResScaleFactor)\n\n ctx.resetTransform()\n ctx.scale(highResScaleFactor, highResScaleFactor)\n ctx.translate(-offsetX, -offsetY)\n ctx.imageSmoothingEnabled = false\n\n const pixelWidth = colWidth * colSpan\n const pixelHeight = rowHeight * rowSpan\n const tileWidth = rasterTileSize * pixelWidth\n const tileHeight = rasterTileSize * pixelHeight\n const firstCol = Math.max(0, Math.floor(offsetX / tileWidth))\n const lastCol = Math.floor((offsetX + blockSize) / tileWidth)\n const firstRow = Math.max(0, Math.floor(offsetY / tileHeight))\n const lastRow = Math.floor((offsetY + blockSize) / tileHeight)\n\n for (let tileRow = firstRow; tileRow <= lastRow; tileRow++) {\n for (let tileCol = firstCol; tileCol <= lastCol; tileCol++) {\n const tile = getTile({ cache, tileRow, tileCol, colSpan, rowSpan })\n if (tile) {\n ctx.drawImage(\n tile,\n 0,\n 0,\n tile.width,\n tile.height,\n tileCol * tileWidth,\n tileRow * tileHeight,\n tile.width * pixelWidth,\n tile.height * pixelHeight,\n )\n }\n }\n }\n ctx.resetTransform()\n ctx.imageSmoothingEnabled = true\n}\n\n/**\n * A raster canvas as a PNG data URI, for embedding in the SVG export.\n *\n * toDataURL is the synchronous read-back. The DOM canvas and a headless node\n * canvas have it; a browser OffscreenCanvas, which the tile and thumbnail\n * caches hold where it exists, is copied onto a DOM canvas first. Returns\n * undefined where read-back is unavailable (jsdom), and the caller then draws\n * in vector.\n */\nexport function canvasHref(canvas: RasterCanvas | undefined) {\n if (!canvas) {\n return undefined\n }\n try {\n if ('toDataURL' in canvas && typeof canvas.toDataURL === 'function') {\n return canvas.toDataURL('image/png')\n }\n if (typeof document === 'undefined') {\n return undefined\n }\n const out = document.createElement('canvas')\n out.width = canvas.width\n out.height = canvas.height\n const ctx = out.getContext('2d')\n if (typeof ctx?.drawImage !== 'function') {\n return undefined\n }\n ctx.drawImage(canvas, 0, 0)\n return out.toDataURL('image/png')\n } catch {\n return undefined\n }\n}\n\n// A canvas much past this many pixels fails to allocate, and the browser's\n// per-side limit is lower still, so a larger raster averages down per axis and\n// is drawn across the same rectangle. An alignment that hits the limit on\n// columns alone keeps every row.\nconst maxImagePixels = 64e6\nconst maxImageSide = 16384\n\n/**\n * The alignment rectangle [col0, col0+numCols) x [row0, row0+numRows) as a PNG\n * data URI, for the SVG export.\n *\n * SVG has no blit, so the export draws the whole background as one <image>. The\n * vector path emits a <rect> per cell, and a 200x500 alignment exhausts the\n * heap building them.\n *\n * Returns undefined where a canvas cannot be read back (jsdom), and the caller\n * then keeps the per-cell path.\n */\nexport function rasterImageHref({\n model,\n theme,\n col0,\n row0,\n numCols,\n numRows,\n}: {\n model: MsaViewModel\n theme: Theme\n col0: number\n row0: number\n numCols: number\n numRows: number\n}) {\n if (numCols <= 0 || numRows <= 0 || typeof document === 'undefined') {\n return undefined\n }\n const cache = getCache(model, theme)\n let colSpan = 1\n let rowSpan = 1\n while (Math.ceil(numCols / colSpan) > maxImageSide) {\n colSpan *= 2\n }\n while (Math.ceil(numRows / rowSpan) > maxImageSide) {\n rowSpan *= 2\n }\n while (\n Math.ceil(numCols / colSpan) * Math.ceil(numRows / rowSpan) >\n maxImagePixels\n ) {\n if (numCols / colSpan >= numRows / rowSpan) {\n colSpan *= 2\n } else {\n rowSpan *= 2\n }\n }\n const width = Math.ceil(numCols / colSpan)\n const height = Math.ceil(numRows / rowSpan)\n\n return canvasHref(\n paint(width, height, out => {\n rasterPixels({\n spec: cache.spec,\n col0,\n row0,\n width,\n height,\n colSpan,\n rowSpan,\n out,\n })\n }),\n )\n}\n\n/**\n * The whole alignment sampled down to a strip behind the minimap thumb, cached\n * with the block tiles since the same keys invalidate both.\n */\nexport function msaThumbnail({\n model,\n theme,\n height,\n}: {\n model: MsaViewModel\n theme: Theme\n height: number\n}) {\n const cache = getCache(model, theme)\n const { numColumns, numRows } = cache\n if (numColumns <= 0 || numRows <= 0) {\n return undefined\n }\n // keyed on the requested height as well as the cache: rowStep is derived from\n // it, so a thumbnail built for a different bar height is the wrong sampling\n if (cache.thumbnail?.height !== height) {\n const colStep = Math.max(1, Math.ceil(numColumns / maxThumbnailColumns))\n const rowStep = Math.max(1, Math.ceil(numRows / height))\n const w = Math.ceil(numColumns / colStep)\n const h = Math.ceil(numRows / rowStep)\n cache.thumbnail = {\n height,\n canvas: paint(w, h, out => {\n rasterPixels({\n spec: cache.spec,\n col0: 0,\n row0: 0,\n width: w,\n height: h,\n colStep,\n rowStep,\n out,\n })\n }),\n }\n }\n return cache.thumbnail.canvas\n}\n", "import type { MsaViewModel } from '../../model.ts'\n\nexport const MINIMAP_BAR_HEIGHT = 12\n\n/**\n * Viewport-rectangle and trapezoid geometry for the minimap, shared by the\n * interactive Minimap and the static MinimapSVG. Both span the alignment canvas\n * exactly -- a minimap drawn a different width than the columns it maps puts\n * its viewport rectangle over the wrong ones.\n */\nexport function getMinimapLayout(model: MsaViewModel) {\n const { scrollX, minimapHeight, totalWidth, msaCanvasWidth } = model\n const unit = totalWidth > 0 ? msaCanvasWidth / totalWidth : 0\n const s = -scrollX * unit\n // the rectangle marks the visible slice of the alignment, so it can never be\n // wider than the bar itself\n const w = Math.min(msaCanvasWidth, Math.max(msaCanvasWidth * unit, 20))\n const polygonHeight = minimapHeight - MINIMAP_BAR_HEIGHT\n const polygonPoints = `${s + w},0 ${s},0 0,${polygonHeight} ${msaCanvasWidth},${polygonHeight}`\n return { unit, s, w, polygonHeight, polygonPoints }\n}\n", "for(var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return\"string\"==typeof r?r.length>0:\"number\"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},u=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},e=function(r){return(r=isFinite(r)?r%360:0)<0?r+360:r},o=function(r,t){return void 0===t&&(t=0),n(r,t)%360},a=function(r){return{r:u(r.r,0,255),g:u(r.g,0,255),b:u(r.b,0,255),a:u(r.a)}},i=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},s=/^#([0-9a-f]{3,8})$/i,d=function(r,t){var n=r.charCodeAt(t);return(15&n)+9*(n>>6)},h=function(r,t){return d(r,t)<<4|d(r,t+1)},b=[],f=0;f<256;f++)b.push((f<16?\"0\":\"\")+f.toString(16));var g=function(r){return b[u(r,0,255)]},c=function(r){var t=r.r,n=r.g,u=r.b,e=r.a,o=Math.max(t,n,u),a=o-Math.min(t,n,u),i=a?o===t?(n-u)/a:o===n?2+(u-t)/a:4+(t-n)/a:0;return{h:60*(i<0?i+6:i),s:o?a/o*100:0,v:o/255*100,a:e}},v=function(r){var t=r.h,n=r.s,u=r.v,e=r.a;t=t/360*6,n/=100,u/=100;var o=Math.floor(t),a=u*(1-n),i=u*(1-(t-o)*n),s=u*(1-(1-t+o)*n),d=o%6;return{r:255*[u,i,a,a,s,u][d],g:255*[s,u,u,i,a,a][d],b:255*[a,a,s,u,u,i][d],a:e}},l=function(r){return{h:e(r.h),s:u(r.s,0,100),l:u(r.l,0,100),a:u(r.a)}},p=function(r){return{h:o(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},m=function(r){return v((n=(t=r).s,{h:t.h,s:(n*=((u=t.l)<50?u:100-u)/100)>0?2*n/(u+n)*100:0,v:u+n,a:t.a}));var t,n,u},y=function(r){return{h:(t=c(r)).h,s:(e=(200-(n=t.s))*(u=t.v)/100)>0&&e<200?n*u/100/(e<=100?e:200-e)*100:0,l:e/2,a:t.a};var t,n,u,e},N=/^hsla?\\(\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(deg|rad|grad|turn)?\\s*,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))%\\s*,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))%\\s*(?:,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*)?\\)$/i,x=/^hsla?\\(\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(deg|rad|grad|turn)?\\s+([+-]?(?:\\d*\\.\\d+|\\d+))%\\s+([+-]?(?:\\d*\\.\\d+|\\d+))%\\s*(?:\\/\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*)?\\)$/i,M=/^rgba?\\(\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*(?:,\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*)?\\)$/i,H=/^rgba?\\(\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s+([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s+([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*(?:\\/\\s*([+-]?(?:\\d*\\.\\d+|\\d+))(%)?\\s*)?\\)$/i,$={string:[[function(r){if(!s.test(r))return null;var t=r.length;return t<=5?{r:17*d(r,1),g:17*d(r,2),b:17*d(r,3),a:5===t?n(17*d(r,4)/255,2):1}:7===t||9===t?{r:h(r,1),g:h(r,3),b:h(r,5),a:9===t?n(h(r,7)/255,2):1}:null},\"hex\"],[function(r){var t=M.exec(r)||H.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},\"rgb\"],[function(t){var n=N.exec(t)||x.exec(t);if(!n)return null;var u,e,o=l({h:(u=n[1],e=n[2],void 0===e&&(e=\"deg\"),Number(u)*(r[e]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return m(o)},\"hsl\"]],object:[[function(r){var n=r.r,u=r.g,e=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(u)&&t(e)?a({r:Number(n),g:Number(u),b:Number(e),a:Number(i)}):null},\"rgb\"],[function(r){var n=r.h,u=r.s,e=r.l,o=r.a,a=void 0===o?1:o;if(!t(n)||!t(u)||!t(e))return null;var i=l({h:Number(n),s:Number(u),l:Number(e),a:Number(a)});return m(i)},\"hsl\"],[function(r){var n=r.h,o=r.s,a=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(o)||!t(a))return null;var d=function(r){return{h:e(r.h),s:u(r.s,0,100),v:u(r.v,0,100),a:u(r.a)}}({h:Number(n),s:Number(o),v:Number(a),a:Number(s)});return v(d)},\"hsv\"]]},j=function(r,t){for(var n=0;n<t.length;n++){var u=t[n][0](r);if(u)return[u,t[n][1]]}return[null,void 0]},w=function(r){return\"string\"==typeof r?j(r.trim(),$.string):\"object\"==typeof r&&null!==r?j(r,$.object):[null,void 0]},S=function(r){return w(r)[1]},k=function(r,t){var n=y(r);return{h:n.h,s:u(n.s+100*t,0,100),l:n.l,a:n.a}},E=function(r){return(299*r.r+587*r.g+114*r.b)/1e3/255},R=function(r,t){var n=y(r);return{h:n.h,s:n.s,l:u(n.l+100*t,0,100),a:n.a}},q=function(){function r(r){this.parsed=w(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1}}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(E(this.rgba),2)},r.prototype.isDark=function(){return E(this.rgba)<.5},r.prototype.isLight=function(){return E(this.rgba)>=.5},r.prototype.toHex=function(){return r=i(this.rgba),t=r.r,u=r.g,e=r.b,a=(o=r.a)<1?g(n(255*o)):\"\",\"#\"+g(t)+g(u)+g(e)+a;var r,t,u,e,o,a},r.prototype.toRgb=function(){return i(this.rgba)},r.prototype.toRgbString=function(){return r=i(this.rgba),t=r.r,n=r.g,u=r.b,(e=r.a)<1?\"rgba(\"+t+\", \"+n+\", \"+u+\", \"+e+\")\":\"rgb(\"+t+\", \"+n+\", \"+u+\")\";var r,t,n,u,e},r.prototype.toHsl=function(){return p(y(this.rgba))},r.prototype.toHslString=function(){return r=p(y(this.rgba)),t=r.h,n=r.s,u=r.l,(e=r.a)<1?\"hsla(\"+t+\", \"+n+\"%, \"+u+\"%, \"+e+\")\":\"hsl(\"+t+\", \"+n+\"%, \"+u+\"%)\";var r,t,n,u,e},r.prototype.toHsv=function(){return r=c(this.rgba),{h:o(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return A({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),A(k(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),A(k(this.rgba,-r))},r.prototype.grayscale=function(){return A(k(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),A(R(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),A(R(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(y(this.rgba).h+r)},r.prototype.alpha=function(r){return\"number\"==typeof r?A({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=y(this.rgba);return\"number\"==typeof r?A({h:r,s:t.s,l:t.l,a:t.a}):o(t.h)},r.prototype.isEqual=function(r){return this.toHex()===A(r).toHex()},r}(),A=function(r){return r instanceof q?r:new q(r)},C=[],D=function(r){r.forEach(function(r){C.indexOf(r)<0&&(r(q,$),C.push(r))})},F=function(){return new q({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})};export{q as Colord,A as colord,D as extend,S as getFormat,F as random};\n", "var o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},t=function(t){return.2126*o(t.r)+.7152*o(t.g)+.0722*o(t.b)},r=function(o){o.prototype.luminance=function(){return o=t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r=\"#FFF\");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=t(e),d=t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o=\"#FFF\"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?\"normal\":i,\"AAA\"===(a=void 0===(n=r.level)?\"AA\":n)&&\"normal\"===e?7:\"AA\"===a&&\"large\"===e?3:4.5);var r,n,a,i,e}};export{r as default};\n", "var e=function(e,f){var a={white:\"#ffffff\",bisque:\"#ffe4c4\",blue:\"#0000ff\",cadetblue:\"#5f9ea0\",chartreuse:\"#7fff00\",chocolate:\"#d2691e\",coral:\"#ff7f50\",antiquewhite:\"#faebd7\",aqua:\"#00ffff\",azure:\"#f0ffff\",whitesmoke:\"#f5f5f5\",papayawhip:\"#ffefd5\",plum:\"#dda0dd\",blanchedalmond:\"#ffebcd\",black:\"#000000\",gold:\"#ffd700\",goldenrod:\"#daa520\",gainsboro:\"#dcdcdc\",cornsilk:\"#fff8dc\",cornflowerblue:\"#6495ed\",burlywood:\"#deb887\",aquamarine:\"#7fffd4\",beige:\"#f5f5dc\",crimson:\"#dc143c\",cyan:\"#00ffff\",darkblue:\"#00008b\",darkcyan:\"#008b8b\",darkgoldenrod:\"#b8860b\",darkkhaki:\"#bdb76b\",darkgray:\"#a9a9a9\",darkgreen:\"#006400\",darkgrey:\"#a9a9a9\",peachpuff:\"#ffdab9\",darkmagenta:\"#8b008b\",darkred:\"#8b0000\",darkorchid:\"#9932cc\",darkorange:\"#ff8c00\",darkslateblue:\"#483d8b\",gray:\"#808080\",darkslategray:\"#2f4f4f\",darkslategrey:\"#2f4f4f\",deeppink:\"#ff1493\",deepskyblue:\"#00bfff\",wheat:\"#f5deb3\",firebrick:\"#b22222\",floralwhite:\"#fffaf0\",ghostwhite:\"#f8f8ff\",darkviolet:\"#9400d3\",magenta:\"#ff00ff\",green:\"#008000\",dodgerblue:\"#1e90ff\",grey:\"#808080\",honeydew:\"#f0fff0\",hotpink:\"#ff69b4\",blueviolet:\"#8a2be2\",forestgreen:\"#228b22\",lawngreen:\"#7cfc00\",indianred:\"#cd5c5c\",indigo:\"#4b0082\",fuchsia:\"#ff00ff\",brown:\"#a52a2a\",maroon:\"#800000\",mediumblue:\"#0000cd\",lightcoral:\"#f08080\",darkturquoise:\"#00ced1\",lightcyan:\"#e0ffff\",ivory:\"#fffff0\",lightyellow:\"#ffffe0\",lightsalmon:\"#ffa07a\",lightseagreen:\"#20b2aa\",linen:\"#faf0e6\",mediumaquamarine:\"#66cdaa\",lemonchiffon:\"#fffacd\",lime:\"#00ff00\",khaki:\"#f0e68c\",mediumseagreen:\"#3cb371\",limegreen:\"#32cd32\",mediumspringgreen:\"#00fa9a\",lightskyblue:\"#87cefa\",lightblue:\"#add8e6\",midnightblue:\"#191970\",lightpink:\"#ffb6c1\",mistyrose:\"#ffe4e1\",moccasin:\"#ffe4b5\",mintcream:\"#f5fffa\",lightslategray:\"#778899\",lightslategrey:\"#778899\",navajowhite:\"#ffdead\",navy:\"#000080\",mediumvioletred:\"#c71585\",powderblue:\"#b0e0e6\",palegoldenrod:\"#eee8aa\",oldlace:\"#fdf5e6\",paleturquoise:\"#afeeee\",mediumturquoise:\"#48d1cc\",mediumorchid:\"#ba55d3\",rebeccapurple:\"#663399\",lightsteelblue:\"#b0c4de\",mediumslateblue:\"#7b68ee\",thistle:\"#d8bfd8\",tan:\"#d2b48c\",orchid:\"#da70d6\",mediumpurple:\"#9370db\",purple:\"#800080\",pink:\"#ffc0cb\",skyblue:\"#87ceeb\",springgreen:\"#00ff7f\",palegreen:\"#98fb98\",red:\"#ff0000\",yellow:\"#ffff00\",slateblue:\"#6a5acd\",lavenderblush:\"#fff0f5\",peru:\"#cd853f\",palevioletred:\"#db7093\",violet:\"#ee82ee\",teal:\"#008080\",slategray:\"#708090\",slategrey:\"#708090\",aliceblue:\"#f0f8ff\",darkseagreen:\"#8fbc8f\",darkolivegreen:\"#556b2f\",greenyellow:\"#adff2f\",seagreen:\"#2e8b57\",seashell:\"#fff5ee\",tomato:\"#ff6347\",silver:\"#c0c0c0\",sienna:\"#a0522d\",lavender:\"#e6e6fa\",lightgreen:\"#90ee90\",orange:\"#ffa500\",orangered:\"#ff4500\",steelblue:\"#4682b4\",royalblue:\"#4169e1\",turquoise:\"#40e0d0\",yellowgreen:\"#9acd32\",salmon:\"#fa8072\",saddlebrown:\"#8b4513\",sandybrown:\"#f4a460\",rosybrown:\"#bc8f8f\",darksalmon:\"#e9967a\",lightgoldenrodyellow:\"#fafad2\",snow:\"#fffafa\",lightgrey:\"#d3d3d3\",lightgray:\"#d3d3d3\",dimgray:\"#696969\",dimgrey:\"#696969\",olivedrab:\"#6b8e23\",olive:\"#808000\"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return\"transparent\";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b=\"black\";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g)}return b}};f.string.push([function(f){var r=f.toLowerCase(),d=\"transparent\"===r?\"#0000\":a[r];return d?new e(d).toRgb():null},\"name\"])};export{e as default};\n", "import { colord, extend } from 'colord'\nimport a11yPlugin from 'colord/plugins/a11y'\nimport namesPlugin from 'colord/plugins/names'\n\nimport type { Theme } from '@mui/material'\n\nextend([namesPlugin, a11yPlugin])\n\nconst contrastAdjustCache = new Map<string, string>()\n\n// Adjusts a background-tile color until it meets WCAG AA (4.5:1) contrast\n// against `bg`, so it can be used as letter text in letter-color mode.\n// Darkens on light backgrounds, lightens on dark backgrounds.\nexport function adjustColorForContrast(color: string, bg: string): string {\n const cacheKey = `${color}|${bg}`\n const cached = contrastAdjustCache.get(cacheKey)\n if (cached !== undefined) {\n return cached\n }\n let c = colord(color)\n if (!c.isReadable(bg)) {\n const bgIsDark = colord(bg).luminance() < 0.5\n for (let i = 0; i < 40 && !c.isReadable(bg); i++) {\n c = bgIsDark ? c.lighten(0.05) : c.darken(0.05)\n }\n }\n const result = c.toHex()\n contrastAdjustCache.set(cacheKey, result)\n return result\n}\n\n// a wash over the alignment or the tree: a color carrying its own alpha draws\n// at that alpha, and one with none takes `alpha` so the marks under it stay\n// readable\nexport function withAlpha(color: string, alpha: number) {\n const parsed = colord(color)\n return parsed.alpha() === 1 ? parsed.alpha(alpha).toRgbString() : color\n}\n\nexport function outlineColor(fill: string) {\n return colord(fill).darken(0.1).toHex()\n}\n\nexport function transform<T>(\n obj: Record<string, T>,\n cb: (arg0: [string, T]) => [string, T],\n) {\n return Object.fromEntries(Object.entries(obj).map(cb))\n}\n\nconst contrastTextCaches = new WeakMap<Theme, Map<string, string>>()\n\n/**\n * Readable letter color over a given cell color, memoized per theme.\n *\n * Keyed by cell color, since a dynamic scheme has no letter->color table; this\n * covers static schemes and a track's own `colors` too. An uncolored cell gets\n * the theme's text color, which stays readable in the dark theme.\n */\nexport function contrastTextFn(theme: Theme) {\n let cache = contrastTextCaches.get(theme)\n if (!cache) {\n cache = new Map()\n contrastTextCaches.set(theme, cache)\n }\n const fallback = theme.palette.text.primary\n return (color: string | undefined) => {\n if (!color) {\n return fallback\n }\n const hit = cache.get(color)\n if (hit !== undefined) {\n return hit\n }\n const out = theme.palette.getContrastText(colord(color).toHex())\n cache.set(color, out)\n return out\n }\n}\n\nexport function dropBlanks<T>(blanks: number[], arr: T[]) {\n if (blanks.length === 0) {\n return arr\n }\n const set = new Set(blanks)\n return arr.filter((_, i) => !set.has(i))\n}\n\nexport function skipBlanks(blanks: number[], str: string) {\n if (blanks.length === 0) {\n return str\n }\n const chunks = []\n let lastEnd = 0\n for (const blankIdx of blanks) {\n if (blankIdx > lastEnd) {\n chunks.push(str.slice(lastEnd, blankIdx))\n }\n lastEnd = blankIdx + 1\n }\n if (lastEnd < str.length) {\n chunks.push(str.slice(lastEnd))\n }\n return chunks.join('')\n}\n\nexport function computeRowInsertions(blanks: number[], seq: string) {\n const insertions: { pos: number; letters: string }[] = []\n const blanksLen = blanks.length\n let displayPos = 0\n let blankIdx = 0\n let currentInsertPos = -1\n let letterChars: string[] = []\n for (let i = 0; i < seq.length; i++) {\n if (blankIdx < blanksLen && blanks[blankIdx] === i) {\n // bit trick: (code - 45) >>> 0 <= 1 checks for '-' (45) or '.' (46)\n if (!((seq.charCodeAt(i) - 45) >>> 0 <= 1)) {\n if (currentInsertPos === displayPos) {\n letterChars.push(seq[i]!)\n } else {\n if (letterChars.length > 0) {\n insertions.push({\n pos: currentInsertPos,\n letters: letterChars.join(''),\n })\n }\n currentInsertPos = displayPos\n letterChars = [seq[i]!]\n }\n }\n blankIdx++\n } else {\n displayPos++\n }\n }\n if (letterChars.length > 0) {\n insertions.push({ pos: currentInsertPos, letters: letterChars.join('') })\n }\n return insertions\n}\n\nexport function len(a: { end: number; start: number }) {\n return a.end - a.start\n}\n", "import { minFeatureLabelHeight } from '../../constants.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { Annotation, NodeWithIdsAndLength } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\n\n/** one drawn span: a feature, the lane it sits in, and its row's depth */\nexport interface SpanBand {\n annotation: Annotation\n lane: number\n laneCount: number\n}\n\n/** one row's spans, at the row baseline `y` the tree layout gives it */\nexport interface SpanRow<T extends SpanBand> {\n y: number\n bands: T[]\n}\n\n/**\n * Where a band lands inside its row. The alignment overlay fills the row, bars\n * it along the bottom, or stacks thin sub-rows; a `features` row panel divides\n * the row between its lanes.\n */\nexport interface SpanLayout {\n /** the band height in a row needing `laneCount` lanes */\n height: (laneCount: number) => number\n /** the band's top edge, from its row baseline, its lane and its height */\n top: (y: number, lane: number, height: number) => number\n /** how far back from the feature's end the head starts */\n headLength: (height: number) => number\n /**\n * how far the head rises above the band. A bar too thin to taper reads its\n * direction off a head taller than itself, and the bar sits on the row's\n * bottom edge, so the room is above.\n */\n headRise?: (height: number) => number\n}\n\n/**\n * What a renderer hands the span mark: its rows, where a band lands in them,\n * its x mapping, the colors and the label each feature takes.\n */\nexport interface SpanSource<T extends SpanBand> {\n rows: SpanRow<T>[]\n layout: SpanLayout\n xOf: (band: T) => [number, number]\n colors: Map<Annotation, { fill: string; stroke: string }>\n labelOf?: (band: T) => string | undefined\n labelDrawn?: (band: T) => void\n}\n\n/** a span as drawn: a box, or an arrow's outline where it carries a strand */\nexport interface SpanShape<T extends SpanBand> {\n band: T\n fill: string\n stroke: string\n box?: { x: number; y: number; w: number; h: number }\n outline?: [number, number][]\n}\n\nexport interface SpanLabel {\n text: string\n x: number\n y: number\n fill: string\n}\n\n/** one row's shapes, then the labels drawn over them at `fontSize` */\nexport interface SpanMarkRow<T extends SpanBand> {\n shapes: SpanShape<T>[]\n labels: SpanLabel[]\n fontSize: number\n}\n\n/** the rows of `bandsByRow` that `leaves` covers, in display order */\nexport function spanRows<T extends SpanBand>(\n leaves: HierarchyNode<NodeWithIdsAndLength>[],\n bandsByRow: Map<string, T[]>,\n): SpanRow<T>[] {\n const rows: SpanRow<T>[] = []\n for (const leaf of leaves) {\n const bands = bandsByRow.get(leaf.data.name)\n if (bands && bands.length > 0) {\n rows.push({ y: leaf.x!, bands })\n }\n }\n return rows\n}\n\n/**\n * The span mark as geometry, in whatever x space `xOf` maps its bands into:\n * alignment columns for the domain overlay, panel pixels for a `features` row\n * panel. A feature with a strand is an arrow, one without a box, and a label\n * lands inside the span wherever `measureText` says the text fits.\n *\n * `y - rowHeight` is the row's top edge in the coordinates `rows` gives.\n */\nexport function featureSpanMarks<T extends SpanBand>({\n rows,\n layout,\n xOf,\n colors,\n labelOf,\n labelDrawn,\n measureText,\n xMin,\n xMax,\n}: SpanSource<T> & {\n measureText: (text: string, fontSize: number) => number\n xMin: number\n xMax: number\n}): SpanMarkRow<T>[] {\n const out: SpanMarkRow<T>[] = []\n for (const { y, bands } of rows) {\n const h = layout.height(bands[0]!.laneCount)\n const headLen = layout.headLength(h)\n const rise = layout.headRise?.(h) ?? 0\n const labelled = labelOf !== undefined && h >= minFeatureLabelHeight\n const fontSize = Math.min(h - 2, 11)\n const shapes: SpanShape<T>[] = []\n const labels: SpanLabel[] = []\n // one row's spans are drawn before any of its labels. Bands are ordered\n // longest-first so a nested one lands on top, and drawing each label with\n // its own span put the child's box over the parent's text: `S` covered\n // `RBD`, and `RBD` read as `RB`.\n const placed: {\n band: T\n xStart: number\n w: number\n t: number\n head: number\n fill: string\n }[] = []\n\n for (const band of bands) {\n const [xStart, xEnd] = xOf(band)\n const w = xEnd - xStart\n if (xEnd < xMin || xStart > xMax) {\n continue\n }\n const t = layout.top(y, band.lane, h)\n const { fill, stroke } = colors.get(band.annotation)!\n const { strand } = band.annotation\n const head = strand === undefined ? 0 : Math.min(headLen, w)\n shapes.push(\n strand === undefined\n ? { band, fill, stroke, box: { x: xStart, y: t, w, h } }\n : {\n band,\n fill,\n stroke,\n outline: geneArrow({ x: xStart, t, w, h, head, rise, strand }),\n },\n )\n if (labelled) {\n placed.push({ band, xStart, w, t, head, fill })\n }\n }\n\n for (const { band, xStart, w, t, head, fill } of placed) {\n // asking for the label here rather than in the pass above keeps the\n // once-per-block segment numbering in drawing order\n const text = labelOf!(band)\n // the head narrows to a point, so only about half of it holds text\n if (\n text !== undefined &&\n measureText(text, fontSize) + 2 <= w - head / 2\n ) {\n labelDrawn?.(band)\n labels.push({ text, x: xStart + w / 2, y: t + h / 2, fill })\n }\n }\n out.push({ shapes, labels, fontSize })\n }\n return out\n}\n\n/**\n * The span mark, drawn into `ctx` from `featureSpanMarks`, with the context\n * translated so that `y - rowHeight` is the row's top edge.\n */\nexport function drawFeatureSpans<T extends SpanBand>({\n ctx,\n contrastText,\n ...source\n}: SpanSource<T> & {\n ctx: RenderCtx\n contrastText: (color: string) => string\n xMin: number\n xMax: number\n}) {\n let font = ''\n const setFont = (fontSize: number) => {\n const next = `${fontSize}px sans-serif`\n if (next !== font) {\n ctx.font = next\n font = next\n }\n }\n const rows = featureSpanMarks({\n ...source,\n measureText: (text, fontSize) => {\n setFont(fontSize)\n return ctx.measureText(text).width\n },\n })\n for (const { shapes, labels, fontSize } of rows) {\n for (const { fill, stroke, box, outline } of shapes) {\n ctx.fillStyle = fill\n ctx.strokeStyle = stroke\n if (box) {\n ctx.fillRect(box.x, box.y, box.w, box.h)\n ctx.strokeRect(box.x, box.y, box.w, box.h)\n } else if (outline) {\n ctx.beginPath()\n ctx.moveTo(...outline[0]!)\n for (let i = 1; i < outline.length; i++) {\n ctx.lineTo(...outline[i]!)\n }\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n }\n }\n if (labels.length > 0) {\n setFont(fontSize)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n for (const { text, x, y, fill } of labels) {\n ctx.fillStyle = contrastText(fill)\n ctx.fillText(text, x, y)\n }\n }\n }\n}\n\n/**\n * A gene arrow's outline, the way gggenes and gggenomes draw one: the head is\n * the last `head` pixels *of* the feature, tapering to a point at its end, and\n * a feature shorter than the head is all head. The glyph therefore covers its\n * start..end span and nothing else, so adjacent genes butt together instead of\n * biting triangles out of each other, a neighbour never draws over a label, and\n * a gene 20 columns wide reads as 20 columns wide.\n *\n * `rise` lifts the head above the band, for a bar too thin to taper.\n */\nfunction geneArrow({\n x,\n t,\n w,\n h,\n head,\n rise,\n strand,\n}: {\n x: number\n t: number\n w: number\n h: number\n head: number\n rise: number\n strand: number\n}): [number, number][] {\n const tip = strand > 0 ? x + w : x\n const tail = strand > 0 ? x : x + w\n const flange = strand > 0 ? tip - head : tip + head\n const bottom = t + h\n const crown = t - rise\n const point = (crown + bottom) / 2\n if (head >= w) {\n return [\n [tail, crown],\n [tip, point],\n [tail, bottom],\n ]\n }\n return [\n [tail, t],\n [flange, t],\n ...(rise > 0 ? [[flange, crown] as [number, number]] : []),\n [tip, point],\n [flange, bottom],\n [tail, bottom],\n ]\n}\n", "import { domainUnderlineHeight, subFeatureRowHeight } from '../../constants.ts'\nimport { contrastTextFn } from '../../util.ts'\nimport { getVisibleLeaves } from '../getVisibleLeaves.ts'\nimport { drawFeatureSpans, spanRows } from './drawFeatureSpans.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { DomainBand, NodeWithIdsAndLength } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { SpanSource } from './drawFeatureSpans.ts'\nimport type { Theme } from '@mui/material'\n\nexport function renderBoxFeatureCanvasBlock({\n model,\n theme,\n offsetX,\n offsetY,\n ctx,\n highResScaleFactorOverride,\n blockSizeXOverride,\n blockSizeYOverride,\n}: {\n offsetX: number\n offsetY: number\n model: MsaViewModel\n theme: Theme\n ctx: RenderCtx\n highResScaleFactorOverride?: number\n blockSizeXOverride?: number\n blockSizeYOverride?: number\n}) {\n const { blockSize, rowHeight, highResScaleFactor, actuallyShowDomains } =\n model\n if (!actuallyShowDomains) {\n return\n }\n const k = highResScaleFactorOverride ?? highResScaleFactor\n const bx = blockSizeXOverride ?? blockSize\n const by = blockSizeYOverride ?? blockSize\n ctx.resetTransform()\n ctx.scale(k, k)\n ctx.translate(-offsetX, rowHeight / 2 - offsetY)\n\n drawFeatureSpans<DomainBand>({\n ctx,\n ...domainOverlaySource(\n model,\n getVisibleLeaves({ model, offsetY, blockSizeY: by }),\n ),\n contrastText: contrastTextFn(theme),\n xMin: offsetX,\n xMax: offsetX + bx,\n })\n}\n\n/**\n * The domain overlay's spans over `leaves`, in alignment pixels: filled rows,\n * an underline bar, or thin sub-rows, as `domainUnderline` and\n * `subFeatureRows` decide.\n */\nexport function domainOverlaySource(\n model: MsaViewModel,\n leaves: HierarchyNode<NodeWithIdsAndLength>[],\n): SpanSource<DomainBand> {\n const {\n rowHeight,\n subFeatureRows,\n colWidth,\n featureColors,\n featureLabels,\n segmentLabels,\n showMsaLetters,\n domainUnderline,\n domainBands,\n } = model\n // the plain and underline modes give every band the same height; a sub-row\n // band is thinner, and how thin depends on how many lanes its row needs\n const barHeight = domainUnderline\n ? Math.min(domainUnderlineHeight, rowHeight)\n : rowHeight\n // exon numbers label the bands only when residue letters aren't drawn (zoomed\n // out); when letters show, the alternating shades alone mark the boundaries\n // and a number would collide with the sequence. A featureLabel encoding names\n // what every span carries instead\n const drawSegmentLabels = !featureLabels && !showMsaLetters && !subFeatureRows\n // a segment (exon) number labels its band once per block, on the topmost\n // visible row carrying that segment, so it reads as a column header for the\n // whole band. Keyed by accession rather than drawn on row 0, because the rows\n // carrying the gene model are often not the first ones in the alignment\n const labelled = drawSegmentLabels ? new Set<string>() : undefined\n\n return {\n rows: spanRows(leaves, domainBands),\n layout: {\n // sub-rows are thin, but a row whose lanes would spill onto the row below\n // shares out the row height between them instead\n height: laneCount =>\n subFeatureRows\n ? Math.min(subFeatureRowHeight, rowHeight / laneCount)\n : barHeight,\n top: (y, lane, h) =>\n y -\n rowHeight +\n (subFeatureRows ? lane * h : domainUnderline ? rowHeight - h : 0),\n headLength: h => (domainUnderline ? rowHeight / 2 : h),\n // a head only as tall as an underline bar tapers over ten pixels of\n // three, which reads as nothing; it takes the lower two fifths of the\n // row instead, leaving the letters above it\n headRise: h => (domainUnderline ? Math.max(0, rowHeight * 0.4 - h) : 0),\n },\n xOf: band => [band.startCol * colWidth, band.endCol * colWidth],\n colors: featureColors,\n labelOf: band =>\n featureLabels?.get(band.annotation) ??\n (labelled && !labelled.has(band.annotation.accession)\n ? segmentLabels.get(band.annotation.accession)\n : undefined),\n labelDrawn: band => labelled?.add(band.annotation.accession),\n }\n}\n", "// Replace just the px size token in a canvas font string, preserving the\n// family (and optionally toggling bold). Accepts anything with a `font` field,\n// so it works for both a real CanvasRenderingContext2D and the svgcanvas\n// export context.\n//\n// [\\d.]+ is load-bearing: it matches fractional sizes produced by smooth zoom.\n// \\d+ alone matches only the fraction (\"8604\" in \"14.8604px\"), splicing the new\n// size into the middle to make an invalid string like \"14 0.18px sans-serif\" \u2014\n// which canvas silently rejects, freezing the font and making fillText draw\n// nothing while fillRect still works.\nexport function setFontSize(\n ctx: { font: string },\n fontSize: number,\n bold = false,\n) {\n ctx.font = ctx.font.replace(\n /(?:bold )?[\\d.]+px/,\n `${bold ? 'bold ' : ''}${fontSize}px`,\n )\n}\n", "// Shared highlight colors for the MSA/tree hover and selection overlay canvases.\n// Kept in one place so the reference-row color (drawn identically over both the\n// tree and the alignment) can't drift between the two surfaces.\n\n// reference (relativeTo) row, drawn over both the tree and the alignment\nexport const referenceColor = 'rgba(0,128,255,0.3)'\n\n// tree-node descendant rows highlighted on hover. The alpha differs by surface\n// intentionally: the tree background is plain so it can take a stronger wash,\n// while the alignment cells are already colored so a lighter wash reads better.\nexport const treeHoverColor = 'rgba(255,165,0,0.2)'\nexport const multiRowHoverColor = 'rgba(255,165,0,0.15)'\n\n// the hovered column/row, and the one pinned by a click. Drawn on the alignment\n// overlay canvas and again as plain divs over the track area, which have to\n// match or the crosshair appears to change color as it crosses the tracks.\nexport const hoverColor = 'rgba(0,0,0,0.15)'\nexport const clickColor = 'rgba(128,128,0,0.2)'\n\n// the selected block, a blue that reads apart from the orange highlights\nexport const selectionFill = 'rgba(25,118,210,0.22)'\nexport const selectionBorder = 'rgba(25,118,210,0.95)'\n", "import { setFontSize } from '../../setFontSize.ts'\nimport {\n referenceColor,\n selectionBorder,\n selectionFill,\n} from '../overlayColors.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\n// a fill plus a solid border; the hover wash alone is invisible over clustalx\n// coloring\nexport const highlightFill = 'rgba(255,140,0,0.28)'\nexport const highlightBorder = 'rgba(210,90,0,0.95)'\nexport const highlightRowFill = 'rgba(255,140,0,0.18)'\n\nexport const labelFontSize = 11\nconst labelPad = 3\n// the label box above a highlight band; tree blocks also check rows this far\n// outside themselves\nexport const highlightLabelHeight = labelFontSize + labelPad * 2\n\nexport interface LabelBox {\n left: number\n right: number\n top: number\n bottom: number\n}\n\n/**\n * A highlight's label, over its band where it fits and beside it where it does\n * not, kept inside `bounds` and out of the way of the labels already placed.\n *\n * `bounds` keeps the label of a band scrolled partly off the left edge visible.\n * With `placed`, a label that would overlap an earlier one, as two\n * single-residue highlights a column apart do, steps down a row.\n */\nexport function drawHighlightLabel({\n ctx,\n theme,\n label,\n x,\n y,\n spanWidth,\n bounds,\n placed,\n}: {\n ctx: RenderCtx\n theme: Theme\n label: string\n x: number\n y: number\n spanWidth: number\n bounds?: { min: number; max: number }\n placed?: LabelBox[]\n}) {\n setFontSize(ctx, labelFontSize)\n ctx.textAlign = 'start'\n const boxWidth = ctx.measureText(label).width + labelPad * 2\n const boxHeight = highlightLabelHeight\n let left = boxWidth <= spanWidth ? x : x + spanWidth + 2\n if (bounds) {\n left = Math.max(bounds.min, Math.min(left, bounds.max - boxWidth))\n }\n let top = y\n if (placed) {\n const overlaps = (box: LabelBox) =>\n box.left < left + boxWidth &&\n box.right > left &&\n box.top < top + boxHeight &&\n box.bottom > top\n while (placed.some(overlaps)) {\n top += boxHeight\n }\n placed.push({ left, right: left + boxWidth, top, bottom: top + boxHeight })\n }\n ctx.fillStyle = theme.palette.background.paper\n ctx.fillRect(left, top, boxWidth, boxHeight)\n ctx.fillStyle = theme.palette.text.primary\n ctx.fillText(label, left + labelPad, top + labelPad + labelFontSize - 2)\n}\n\n/**\n * The persistent overlay on the alignment: the band behind each clade of\n * `clades`, the `rowTint` encoding's wash, the row tints and bordered column\n * bands of `highlights`, and a label above each band. `offsetX`/`offsetY` are\n * the content coordinates at the canvas origin, the convention renderMSABlock\n * uses, so the live overlay passes -scrollX/-scrollY and the export passes its\n * layout offsets.\n *\n * Rows are culled to the ones this block covers. A tint over every row of a\n * large alignment would otherwise draw the whole column of rects in each block,\n * and again on every pointer move through renderMouseover.\n */\nexport function renderHighlights({\n ctx,\n model,\n theme,\n offsetX,\n offsetY,\n width,\n height,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n offsetX: number\n offsetY: number\n width: number\n height: number\n}) {\n const { resolvedClades, resolvedHighlights, rowTints, colWidth, rowHeight } =\n model\n const placed: LabelBox[] = []\n ctx.lineWidth = 2\n const firstRow = Math.max(0, Math.floor(offsetY / rowHeight))\n const lastRow = Math.ceil((offsetY + height) / rowHeight)\n const fillRow = (index: number) => {\n ctx.fillRect(0, index * rowHeight - offsetY, width, rowHeight)\n }\n for (const { rows, color, mark } of resolvedClades) {\n if (mark === 'highlight' && rows[1] >= firstRow && rows[0] <= lastRow) {\n ctx.fillStyle = color\n ctx.fillRect(\n 0,\n rows[0] * rowHeight - offsetY,\n width,\n (rows[1] - rows[0] + 1) * rowHeight,\n )\n }\n }\n if (rowTints) {\n for (\n let index = firstRow;\n index <= Math.min(lastRow, rowTints.length - 1);\n index++\n ) {\n const color = rowTints[index]\n if (color) {\n ctx.fillStyle = color\n fillRow(index)\n }\n }\n }\n for (const { rowIndices, color } of resolvedHighlights) {\n ctx.fillStyle = color ?? highlightRowFill\n for (const index of rowIndices) {\n if (index >= firstRow && index <= lastRow) {\n fillRow(index)\n }\n }\n }\n for (const { startCol, endCol, label, color } of resolvedHighlights) {\n if (startCol === undefined || endCol === undefined) {\n continue\n }\n const x = startCol * colWidth - offsetX\n const spanWidth = (endCol - startCol + 1) * colWidth\n ctx.fillStyle = color ?? highlightFill\n ctx.fillRect(x, 0, spanWidth, height)\n ctx.strokeStyle = color ?? highlightBorder\n ctx.strokeRect(x, 0, spanWidth, height)\n if (label) {\n drawHighlightLabel({\n ctx,\n theme,\n label,\n x,\n y: 0,\n spanWidth,\n bounds: { min: 0, max: width },\n placed,\n })\n }\n }\n}\n\n/**\n * The selected block, a bordered band per run of consecutive selected rows,\n * culled to the rows this block covers\n */\nexport function renderSelection({\n ctx,\n model,\n offsetX,\n offsetY,\n height,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n offsetX: number\n offsetY: number\n height: number\n}) {\n const { resolvedSelection, colWidth, rowHeight } = model\n if (!resolvedSelection) {\n return\n }\n const { startCol, endCol, rowRuns } = resolvedSelection\n const x = startCol * colWidth - offsetX\n const w = (endCol - startCol + 1) * colWidth\n ctx.lineWidth = 1\n for (const [first, last] of rowRuns) {\n const y = first * rowHeight - offsetY\n const h = (last - first + 1) * rowHeight\n if (y < height && y + h > 0) {\n ctx.fillStyle = selectionFill\n ctx.fillRect(x, y, w, h)\n ctx.strokeStyle = selectionBorder\n ctx.strokeRect(x, y, w, h)\n }\n }\n}\n\n/**\n * The overlay parts that come from the snapshot: the reference row's tint, a\n * bordered band per run of highlighted columns and the `highlights` layer. The\n * live overlay draws these under the selected block and its hover and click\n * bands; the SVG export draws only these.\n */\nexport function renderPersistentHighlights({\n ctx,\n model,\n theme,\n offsetX,\n offsetY,\n width,\n height,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n offsetX: number\n offsetY: number\n width: number\n height: number\n}) {\n const { colWidth, rowHeight, referenceRowIndex, highlightedColumnRuns } =\n model\n\n if (referenceRowIndex !== undefined) {\n ctx.fillStyle = referenceColor\n ctx.fillRect(0, referenceRowIndex * rowHeight - offsetY, width, rowHeight)\n }\n\n ctx.lineWidth = 2\n for (const { start, end } of highlightedColumnRuns) {\n const x = start * colWidth - offsetX\n const w = (end - start + 1) * colWidth\n ctx.fillStyle = highlightFill\n ctx.fillRect(x, 0, w, height)\n ctx.strokeStyle = highlightBorder\n ctx.strokeRect(x, 0, w, height)\n }\n\n renderHighlights({ ctx, model, theme, offsetX, offsetY, width, height })\n}\n", "import type { DomainBand } from '../../types.ts'\n\n/**\n * Left-to-right cursor over one row's domain bands that returns the band drawn\n * on top at a column, for a letter's contrast color.\n *\n * The overlay paints in `domainBands` order, largest first, so where signatures\n * nest (InterProScan often emits a family enclosing a domain) the visible band\n * is the last one painted. `stackIndex` is that paint order.\n *\n * `bands` must be sorted by start column (`domainBandsByStart`) and columns\n * visited in increasing order, which keeps this to one pass per row.\n */\nexport function domainBandCursor(bands: DomainBand[] | undefined) {\n let next = 0\n let active: DomainBand[] = []\n\n return (col: number) => {\n if (!bands) {\n return undefined\n }\n while (next < bands.length && bands[next]!.startCol <= col) {\n active.push(bands[next]!)\n next++\n }\n if (active.some(band => band.endCol <= col)) {\n active = active.filter(band => band.endCol > col)\n }\n let top: DomainBand | undefined\n for (const band of active) {\n if (!top || band.stackIndex > top.stackIndex) {\n top = band\n }\n }\n return top\n }\n}\n", "// The half-open range of alignment columns [xStart, xEnd) intersecting a block\n// of width blockWidth at horizontal offset offsetX. X-axis counterpart to\n// getVisibleLeaves.\nexport function visibleColRange({\n offsetX,\n blockWidth,\n colWidth,\n}: {\n offsetX: number\n blockWidth: number\n colWidth: number\n}) {\n return {\n xStart: Math.max(0, Math.floor(offsetX / colWidth)),\n xEnd: Math.max(0, Math.ceil((offsetX + blockWidth) / colWidth)),\n }\n}\n", "import { setFontSize } from '../../setFontSize.ts'\nimport { adjustColorForContrast, contrastTextFn } from '../../util.ts'\nimport { getVisibleLeaves } from '../getVisibleLeaves.ts'\nimport { domainBandCursor } from './domainBandCursor.ts'\nimport { tileColorFn } from './tileColor.ts'\nimport { visibleColRange } from './visibleColRange.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { NodeWithIdsAndLength } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\nexport function renderMSABlock({\n model,\n offsetX,\n offsetY,\n ctx,\n theme,\n highResScaleFactorOverride,\n blockSizeXOverride,\n blockSizeYOverride,\n rasterTiles,\n}: {\n offsetX: number\n offsetY: number\n theme: Theme\n model: MsaViewModel\n ctx: RenderCtx\n highResScaleFactorOverride?: number\n blockSizeXOverride?: number\n blockSizeYOverride?: number\n rasterTiles?: boolean\n}) {\n const {\n colWidth,\n blockSize,\n rowHeight,\n fontSize,\n highResScaleFactor,\n actuallyShowDomains,\n bgColor,\n } = model\n const k = highResScaleFactorOverride ?? highResScaleFactor\n const bx = blockSizeXOverride ?? blockSize\n const by = blockSizeYOverride ?? blockSize\n ctx.resetTransform()\n ctx.scale(k, k)\n ctx.translate(-offsetX, rowHeight / 2 - offsetY)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'alphabetic'\n setFontSize(ctx, fontSize, !bgColor)\n\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: bx,\n colWidth,\n })\n const visibleLeaves = getVisibleLeaves({ model, offsetY, blockSizeY: by })\n const { relativeTo, columns } = model\n const referenceSeq = relativeTo\n ? columns.get(relativeTo)?.slice(xStart, xEnd)\n : null\n\n drawTilesAndText({\n model,\n ctx,\n theme,\n xStart,\n xEnd,\n visibleLeaves,\n referenceSeq,\n // when domains are shown the background tiles come from\n // renderBoxFeatureCanvasBlock, so only the letters are drawn here\n drawTiles: !actuallyShowDomains,\n // ...and when the caller has already laid the raster down, the tiles are\n // there but nothing here has to paint them\n rasterTiles,\n })\n drawInsertionIndicators({\n model,\n ctx,\n xStart,\n xEnd,\n visibleLeaves,\n })\n ctx.resetTransform()\n}\n\nfunction drawTilesAndText({\n model,\n ctx,\n theme,\n visibleLeaves,\n xStart,\n xEnd,\n referenceSeq,\n drawTiles,\n rasterTiles,\n}: {\n model: MsaViewModel\n theme: Theme\n ctx: RenderCtx\n visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]\n xStart: number\n xEnd: number\n referenceSeq: string | null | undefined\n drawTiles: boolean\n rasterTiles?: boolean\n}) {\n const {\n bgColor,\n columns,\n colWidth,\n rowHeight,\n fontSize,\n relativeTo,\n showMsaLetters,\n subFeatureRows,\n domainUnderline,\n domainBandsByStart,\n featureColors,\n } = model\n\n const tiles = drawTiles && bgColor\n const paintTiles = tiles && !rasterTiles\n if (paintTiles || showMsaLetters) {\n const tileColor = tileColorFn(model)\n // Domain fills come from a categorical palette with no fixed lightness, and\n // a dynamic scheme colors a cell from its column, so a readable letter color\n // is a question about the cell's own color rather than about its letter.\n const contrastText = contrastTextFn(theme)\n const offsetXAligned = xStart * colWidth\n const halfColWidth = colWidth / 2\n // the context is translated by rowHeight/2, so `y` is the row's bottom\n // edge and the baseline lands fontSize/4 below the row center, where the\n // tree puts its tip labels\n const baselineOffset = rowHeight / 2 - fontSize / 4\n // with the tiles coming from the domain overlay instead, letters sit either\n // on a domain box or on the plain background; sub-row layout stacks the boxes\n // above the letters and letter-color mode shrinks them to a bar under the\n // row, so neither leaves anything behind a letter\n const overDomains = !drawTiles && !subFeatureRows && !domainUnderline\n\n for (let i = 0, l1 = visibleLeaves.length; i < l1; i++) {\n const node = visibleLeaves[i]!\n const { name } = node.data\n const y = node.x!\n const str = columns.get(name)?.slice(xStart, xEnd)\n if (str) {\n const tileY = y - rowHeight\n const textY = y - baselineOffset\n const bandAt = domainBandCursor(\n overDomains ? domainBandsByStart.get(name) : undefined,\n )\n\n for (let j = 0, l2 = str.length; j < l2; j++) {\n const col = xStart + j\n const letter = str[j]!\n const x = j * colWidth + offsetXAligned\n const isMatchingReference =\n referenceSeq && name !== relativeTo && letter === referenceSeq[j]\n const color = tileColor(col, letter)\n\n if (paintTiles) {\n ctx.fillStyle = isMatchingReference\n ? theme.palette.action.hover\n : color || theme.palette.background.default\n ctx.fillRect(x, tileY, colWidth, rowHeight)\n }\n\n if (showMsaLetters) {\n const covering = bandAt(col)\n ctx.fillStyle = covering\n ? // on top of a domain box: contrast against the box fill\n contrastText(featureColors.get(covering.annotation)?.fill)\n : isMatchingReference\n ? // the dot sits on the faint reference-match wash, which is\n // the theme's background with a little of its text color in it\n theme.palette.text.primary\n : tiles\n ? // on top of a colored tile, or on the background where the\n // scheme gives that cell no color\n contrastText(color)\n : bgColor || !color\n ? // plain background, uncolored letters\n theme.palette.text.primary\n : // letter-color mode: darken/lighten to stay readable\n adjustColorForContrast(\n color,\n theme.palette.background.default,\n )\n ctx.fillText(\n isMatchingReference ? '.' : letter,\n x + halfColWidth,\n textY,\n )\n }\n }\n }\n }\n }\n}\n\nfunction drawInsertionIndicators({\n model,\n ctx,\n visibleLeaves,\n xStart,\n xEnd,\n}: {\n model: MsaViewModel\n ctx: RenderCtx\n visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]\n xStart: number\n xEnd: number\n}) {\n const { bgColor, hideGapsEffective } = model\n if (!hideGapsEffective) {\n return\n }\n\n ctx.lineWidth = 1\n ctx.strokeStyle = '#f0f'\n drawZigZag({ visibleLeaves, xStart, ctx, model, xEnd, offset: 0 })\n ctx.strokeStyle = !bgColor ? '#000' : '#fff'\n drawZigZag({ visibleLeaves, xStart, ctx, model, xEnd, offset: -1 })\n}\n\nfunction drawZigZag({\n model,\n ctx,\n visibleLeaves,\n xStart,\n xEnd,\n offset,\n}: {\n model: MsaViewModel\n ctx: RenderCtx\n visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]\n xStart: number\n xEnd: number\n offset: number\n}) {\n const zigSize = 1\n const { colWidth, rowHeight, insertionPositions } = model\n for (const node of visibleLeaves) {\n const { name } = node.data\n const insertions = insertionPositions.get(name)\n if (insertions) {\n const y = node.x!\n for (const { pos } of insertions) {\n if (pos >= xStart && pos < xEnd) {\n const x = pos * colWidth\n const top = y - rowHeight\n const bottom = y\n ctx.beginPath()\n ctx.moveTo(x + offset, top + offset)\n let currentY = top\n let goRight = true\n while (currentY < bottom) {\n const nextY = Math.min(currentY + zigSize * 2, bottom)\n const nextX = goRight ? x + zigSize : x - zigSize\n ctx.lineTo(nextX + offset, nextY + offset)\n currentY = nextY\n goRight = !goRight\n }\n ctx.stroke()\n }\n }\n }\n }\n}\n", "import { rowPanelHeaderHeight } from '../../constants.ts'\n\nexport function headerRunsAcross(panelWidth: number) {\n return panelWidth > rowPanelHeaderHeight\n}\n", "import { contrastTextFn } from '../../util.ts'\nimport { getVisibleLeaves } from '../getVisibleLeaves.ts'\nimport { drawFeatureSpans, spanRows } from '../msa/drawFeatureSpans.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type {\n NodeWithIdsAndLength,\n ResolvedFeaturePanel,\n RowPanelSpan,\n} from '../../types.ts'\nimport type { SpanSource } from '../msa/drawFeatureSpans.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\n// a span keeps a pixel clear above and below it, so stacked lanes and adjacent\n// rows read apart\nconst rowPadding = 2\n\n/**\n * The spans of a `features` panel, drawn with the mark the alignment overlay\n * draws: an arrow where the feature carries a strand, a box otherwise, labeled\n * where the text fits. The x mapping is the panel's own, resolved in\n * `resolvedRowPanels`; a row needing several lanes divides its height between\n * them.\n */\nexport function renderFeaturePanel({\n ctx,\n model,\n theme,\n panel,\n x,\n offsetY,\n blockSizeYOverride,\n highResScaleFactorOverride,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n panel: ResolvedFeaturePanel\n x: number\n offsetY: number\n blockSizeYOverride?: number\n highResScaleFactorOverride?: number\n}) {\n const { rowHeight, blockSize, highResScaleFactor } = model\n const by = blockSizeYOverride ?? blockSize\n const k = highResScaleFactorOverride ?? highResScaleFactor\n ctx.resetTransform()\n ctx.scale(k, k)\n ctx.translate(x, rowHeight / 2 - offsetY)\n\n drawFeatureSpans<RowPanelSpan>({\n ctx,\n ...featurePanelSource(\n model,\n panel,\n getVisibleLeaves({ model, offsetY, blockSizeY: by }),\n ),\n contrastText: contrastTextFn(theme),\n xMin: 0,\n xMax: panel.width,\n })\n}\n\n/** a features panel's spans over `leaves`, in panel pixels, a lane apiece */\nexport function featurePanelSource(\n model: MsaViewModel,\n panel: ResolvedFeaturePanel,\n leaves: HierarchyNode<NodeWithIdsAndLength>[],\n): SpanSource<RowPanelSpan> {\n const { rowHeight } = model\n return {\n rows: spanRows(leaves, panel.spans),\n layout: {\n height: laneCount => Math.max(1, rowHeight / laneCount - rowPadding),\n top: (y, lane, h) =>\n y - rowHeight + lane * (h + rowPadding) + rowPadding / 2,\n headLength: h => h,\n },\n xOf: span => [span.xStart, span.xEnd],\n colors: panel.colors,\n labelOf: span => panel.labels?.get(span.annotation),\n }\n}\n", "import { getVisibleLeaves } from '../getVisibleLeaves.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ResolvedStripPanel } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\n\n/**\n * One cell per row of a `strip` panel, in the color its field takes through\n * the panel's scale. A row the table has no value for leaves the cell empty.\n *\n * `x` is the panel's left edge in the context: the live view gives each panel\n * a canvas of its own and passes 0, and the export packs every panel into one\n * context and passes the panel's own offset.\n */\nexport function renderStrip({\n ctx,\n model,\n panel,\n x,\n offsetY,\n blockSizeYOverride,\n highResScaleFactorOverride,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n panel: ResolvedStripPanel\n x: number\n offsetY: number\n blockSizeYOverride?: number\n highResScaleFactorOverride?: number\n}) {\n const { rowHeight, blockSize, highResScaleFactor } = model\n const by = blockSizeYOverride ?? blockSize\n ctx.resetTransform()\n const k = highResScaleFactorOverride ?? highResScaleFactor\n ctx.scale(k, k)\n ctx.translate(x, -offsetY)\n for (const leaf of getVisibleLeaves({ model, offsetY, blockSizeY: by })) {\n const color = panel.colors.get(leaf.data.name)\n if (color) {\n ctx.fillStyle = color\n // leaf.x is the row's center, at rowHeight*(index+0.5)\n ctx.fillRect(0, leaf.x! - rowHeight / 2, panel.width, rowHeight)\n }\n }\n}\n", "import { renderFeaturePanel } from './renderFeaturePanel.ts'\nimport { renderStrip } from './renderStrip.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ResolvedRowPanel } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\ninterface PanelArgs {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n panel: ResolvedRowPanel\n x: number\n offsetY: number\n blockSizeYOverride?: number\n highResScaleFactorOverride?: number\n}\n\n/**\n * One row panel, by kind. `x` is the panel's left edge in the context: the\n * live view gives each panel a canvas of its own and passes 0, and the export\n * packs every panel into one context and passes the panel's own offset.\n */\nexport function renderRowPanel({ panel, ...rest }: PanelArgs) {\n if (panel.kind === 'features') {\n renderFeaturePanel({ panel, ...rest })\n } else {\n renderStrip({ panel, ...rest })\n }\n}\n\n/** every row panel side by side in one context, for the SVG export */\nexport function renderRowPanels({\n model,\n ...rest\n}: Omit<PanelArgs, 'panel' | 'x'>) {\n for (const panel of model.resolvedRowPanels) {\n renderRowPanel({ model, panel, x: panel.offsetX, ...rest })\n }\n}\n", "// Per-column residue counts for an alignment, stored as a flat typed array\n// instead of one `Record<string, number>` per column. Column statistics are the\n// hottest computation in the viewer (they feed conservation, ClustalX coloring,\n// consensus and the hover tooltip), and the object-per-column form spent all of\n// its time on megamorphic string-keyed property increments: 1000x5000 residues\n// took ~1.6s to tally that way versus ~35ms here.\n//\n// Each column owns a fixed stride of counter slots. Slots 1-26 are A-Z (case\n// folded), plus a slot each for the two gap characters, '*', and anything else.\n\nconst SLOTS = 32\nconst DASH = 27\nconst DOT = 28\nconst STAR = 29\nconst OTHER = 30\n\nconst A = 'A'.charCodeAt(0)\nconst Z = 'Z'.charCodeAt(0)\nconst a = 'a'.charCodeAt(0)\nconst z = 'z'.charCodeAt(0)\n\n// charCode -> slot. A plain `code & 31` would fold digits and punctuation onto\n// letter slots ('0' onto 'P'), so the mapping is an explicit table.\nconst slotOfCode = new Uint8Array(128).fill(OTHER)\nfor (let c = A; c <= Z; c++) {\n slotOfCode[c] = c - A + 1\n}\nfor (let c = a; c <= z; c++) {\n slotOfCode[c] = c - a + 1\n}\nslotOfCode['-'.charCodeAt(0)] = DASH\nslotOfCode['.'.charCodeAt(0)] = DOT\nslotOfCode['*'.charCodeAt(0)] = STAR\n\nconst letterOfSlot = Array.from({ length: SLOTS }, (_, slot) =>\n slot >= 1 && slot <= 26 ? String.fromCharCode(A + slot - 1) : '',\n)\nletterOfSlot[DASH] = '-'\nletterOfSlot[DOT] = '.'\nletterOfSlot[STAR] = '*'\nletterOfSlot[OTHER] = '?'\n\nfunction slotOf(code: number) {\n return code < 128 ? slotOfCode[code]! : OTHER\n}\n\nfunction isGapSlot(slot: number) {\n return slot === DASH || slot === DOT\n}\n\nexport class ColumnCounts {\n readonly numColumns: number\n private readonly counts: Uint32Array\n // per-column residue+gap totals\n readonly totals: Uint32Array\n // whole-alignment totals per slot, so \"which letters appear anywhere\" is a\n // 32-slot scan rather than a walk over every column\n private readonly slotTotals = new Uint32Array(SLOTS)\n\n constructor(numColumns: number) {\n this.numColumns = numColumns\n this.counts = new Uint32Array(numColumns * SLOTS)\n this.totals = new Uint32Array(numColumns)\n }\n\n /** tallies a row, counting the columns past a short row's end as gaps */\n addRow(row: string) {\n const { counts, totals, slotTotals, numColumns } = this\n const n = Math.min(row.length, numColumns)\n for (let col = 0; col < n; col++) {\n const slot = slotOf(row.charCodeAt(col))\n counts[col * SLOTS + slot]!++\n totals[col]!++\n slotTotals[slot]!++\n }\n for (let col = n; col < numColumns; col++) {\n counts[col * SLOTS + DASH]!++\n totals[col]!++\n }\n slotTotals[DASH]! += numColumns - n\n }\n\n add(col: number, letter: string) {\n const slot = slotOf(letter.charCodeAt(0))\n this.counts[col * SLOTS + slot]!++\n this.totals[col]!++\n this.slotTotals[slot]!++\n }\n\n total(col: number) {\n return this.totals[col] ?? 0\n }\n\n count(col: number, letter: string) {\n return this.counts[col * SLOTS + slotOf(letter.charCodeAt(0))] ?? 0\n }\n\n gapCount(col: number) {\n const base = col * SLOTS\n return (this.counts[base + DASH] ?? 0) + (this.counts[base + DOT] ?? 0)\n }\n\n /**\n * Visits every non-gap residue present in a column. Slots with a zero count\n * are skipped, so this is ~the number of distinct residues, not 32.\n */\n forEachResidue(col: number, cb: (slot: number, count: number) => void) {\n const { counts } = this\n const base = col * SLOTS\n for (let slot = 1; slot < SLOTS; slot++) {\n const count = counts[base + slot]!\n if (count > 0 && !isGapSlot(slot)) {\n cb(slot, count)\n }\n }\n }\n\n /**\n * Shannon entropy of a column in bits, taken over its non-gap residues only:\n * a column of two residues and eight gaps is a two-way choice, not a ten-way\n * one, and gap occupancy is accounted for separately by every caller. 0 for\n * an all-gap column.\n */\n entropy(col: number) {\n const nonGapTotal = this.total(col) - this.gapCount(col)\n if (nonGapTotal === 0) {\n return 0\n }\n let entropy = 0\n this.forEachResidue(col, (_slot, count) => {\n const freq = count / nonGapTotal\n entropy -= freq * Math.log2(freq)\n })\n return entropy\n }\n\n /** non-gap [letter, count] pairs for one column, for display */\n residueEntries(col: number) {\n const entries: [string, number][] = []\n this.forEachResidue(col, (slot, count) => {\n entries.push([letterOfSlot[slot]!, count])\n })\n return entries\n }\n\n /** the distinct non-gap letters appearing anywhere in the alignment */\n get lettersPresent() {\n const letters = new Set<string>()\n for (let slot = 1; slot < SLOTS; slot++) {\n if (this.slotTotals[slot]! > 0 && !isGapSlot(slot)) {\n letters.add(letterOfSlot[slot]!)\n }\n }\n return letters\n }\n}\n\nexport function letterOfResidueSlot(slot: number) {\n return letterOfSlot[slot]!\n}\n\nexport function residueSlotOfLetter(letter: string) {\n return slotOf(letter.charCodeAt(0))\n}\n\nexport const numResidueSlots = SLOTS\n\n/**\n * Tally counts from alignment rows (gapped sequence strings, one per row). The\n * column count defaults to the longest row, and a shorter row counts as gapped\n * to the end.\n */\nexport function columnCountsFromRows(\n rows: string[],\n numColumns = rows.reduce((max, row) => Math.max(max, row.length), 0),\n) {\n const counts = new ColumnCounts(numColumns)\n for (const row of rows) {\n counts.addRow(row)\n }\n return counts\n}\n\n/**\n * Tally counts from column strings (one string per column, listing that\n * column's residues top to bottom). Convenient for tests and for callers that\n * already think column-wise.\n */\nexport function columnCountsFromColumns(columns: string[]) {\n const counts = new ColumnCounts(columns.length)\n for (const [col, column] of columns.entries()) {\n for (const letter of column) {\n counts.add(col, letter)\n }\n }\n return counts\n}\n", "import { letterOfResidueSlot } from './columnCounts.ts'\n\nimport type { ColumnCounts } from './columnCounts.ts'\n\nexport interface LogoLetter {\n letter: string\n /** height of this letter's slice of the stack, in bits */\n bits: number\n}\n\n/** the y-axis ceiling of a logo: the information content of a fully conserved\n * column, log2 of the alphabet size */\nexport function maxBitsFor(sequenceType: 'dna' | 'rna' | 'amino') {\n return Math.log2(sequenceType === 'amino' ? 20 : 4)\n}\n\n/**\n * One column of a sequence logo, tallest letter last so a caller can draw the\n * stack bottom-up in array order.\n *\n * Heights follow Schneider & Stephens: the column's information content is\n * `log2(alphabet) - H` bits, split among residues by frequency. Frequencies\n * count non-gap residues only, so two residues and eight gaps form a two-way\n * choice.\n *\n * Unlike plain WebLogo, the stack is then scaled by the non-gap fraction, so a\n * 90%-gap column with one conserved pair does not draw a full-height stack, and\n * stack height matches the conservation track.\n */\nexport function columnLogoStack(\n colStats: ColumnCounts,\n col: number,\n maxBits: number,\n): LogoLetter[] {\n const total = colStats.total(col)\n const nonGapTotal = total - colStats.gapCount(col)\n if (nonGapTotal === 0) {\n return []\n }\n\n const informationContent =\n Math.max(0, maxBits - colStats.entropy(col)) * (nonGapTotal / total)\n if (informationContent === 0) {\n return []\n }\n\n const stack: LogoLetter[] = []\n colStats.forEachResidue(col, (slot, count) => {\n stack.push({\n letter: letterOfResidueSlot(slot),\n bits: (count / nonGapTotal) * informationContent,\n })\n })\n // ascending, so drawing in order stacks the tallest letter on top. Ties break\n // on letter to keep the stack order stable between redraws.\n stack.sort((a, b) => a.bits - b.bits || a.letter.localeCompare(b.letter))\n return stack\n}\n", "import { columnLogoStack } from '../../sequenceLogo.ts'\nimport { setFontSize } from '../../setFontSize.ts'\nimport { contrastTextFn } from '../../util.ts'\nimport { visibleColRange } from '../msa/visibleColRange.ts'\n\nimport type { ColumnCounts } from '../../columnCounts.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { Arc, BasicTrack } from '../../types.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\nfunction drawConservationBars({\n ctx,\n values,\n color,\n colWidth,\n trackHeight,\n offsetX,\n blockSize,\n}: {\n ctx: RenderCtx\n values: number[]\n color: string\n colWidth: number\n trackHeight: number\n offsetX: number\n blockSize: number\n}) {\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: blockSize,\n colWidth,\n })\n\n ctx.fillStyle = color\n for (let i = xStart; i < xEnd && i < values.length; i++) {\n const value = values[i]!\n const barHeight = value * trackHeight\n const x = i * colWidth\n ctx.fillRect(x, trackHeight - barHeight, colWidth, barHeight)\n }\n}\n\n// bar-track values are model getters, off the plain track object, so the canvas\n// autorun stays reactive\nexport function barTrackValues(model: MsaViewModel, trackId: string) {\n const supplied = model.columnTrackContent.get(trackId)?.values\n if (supplied) {\n return supplied\n }\n return trackId === 'property-conservation'\n ? model.propertyConservation\n : model.conservation\n}\n\n// An arc's apex scales with the square root of its span. Contact-map spans skew\n// short, and a linear scale flattens them along the baseline.\nfunction drawArcs({\n ctx,\n arcs,\n color,\n colWidth,\n trackHeight,\n offsetX,\n blockSize,\n}: {\n ctx: RenderCtx\n arcs: Arc[] | undefined\n color: string\n colWidth: number\n trackHeight: number\n offsetX: number\n blockSize: number\n}) {\n if (!arcs?.length) {\n return\n }\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: blockSize,\n colWidth,\n })\n let maxSpan = 1\n for (const arc of arcs) {\n maxSpan = Math.max(maxSpan, arc.end - arc.start)\n }\n // a full-height apex would put the stroke half outside the track\n const apexRoom = trackHeight - 1\n ctx.lineWidth = 1\n for (const arc of arcs) {\n // an arc that spans the block draws even though neither foot is inside it\n if (arc.end < xStart || arc.start > xEnd) {\n continue\n }\n const x1 = (arc.start + 0.5) * colWidth\n const x2 = (arc.end + 0.5) * colWidth\n const apex = apexRoom * Math.sqrt((arc.end - arc.start) / maxSpan)\n ctx.strokeStyle = arc.color ?? color\n ctx.beginPath()\n ctx.moveTo(x1, trackHeight)\n ctx.quadraticCurveTo((x1 + x2) / 2, trackHeight - 2 * apex, x2, trackHeight)\n ctx.stroke()\n }\n}\n\nfunction drawTextTrackContent({\n ctx,\n data,\n colorScheme,\n contrastText,\n bgColor,\n drawLetters,\n colWidth,\n rowHeight,\n offsetX,\n blockSize,\n}: {\n ctx: RenderCtx\n data: string | undefined\n colorScheme: Record<string, string>\n contrastText: (color: string | undefined) => string\n bgColor: boolean\n drawLetters: boolean\n colWidth: number\n rowHeight: number\n offsetX: number\n blockSize: number\n}) {\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: blockSize,\n colWidth,\n })\n const str = data?.slice(xStart, xEnd)\n\n for (let i = 0; str && i < str.length; i++) {\n const letter = str[i]!\n const upper = letter.toUpperCase()\n const fill = bgColor ? colorScheme[upper] : undefined\n const x = (xStart + i) * colWidth\n if (fill) {\n ctx.fillStyle = fill\n ctx.fillRect(x, 0, colWidth, rowHeight)\n }\n if (drawLetters) {\n ctx.fillStyle = contrastText(fill)\n ctx.fillText(letter, x + colWidth / 2, rowHeight / 2)\n }\n }\n}\n\n// the smallest 1/2/5 x 10^n column step that leaves room for a label\nexport function rulerStep(colWidth: number, minPixels = 55) {\n let step = 1\n const mantissas = [1, 2, 5]\n for (let i = 0; step * colWidth < minPixels; i++) {\n step = mantissas[i % 3]! * 10 ** Math.floor(i / 3)\n }\n return step\n}\n\n// The 0-based columns in [xStart, end) to label: column 1, then each column\n// whose 1-based number is a multiple of the step. A step of 2 or more puts the\n// first multiple at least half a step's width past column 1, which clears the\n// two labels.\nexport function rulerCols(xStart: number, end: number, colWidth: number) {\n const step = rulerStep(colWidth)\n const cols = step > 1 && xStart <= 0 && end > 0 ? [0] : []\n const first = Math.max(1, Math.ceil((xStart + 1) / step)) * step\n for (let n = first; n <= end; n += step) {\n cols.push(n - 1)\n }\n return cols\n}\n\nconst RULER_FONT_SIZE = 10\nconst TICK_HEIGHT = 4\n\nfunction drawColumnRuler({\n ctx,\n numColumns,\n label,\n textColor,\n colWidth,\n trackHeight,\n offsetX,\n blockSize,\n}: {\n ctx: RenderCtx\n numColumns: number\n label: (col: number) => string | undefined\n textColor: string\n colWidth: number\n trackHeight: number\n offsetX: number\n blockSize: number\n}) {\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: blockSize,\n colWidth,\n })\n const end = Math.min(xEnd, numColumns)\n setFontSize(ctx, RULER_FONT_SIZE)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'alphabetic'\n ctx.fillStyle = textColor\n ctx.strokeStyle = textColor\n ctx.lineWidth = 1\n\n for (const col of rulerCols(xStart, end, colWidth)) {\n const text = label(col)\n if (text === undefined) {\n continue\n }\n const x = (col + 0.5) * colWidth\n ctx.fillText(text, x, trackHeight - TICK_HEIGHT - 2)\n ctx.beginPath()\n ctx.moveTo(x, trackHeight - TICK_HEIGHT)\n ctx.lineTo(x, trackHeight)\n ctx.stroke()\n }\n}\n\n// Cap height as a fraction of the font size, within a percent or two for the\n// sans-serif faces both backends use. `measureText` reports no vertical box in\n// the SVG export backend, so one constant ratio scales every logo letter, and\n// the slices sum to the stack height.\nconst CAP_HEIGHT_RATIO = 0.72\nconst MIN_LETTER_PX = 3\n\nfunction drawSequenceLogo({\n ctx,\n colStats,\n colorScheme,\n maxBits,\n textColor,\n colWidth,\n trackHeight,\n offsetX,\n blockSize,\n}: {\n ctx: RenderCtx\n colStats: ColumnCounts\n colorScheme: Record<string, string>\n maxBits: number\n textColor: string\n colWidth: number\n trackHeight: number\n offsetX: number\n blockSize: number\n}) {\n const { xStart, xEnd } = visibleColRange({\n offsetX,\n blockWidth: blockSize,\n colWidth,\n })\n const end = Math.min(xEnd, colStats.numColumns)\n\n // one reference font size for the block; each letter's transform scales it to\n // a height proportional to its frequency\n const referenceFontSize = trackHeight\n setFontSize(ctx, referenceFontSize)\n ctx.textAlign = 'left'\n ctx.textBaseline = 'alphabetic'\n const capHeight = referenceFontSize * CAP_HEIGHT_RATIO\n\n for (let col = xStart; col < end; col++) {\n const stack = columnLogoStack(colStats, col, maxBits)\n if (stack.length === 0) {\n continue\n }\n const x = col * colWidth\n // the stack is ascending, so the tallest letter lands on top\n let bottom = trackHeight\n for (const { letter, bits } of stack) {\n const h = (bits / maxBits) * trackHeight\n if (h < MIN_LETTER_PX) {\n bottom -= h\n continue\n }\n const width = ctx.measureText(letter).width\n if (width === 0) {\n bottom -= h\n continue\n }\n ctx.fillStyle = colorScheme[letter] ?? textColor\n ctx.save()\n // land the glyph's baseline on the bottom of its slice, then stretch it to\n // fill the slice vertically and the column horizontally\n ctx.translate(x, bottom)\n ctx.scale(colWidth / width, h / capHeight)\n ctx.fillText(letter, 0, 0)\n ctx.restore()\n bottom -= h\n }\n }\n}\n\n/**\n * Draw one track's content into a block of the alignment's column space, at\n * `offsetY` within the ctx. Owns the transform, so the live canvas blocks and\n * the SVG export draw into the same coordinate space. A new track kind needs a\n * `kind`, a draw function above, and a case here.\n */\nexport function drawTrackBlock({\n model,\n ctx,\n track,\n offsetX,\n offsetY = 0,\n theme,\n blockSizeXOverride,\n highResScaleFactorOverride,\n}: {\n model: MsaViewModel\n ctx: RenderCtx\n track: BasicTrack\n offsetX: number\n offsetY?: number\n theme: Theme\n blockSizeXOverride?: number\n highResScaleFactorOverride?: number\n}) {\n // an autorun tracks every model read here, so each kind reads only what it\n // draws and a vertical zoom leaves the bar and arc canvases alone\n const { blockSize, colWidth, highResScaleFactor } = model\n const {\n id,\n kind,\n height: trackHeight,\n barColor,\n arcColor,\n arcs,\n customColorScheme,\n data,\n } = track.model\n const blockSizeX = blockSizeXOverride ?? blockSize\n const k = highResScaleFactorOverride ?? highResScaleFactor\n const textColor = theme.palette.text.primary\n\n ctx.resetTransform()\n ctx.scale(k, k)\n ctx.translate(-offsetX, offsetY)\n\n switch (kind) {\n case 'bar': {\n drawConservationBars({\n ctx,\n values: barTrackValues(model, id),\n color: barColor ?? 'gray',\n colWidth,\n trackHeight,\n offsetX,\n blockSize: blockSizeX,\n })\n break\n }\n case 'arc': {\n drawArcs({\n ctx,\n arcs,\n color: arcColor ?? theme.palette.text.primary,\n colWidth,\n trackHeight,\n offsetX,\n blockSize: blockSizeX,\n })\n break\n }\n case 'logo': {\n drawSequenceLogo({\n ctx,\n colStats: model.colStats,\n colorScheme: model.colorScheme,\n maxBits: model.alphabetMaxBits,\n textColor,\n colWidth,\n trackHeight,\n offsetX,\n blockSize: blockSizeX,\n })\n break\n }\n case 'ruler': {\n const { relativeTo, numColumns } = model\n drawColumnRuler({\n ctx,\n numColumns,\n // with relativeTo set, number by the reference row's residues\n label: relativeTo\n ? col => {\n const pos = model.visibleColToSeqPosOneBased(relativeTo, col)\n return pos === undefined ? undefined : `${pos}`\n }\n : col => `${col + 1}`,\n textColor,\n colWidth,\n trackHeight,\n offsetX,\n blockSize: blockSizeX,\n })\n break\n }\n case 'text': {\n const { bgColor, fontSize, rowHeight, showMsaLetters } = model\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n setFontSize(ctx, fontSize)\n drawTextTrackContent({\n ctx,\n data,\n colorScheme: customColorScheme ?? model.colorScheme,\n contrastText: contrastTextFn(theme),\n bgColor,\n drawLetters: showMsaLetters,\n colWidth,\n rowHeight,\n offsetX,\n blockSize: blockSizeX,\n })\n break\n }\n }\n\n ctx.resetTransform()\n}\n\n/**\n * Every turned-on track stacked top to bottom, for the SVG export. The live\n * view draws the same content one canvas block at a time in TrackBlocks.\n */\nexport function renderAllTracks({\n model,\n ctx,\n offsetX,\n theme,\n blockSizeXOverride,\n highResScaleFactorOverride,\n}: {\n model: MsaViewModel\n ctx: RenderCtx\n offsetX: number\n theme: Theme\n blockSizeXOverride?: number\n highResScaleFactorOverride?: number\n}) {\n let currentY = 0\n for (const track of model.turnedOnTracks) {\n drawTrackBlock({\n model,\n ctx,\n track,\n offsetX,\n offsetY: currentY,\n theme,\n blockSizeXOverride,\n highResScaleFactorOverride,\n })\n currentY += track.model.height\n }\n}\n", "import React from 'react'\n\n/**\n * The branch-length scale bar: its label over a bracket `bar.px` wide, both\n * resting on `y`.\n */\nexport default function ScaleBarSVG({\n bar,\n marginLeft,\n y,\n color,\n}: {\n bar: { label: string; px: number }\n marginLeft: number\n y: number\n color: string\n}) {\n return (\n <>\n <text x={marginLeft} y={y - 9} fontSize={10} fill={color}>\n {bar.label}\n </text>\n <path\n d={`M${marginLeft} ${y - 7} v6 h${bar.px} v-6`}\n fill=\"none\"\n stroke={color}\n />\n </>\n )\n}\n", "import { setFontSize } from './setFontSize.ts'\n\n// Cached across calls, since both createElement and getContext are far more\n// expensive than measureText.\n// `null` records that this environment has no 2d context, so the lookup is not\n// retried on every label.\nlet ctxHandle: CanvasRenderingContext2D | null | undefined\n\nfunction getCtx() {\n if (ctxHandle === undefined) {\n ctxHandle =\n typeof document === 'undefined'\n ? null\n : document.createElement('canvas').getContext('2d')\n }\n return ctxHandle\n}\n\n/**\n * Rough average glyph width as a fraction of the font size for the sans-serif\n * stack the labels use. measureTextCanvas falls back on it where there is no\n * canvas to measure with (jsdom, SSR), and the headless render environment's\n * `measureText` reports it.\n */\nexport const CHAR_WIDTH_RATIO = 0.6\n\nexport function measureTextCanvas(text: string, fontSize: number) {\n const ctx = getCtx()\n if (!ctx) {\n return text.length * fontSize * CHAR_WIDTH_RATIO\n }\n setFontSize(ctx, fontSize)\n return ctx.measureText(text).width\n}\n", "import { labelFitFontSize } from '../../constants.ts'\nimport { measureTextCanvas } from '../../measureTextCanvas.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { Clade, ResolvedClade } from '../../types.ts'\n\n// The bar of the bracket mark and the space around it, in px.\nexport const bracketBarWidth = 3\nexport const bracketGap = 4\n\n// The widest gutter the bracket mark takes. A longer label is clipped, so one\n// long name cannot squeeze the tree it annotates.\nexport const maxCladeGutterWidth = 140\n\n/** whether a clade draws in the gutter: a bracket, or a highlight with a label */\nexport function cladeInGutter(clade: Pick<Clade, 'mark' | 'label'>) {\n return (\n clade.mark === 'bracket' || (clade.mark === 'highlight' && !!clade.label)\n )\n}\n\n/** the pixel height of the rows a clade covers */\nfunction cladeHeight(clade: ResolvedClade, rowHeight: number) {\n return (clade.rows[1] - clade.rows[0] + 1) * rowHeight\n}\n\n/**\n * Whether a label reads across the rows. It does where they are taller than the\n * font, and runs up the bar where they are not.\n */\nfunction cladeLabelHorizontal(\n clade: ResolvedClade,\n rowHeight: number,\n fontSize: number,\n) {\n return cladeHeight(clade, rowHeight) >= fontSize\n}\n\n/** the px between the left edge of the gutter and the label's own column */\nfunction cladeLabelOffset(clade: Pick<Clade, 'mark'>) {\n return clade.mark === 'bracket'\n ? bracketGap + bracketBarWidth + bracketGap\n : bracketGap\n}\n\n/**\n * The gutter the bracket mark needs at the right of the tree area: the bar plus\n * the widest label read across at labelFitFontSize, zero where no clade draws\n * there, and at most maxCladeGutterWidth. The records size it, so a zoom, a\n * collapse or a focus leaves it as it is, and a renderer clips a label that\n * outgrows it.\n */\nexport function cladeGutterWidth(clades: Pick<Clade, 'mark' | 'label'>[]) {\n let widest = 0\n for (const clade of clades) {\n if (!cladeInGutter(clade)) {\n continue\n }\n const text = clade.label\n ? measureTextCanvas(clade.label, labelFitFontSize)\n : 0\n widest = Math.max(widest, cladeLabelOffset(clade) + text + bracketGap)\n }\n // a whole pixel, so the room the renderers measure against covers the label\n // the measurement here sized the gutter for\n return Math.min(maxCladeGutterWidth, Math.ceil(widest))\n}\n\n/**\n * The box each gutter label takes, in unscrolled tree-area px: from the\n * label's column to the right edge of the gutter, across the clade's rows. The\n * live view sets DOM text in it, and the SVG export a `<text>`.\n */\nexport function cladeLabelBoxes(\n model: Pick<\n MsaViewModel,\n | 'resolvedClades'\n | 'cladeGutterWidth'\n | 'rowHeight'\n | 'effectiveTreeAreaWidth'\n | 'fontSize'\n >,\n) {\n const {\n resolvedClades,\n cladeGutterWidth,\n rowHeight,\n effectiveTreeAreaWidth,\n fontSize,\n } = model\n const gutterLeft = effectiveTreeAreaWidth - cladeGutterWidth\n return cladeGutterWidth === 0\n ? []\n : resolvedClades.flatMap((clade, index) => {\n const { label, markColor, rows } = clade\n if (!label || !cladeInGutter(clade)) {\n return []\n }\n const left = gutterLeft + cladeLabelOffset(clade)\n return [\n {\n key: `${rows[0]}-${rows[1]}-${index}`,\n label,\n color: markColor,\n left,\n top: rows[0] * rowHeight,\n width: effectiveTreeAreaWidth - left - bracketGap,\n height: cladeHeight(clade, rowHeight),\n horizontal: cladeLabelHorizontal(clade, rowHeight, fontSize),\n },\n ]\n })\n}\n", "const ellipsis = '\u2026'\n\n/**\n * the longest prefix of `text`, plus an ellipsis, that measures at most\n * `room` px\n */\nexport function ellipsize(\n measure: (text: string) => number,\n text: string,\n room: number,\n) {\n const width = measure(text)\n if (width <= room) {\n return { text, width }\n }\n for (let n = Math.floor((text.length * room) / width); n > 0; n--) {\n const truncated = text.slice(0, n).trimEnd() + ellipsis\n const truncatedWidth = measure(truncated)\n if (truncatedWidth <= room) {\n return { text: truncated, width: truncatedWidth }\n }\n }\n return { text: '', width: 0 }\n}\n", "import {\n descendants,\n find,\n forEachDescendant,\n forEachLink,\n hierarchy as coreHierarchy,\n leaves,\n links,\n sort,\n sum,\n} from '@gmod/newick'\n\nimport type { NodeWithIds } from './types.ts'\nimport type { HierarchyNode as CoreHierarchyNode } from '@gmod/newick'\n\n/**\n * A hierarchy node plus the fields this viewer hangs off it during layout.\n *\n * The traversals in `@gmod/newick` are generic over the node type rather than\n * over its data, so they take and return this extended node rather than the base\n * one, and no call site has to cast.\n */\nexport interface HierarchyNode<T = NodeWithIds> extends CoreHierarchyNode<T> {\n children: HierarchyNode<T>[] | null\n parent: HierarchyNode<T> | null\n x?: number\n y?: number\n // the span of `x` over this node's subtree. Leaves are laid out in order, so\n // a subtree occupies one contiguous run of rows and a renderer can skip the\n // whole thing when the run misses its block.\n xMin?: number\n xMax?: number\n len?: number\n depthToLeaf?: number\n _children?: HierarchyNode<T>[] | null\n // pixel x-position of the farthest tip of a collapsed subtree, where the base\n // of the collapsed-clade triangle goes\n collapsedTipXFar?: number\n}\n\n// The @gmod/newick traversals are iterative: a caterpillar tree's depth equals\n// its leaf count, and recursion overflows the stack past about 5000 tips.\nexport {\n descendants,\n find,\n forEachDescendant,\n forEachLink,\n leaves,\n links,\n sort,\n sum,\n}\nexport type { HierarchyLink } from '@gmod/newick'\n\n// declares the wider return type so the layout code can assign the optional\n// fields above onto coreHierarchy's nodes\nexport function hierarchy<T>(\n data: T,\n childrenAccessor: (d: T) => T[] | undefined,\n): HierarchyNode<T> {\n return coreHierarchy(data, childrenAccessor)\n}\n\nexport interface TreeScale {\n readonly rowHeight: number\n readonly treeWidth: number\n}\n\ninterface LayoutFrame {\n scale: TreeScale\n rootToTipLength: number\n}\n\n/**\n * A node of `layoutTree`: its source node's fields plus its place in unit\n * space, rows down and branch length across. The pixel getters multiply by the\n * scale on every read, so a zoom leaves the nodes valid, and an observer\n * reading `x` observes whatever the scale reads.\n */\nexport class LaidOutNode<T> implements HierarchyNode<T> {\n data: T\n depth: number\n height: number\n value?: number\n children: LaidOutNode<T>[] | null\n depthToLeaf = 0\n row = 0\n rowMin = 0\n rowMax = 0\n depthFraction = 0\n branchLength = 0\n collapsedBranchLength?: number\n\n constructor(\n source: HierarchyNode<T>,\n readonly parent: LaidOutNode<T> | null,\n private readonly frame: LayoutFrame,\n ) {\n this.data = source.data\n this.depth = source.depth\n this.height = source.height\n this.value = source.value\n this.children = source.children ? [] : null\n }\n\n private get pxPerBranchLength() {\n const { scale, rootToTipLength } = this.frame\n return rootToTipLength ? scale.treeWidth / rootToTipLength : 0\n }\n\n get x() {\n return this.row * this.frame.scale.rowHeight\n }\n\n get xMin() {\n return this.rowMin * this.frame.scale.rowHeight\n }\n\n get xMax() {\n return this.rowMax * this.frame.scale.rowHeight\n }\n\n get y() {\n return this.depthFraction * this.frame.scale.treeWidth\n }\n\n get len() {\n return this.branchLength * this.pxPerBranchLength\n }\n\n get collapsedTipXFar() {\n return this.collapsedBranchLength === undefined\n ? undefined\n : this.collapsedBranchLength * this.pxPerBranchLength\n }\n}\n\n/**\n * The tree laid out on new nodes: tips one row apart, a parent at the mean of\n * its children, and branch length measured from the root, whose own branch is\n * not drawn. A collapsed node records the farthest tip of its hidden subtree,\n * where the base of its triangle goes.\n */\nexport function layoutTree<T extends { length?: number }>(\n root: HierarchyNode<T>,\n scale: TreeScale,\n) {\n const frame: LayoutFrame = { scale, rootToTipLength: 0 }\n const nodes: LaidOutNode<T>[] = []\n const leafNodes: LaidOutNode<T>[] = []\n const rootHeight = root.height\n const stack: { source: HierarchyNode<T>; parent: LaidOutNode<T> | null }[] = [\n { source: root, parent: null },\n ]\n while (stack.length > 0) {\n const { source, parent } = stack.pop()!\n const node = new LaidOutNode(source, parent, frame)\n nodes.push(node)\n node.depthFraction =\n rootHeight === 0 ? 1 : (source.depth - root.depth) / rootHeight\n if (parent) {\n parent.children!.push(node)\n node.branchLength =\n parent.branchLength + Math.max(source.data.length || 0, 0)\n frame.rootToTipLength = Math.max(frame.rootToTipLength, node.branchLength)\n }\n if (source._children) {\n node.collapsedBranchLength =\n node.branchLength + collapsedSubtreeMaxLength(source)\n }\n if (source.children) {\n for (let i = source.children.length - 1; i >= 0; i--) {\n stack.push({ source: source.children[i]!, parent: node })\n }\n } else {\n node.row = leafNodes.length + 0.5\n node.depthToLeaf = source.depthToLeaf ?? 0\n leafNodes.push(node)\n }\n }\n\n for (let i = nodes.length - 1; i >= 0; i--) {\n const node = nodes[i]!\n if (node.children) {\n let sum = 0\n let min = Infinity\n let max = -Infinity\n let depthToLeaf = 0\n for (const child of node.children) {\n sum += child.row\n min = Math.min(min, child.rowMin)\n max = Math.max(max, child.rowMax)\n depthToLeaf = Math.max(depthToLeaf, 1 + child.depthToLeaf)\n }\n node.row = sum / node.children.length\n node.rowMin = min\n node.rowMax = max\n node.depthToLeaf = depthToLeaf\n } else {\n node.rowMin = node.row\n node.rowMax = node.row\n }\n }\n return {\n root: nodes[0]!,\n leaves: leafNodes,\n rootToTipLength: frame.rootToTipLength,\n }\n}\n\nexport function collapse<T>(node: HierarchyNode<T>) {\n if (node.children) {\n // memoize the real subtree depth onto the node before detaching its\n // children, so cladogram positioning keeps the node (now the apex of a\n // collapsed-clade triangle) at its true branch point rather than snapping\n // it to the tip-alignment line. This also keeps the rest of the tree's\n // horizontal layout stable when a clade is collapsed.\n calcDepthToLeaf(node)\n node._children = node.children\n node.children = null\n }\n}\n\n// Cumulative raw branch length from a collapsed node down to the farthest tip of\n// its detached subtree (excludes the node's own branch). Sizes the base of the\n// collapsed-clade triangle in phylogram mode.\nexport function collapsedSubtreeMaxLength<T extends { length?: number }>(\n node: HierarchyNode<T>,\n) {\n const roots = node._children ?? node.children\n let max = 0\n if (roots) {\n const stack = roots.map(child => ({\n node: child,\n acc: Math.max(child.data.length ?? 0, 0),\n }))\n while (stack.length > 0) {\n const { node: n, acc } = stack.pop()!\n const kids = n.children ?? n._children\n if (kids?.length) {\n for (const child of kids) {\n stack.push({\n node: child,\n acc: acc + Math.max(child.data.length ?? 0, 0),\n })\n }\n } else {\n max = Math.max(max, acc)\n }\n }\n }\n return max\n}\n\n// Cladogram positioning based on ape's plot.phylo: uses topological depth (max\n// steps to a tip) instead of branch length so all leaves align at the rightmost\n// x. Memoizes onto node.depthToLeaf since the layout walks the tree repeatedly.\n// See https://github.com/emmanuelparadis/ape/blob/master/R/plot.phylo.R\nexport function calcDepthToLeaf<T>(node: HierarchyNode<T>): number {\n // the memo check has to guard the traversal, not just the arithmetic: the tree\n // renderer asks for the depth of every node on every pass, and re-walking each\n // subtree makes that quadratic (a 5000-tip caterpillar tree spent >1s per draw\n // here). Once a node is memoized so are all of its descendants.\n if (node.depthToLeaf === undefined) {\n const nodes = descendants(node)\n for (let i = nodes.length - 1; i >= 0; i--) {\n const n = nodes[i]!\n if (n.depthToLeaf === undefined) {\n let maxDepth = 0\n if (n.children) {\n for (const child of n.children) {\n maxDepth = Math.max(maxDepth, 1 + child.depthToLeaf!)\n }\n }\n n.depthToLeaf = maxDepth\n }\n }\n }\n return node.depthToLeaf!\n}\n\n/**\n * Every leaf by name, with a name two leaves share mapping to undefined: a tip\n * set naming it cannot say which tip it means.\n */\nexport function leafIndex<T extends { name: string }>(root: HierarchyNode<T>) {\n const index = new Map<string, HierarchyNode<T> | undefined>()\n for (const leaf of leaves(root)) {\n const { name } = leaf.data\n index.set(name, index.has(name) ? undefined : leaf)\n }\n return index\n}\n\n/**\n * The most recent common ancestor of a set of tip names, or undefined when a\n * name is not a tip of this tree or names two of them.\n *\n * Each name lifts through `parent` to the ancestor the names before it share,\n * so the walk holds two nodes. Recording a root-to-tip path per name instead\n * costs the depth in memory per name, and a caterpillar tree's depth is its tip\n * count. `index` is `leafIndex(root)`, which a caller resolving several tip\n * sets against one tree builds once.\n */\nexport function mrca<T extends { name: string }>(\n root: HierarchyNode<T>,\n names: string[],\n index = leafIndex(root),\n) {\n let node: HierarchyNode<T> | undefined\n for (const name of names) {\n let other = index.get(name)\n if (!other) {\n return undefined\n }\n if (!node) {\n node = other\n continue\n }\n while (node.depth > other.depth) {\n node = node.parent!\n }\n while (other.depth > node.depth) {\n other = other.parent!\n }\n while (node !== other) {\n node = node.parent!\n other = other.parent!\n }\n }\n return node\n}\n\n/**\n * The deepest node whose subtree covers a run of rows, given in the row-space\n * coordinates layoutTree writes to xMin/xMax. A subtree's leaves are one\n * contiguous run, so at most one child per level covers the run and the descent\n * visits the tree's depth rather than its nodes.\n */\nexport function nodeCoveringRows<T>(\n root: HierarchyNode<T>,\n top: number,\n bottom: number,\n) {\n let node = root\n for (;;) {\n const child = node.children?.find(c => c.xMin! <= top && c.xMax! >= bottom)\n if (!child) {\n return node\n }\n node = child\n }\n}\n", "import { calcDepthToLeaf, nodeCoveringRows } from '../../hierarchy.ts'\nimport { setFontSize } from '../../setFontSize.ts'\nimport { getVisibleLeaves } from '../getVisibleLeaves.ts'\nimport {\n drawHighlightLabel,\n highlightLabelHeight,\n highlightRowFill,\n} from '../msa/renderHighlights.ts'\nimport { referenceColor } from '../overlayColors.ts'\nimport { bracketBarWidth, bracketGap } from './cladeBrackets.ts'\nimport { ellipsize } from './ellipsize.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { LabelBox } from '../msa/renderHighlights.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { ClickMapIndex } from './clickMap.ts'\nimport type { Theme } from '@mui/material'\n\nconst radius = 2.5\nconst d = radius * 2\n\n// How far outside a block a node's row-center can sit and still draw into it: a\n// collapsed triangle reaches 0.42 rows each way, a tip label an em, and a\n// highlight label its whole box. Five pixels clipped all three at block edges.\nfunction blockPad(model: MsaViewModel) {\n return Math.max(model.rowHeight, highlightLabelHeight)\n}\n\n// whether a node's row-center y falls within the block being drawn, padded so\n// bubbles/labels/triangles straddling the edge still render\nfunction inYBlock(y: number, offsetY: number, by: number, pad: number) {\n return y > offsetY - pad && y < offsetY + by + pad\n}\n\n/**\n * Every node whose subtree reaches into the block, skipping the subtrees that\n * do not. A subtree's leaves are one contiguous run of rows, recorded by\n * layoutTree as xMin/xMax, so a block of a 200k-tip tree visits a few dozen\n * nodes.\n *\n * A link out of a visited node is drawn even when its child is pruned, so a\n * branch crossing the block stays visible.\n */\nfunction forEachNodeInBlock(\n root: HierarchyNode,\n offsetY: number,\n by: number,\n pad: number,\n cb: (node: HierarchyNode) => void,\n) {\n const top = offsetY - pad\n const bottom = offsetY + by + pad\n const stack = [root]\n while (stack.length > 0) {\n const node = stack.pop()!\n if (node.xMax! < top || node.xMin! > bottom) {\n continue\n }\n cb(node)\n if (node.children) {\n for (const child of node.children) {\n stack.push(child)\n }\n }\n }\n}\n\n// withId gives an unnamed node its path, node-0-1-1, as its name\nfunction cladeName(node: HierarchyNode, unnamed: string) {\n const { id, name } = node.data\n const label = name === id ? unnamed : name\n return node.value === undefined ? label : `${label} (${node.value} tips)`\n}\n\n// Calculate node x-coordinate for both phylogram (with branch lengths) and\n// cladogram (topology only) modes. tipX is the pixel x the tips sit at.\n// For cladograms: x = (maxDepthToLeaf - nodeDepthToLeaf) / maxDepthToLeaf * tipX\n// This positions: leaves at tipX (rightmost), root at 0 (leftmost), internal nodes proportionally in between\n// Matches ape's: xx <- max(xx) - xx (where xx is depth from each node to tips)\nexport function getNodeX(\n node: HierarchyNode,\n showBranchLen: boolean,\n tipX: number,\n maxDepthToLeaf: number,\n): number | undefined {\n if (showBranchLen) {\n return node.len\n }\n if (maxDepthToLeaf === 0) {\n return 0\n }\n const depthToLeaf = calcDepthToLeaf(node)\n return ((maxDepthToLeaf - depthToLeaf) / maxDepthToLeaf) * tipX\n}\n\nfunction renderTree({\n offsetY,\n ctx,\n model,\n theme,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n}: {\n offsetY: number\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n}) {\n const {\n hierarchy,\n showBranchLenEffective: showBranchLen,\n blockSize,\n branchColors,\n } = model\n const by = blockSizeYOverride ?? blockSize\n const defaultStroke = theme.palette.text.primary\n ctx.strokeStyle = defaultStroke\n forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), source => {\n const sy = source.x!\n const sx = getNodeX(source, showBranchLen, tipX, maxDepthToLeaf)\n if (sx === undefined || !source.children) {\n return\n }\n for (const target of source.children) {\n const ty = target.x!\n const tx = getNodeX(target, showBranchLen, tipX, maxDepthToLeaf)\n if (tx === undefined) {\n continue\n }\n const y1 = Math.min(sy, ty)\n const y2 = Math.max(sy, ty)\n // 1d line intersection to check if line crosses block at all, this is an\n // optimization that allows us to skip drawing most tree links outside the\n // block\n if (offsetY + by >= y1 && y2 >= offsetY) {\n // the edge belongs to the child, whose id the branch channel colors\n if (branchColors) {\n ctx.strokeStyle = branchColors.get(target.data.id) ?? defaultStroke\n }\n ctx.beginPath()\n ctx.moveTo(sx, sy)\n ctx.lineTo(sx, ty)\n ctx.lineTo(tx, ty)\n ctx.stroke()\n }\n }\n })\n ctx.strokeStyle = defaultStroke\n}\n\nfunction renderCollapsedTriangles({\n ctx,\n clickMap,\n offsetY,\n model,\n theme,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n}: {\n ctx: RenderCtx\n clickMap?: ClickMapIndex\n offsetY: number\n model: MsaViewModel\n theme: Theme\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n collapsedSet: Set<string>\n}) {\n const {\n hierarchy,\n showBranchLenEffective: showBranchLen,\n blockSize,\n rowHeight,\n fontSize,\n marginLeft: ml,\n branchColors,\n } = model\n // nothing collapsed is the common case, and the traversal below visits every\n // node in the tree on every block of every redraw\n if (collapsedSet.size === 0) {\n return\n }\n const by = blockSizeYOverride ?? blockSize\n const halfHeight = Math.max(2, rowHeight * 0.42)\n forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), node => {\n const { id } = node.data\n if (collapsedSet.has(id)) {\n const apexX = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)\n const y = node.x!\n const inBlock = inYBlock(y, offsetY, by, blockPad(model))\n // in cladogram mode the hidden tips align at the right edge, otherwise use\n // the branch-length extent recorded in the model's hierarchy getter\n const baseX = showBranchLen ? (node.collapsedTipXFar ?? tipX) : tipX\n if (apexX !== undefined && inBlock && baseX > apexX) {\n ctx.beginPath()\n ctx.moveTo(apexX, y)\n ctx.lineTo(baseX, y - halfHeight)\n ctx.lineTo(baseX, y + halfHeight)\n ctx.closePath()\n ctx.fillStyle = branchColors?.get(id) ?? theme.palette.action.disabled\n ctx.fill()\n ctx.strokeStyle = theme.palette.text.primary\n ctx.stroke()\n\n // node.value carries the leaf count from the pre-collapse sum() pass\n const count = node.value\n if (count !== undefined && rowHeight >= 8) {\n ctx.fillStyle = theme.palette.text.primary\n ctx.textAlign = 'left'\n ctx.fillText(`${count}`, baseX + 3, y + fontSize / 4)\n }\n\n // the whole triangle is a click/hover target that opens the\n // branch menu (Expand this node); the apex bubble's own click entry is\n // skipped for collapsed nodes so this descriptive label wins\n clickMap?.insert({\n minX: apexX + ml,\n maxX: baseX + ml,\n minY: y - halfHeight,\n maxY: y + halfHeight,\n branch: true,\n id,\n name: cladeName(node, 'Collapsed clade'),\n })\n }\n }\n })\n}\n\n// the bubbles are click targets whether or not they are painted, so this pass\n// always runs and `draw` only decides whether it also strokes the circles\nfunction renderNodeBubbles({\n ctx,\n theme,\n clickMap,\n offsetY,\n model,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n draw,\n}: {\n ctx: RenderCtx\n clickMap?: ClickMapIndex\n offsetY: number\n model: MsaViewModel\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n collapsedSet: Set<string>\n draw: boolean\n theme: Theme\n}) {\n const {\n hierarchy,\n showBranchLenEffective: showBranchLen,\n blockSize,\n marginLeft: ml,\n } = model\n const by = blockSizeYOverride ?? blockSize\n forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), node => {\n const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)\n if (x === undefined) {\n return\n }\n const { data } = node\n const y = node.x!\n const { id } = data\n if (node.height >= 1 && inYBlock(y, offsetY, by, blockPad(model))) {\n const isCollapsed = collapsedSet.has(id)\n if (draw) {\n ctx.strokeStyle = theme.palette.text.primary\n ctx.fillStyle = isCollapsed\n ? theme.palette.text.primary\n : theme.palette.background.default\n ctx.beginPath()\n ctx.arc(x, y, radius, 0, 2 * Math.PI)\n ctx.fill()\n ctx.stroke()\n }\n\n // collapsed nodes get their click/hover target from the triangle pass,\n // which covers the apex bubble and carries a descriptive label\n if (!isCollapsed) {\n clickMap?.insert({\n minX: x - radius + ml,\n maxX: x - radius + d + ml,\n minY: y - radius,\n maxY: y - radius + d,\n branch: true,\n id,\n name: cladeName(node, 'Clade'),\n })\n }\n }\n })\n}\n\n// The label a newick file puts on an internal node, which is where a bootstrap\n// or posterior support value lands: ((A,B)95,(C,D)80);. withId falls back to the\n// path-derived id for an unnamed node, so a node whose name is its id has no\n// label of its own and an ungated pass prints node-0-1-1 across the tree.\nfunction renderNodeLabels({\n ctx,\n theme,\n offsetY,\n model,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n}: {\n ctx: RenderCtx\n theme: Theme\n offsetY: number\n model: MsaViewModel\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n}) {\n const {\n hierarchy,\n showBranchLenEffective: showBranchLen,\n blockSize,\n fontSize,\n } = model\n const by = blockSizeYOverride ?? blockSize\n const pad = blockPad(model)\n setFontSize(ctx, Math.max(6, fontSize - 3))\n ctx.fillStyle = theme.palette.text.primary\n ctx.textAlign = 'right'\n forEachNodeInBlock(hierarchy, offsetY, by, pad, node => {\n const { id, name } = node.data\n if (node.height < 1 || name === id) {\n return\n }\n const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)\n const y = node.x!\n if (x !== undefined && inYBlock(y, offsetY, by, pad)) {\n ctx.fillText(name, x - radius - 1, y - radius - 1)\n }\n })\n ctx.textAlign = 'start'\n setFontSize(ctx, fontSize)\n}\n\nfunction renderTreeLabels({\n theme,\n model,\n offsetY,\n ctx,\n clickMap,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n}: {\n model: MsaViewModel\n offsetY: number\n ctx: RenderCtx\n clickMap?: ClickMapIndex\n theme: Theme\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n collapsedSet: Set<string>\n}) {\n const {\n fontSize,\n showBranchLenEffective: showBranchLen,\n tipLabelColors,\n blockSize,\n labelsAlignRight,\n drawTree,\n treeAreaWidthMinusMargin,\n marginLeft,\n noTree,\n } = model\n const treeDrawn = drawTree && !noTree\n const by = blockSizeYOverride ?? blockSize\n // labels only exist for leaves, which are laid out top to bottom, so take the\n // same slice the MSA renderer uses instead of walking every tip per block\n const visibleLeaves = getVisibleLeaves({ model, offsetY, blockSizeY: by })\n const pad = blockPad(model)\n const emHeight = ctx.measureText('M').width\n if (labelsAlignRight) {\n ctx.textAlign = 'right'\n ctx.setLineDash([1, 3])\n ctx.strokeStyle = theme.palette.text.primary\n } else {\n ctx.textAlign = 'start'\n }\n for (const node of visibleLeaves) {\n const {\n data: { name, id },\n } = node\n const y = node.x!\n\n const displayName = model.rowDataOf(name)?.genome || name\n // a collapsed clade is drawn as a triangle + tip count; suppress its leaf\n // label when the \"name\" is just the auto-generated internal-node id\n const isAnonymousCollapsed = collapsedSet.has(id) && name === id\n if (!isAnonymousCollapsed && inYBlock(y, offsetY, by, pad)) {\n // fontSize/4 below the row center, the baseline the alignment letters\n // share\n const yp = y + fontSize / 4\n const xp = treeDrawn\n ? (getNodeX(node, showBranchLen, tipX, maxDepthToLeaf) ?? 0)\n : 0\n const fit = (room: number) =>\n ellipsize(text => ctx.measureText(text).width, displayName, room)\n // a label cut to nothing still gets a click box the font size wide\n const boxWidth = (width: number) => Math.max(width, fontSize)\n\n ctx.fillStyle = tipLabelColors?.get(name) ?? theme.palette.text.primary\n if (labelsAlignRight) {\n const smallPadding = 2\n const offset = treeAreaWidthMinusMargin - smallPadding\n const { text, width } = fit(\n offset - (treeDrawn ? xp + radius + 2 + smallPadding : 0),\n )\n if (treeDrawn) {\n // beginPath is load-bearing: without it every leader line re-strokes\n // all the ones before it, which is quadratic in the label count\n ctx.beginPath()\n ctx.moveTo(xp + radius + 2, y)\n ctx.lineTo(offset - smallPadding - width, y)\n ctx.stroke()\n }\n ctx.fillText(text, offset, yp)\n // everything here is drawn under translate(marginLeft), so the click box\n // has to be the text's own right edge in that same space -- taking\n // the tree area width instead put the target smallPadding off the label\n const labelRight = offset + marginLeft\n clickMap?.insert({\n minX: labelRight - boxWidth(width),\n maxX: labelRight,\n minY: yp - emHeight,\n maxY: yp,\n name,\n label: displayName,\n id,\n })\n } else {\n const labelX = treeDrawn ? xp + d : 2\n const { text, width } = fit(treeAreaWidthMinusMargin - labelX)\n ctx.fillText(text, labelX, yp)\n clickMap?.insert({\n minX: labelX + marginLeft,\n maxX: labelX + boxWidth(width) + marginLeft,\n minY: yp - emHeight,\n maxY: yp,\n name,\n label: displayName,\n id,\n })\n }\n }\n }\n ctx.setLineDash([])\n}\n\n// the first row of a set, as a loop: spreading into Math.min passes one\n// argument per row, and the ~125k argument limit throws RangeError on a set\n// covering the 230k-tip COVID tree\nfunction firstRow(rowIndices: number[]) {\n let min = Infinity\n for (const index of rowIndices) {\n if (index < min) {\n min = index\n }\n }\n return min\n}\n\n// the highlight mark of the `clades` layer: a translucent rectangle from the\n// clade's common ancestor to the right edge of the tree area, under the\n// branches. A clade spanning hundreds of rows crosses several blocks, so each\n// block draws the whole rectangle and the canvas takes the part that is its.\nfunction renderCladeHighlights({\n ctx,\n model,\n offsetY,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n offsetY: number\n tipX: number\n maxDepthToLeaf: number\n blockSizeYOverride?: number\n}) {\n const {\n resolvedClades,\n hierarchy,\n showBranchLenEffective: showBranchLen,\n rowHeight,\n effectiveTreeAreaWidth,\n marginLeft,\n blockSize,\n } = model\n const by = blockSizeYOverride ?? blockSize\n const right = effectiveTreeAreaWidth - marginLeft\n for (const { rows, color, mark } of resolvedClades) {\n if (mark !== 'highlight') {\n continue\n }\n const top = rows[0] * rowHeight\n const bottom = (rows[1] + 1) * rowHeight\n if (bottom < offsetY || top > offsetY + by) {\n continue\n }\n const node = nodeCoveringRows(\n hierarchy,\n top + rowHeight / 2,\n bottom - rowHeight / 2,\n )\n const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf) ?? 0\n ctx.fillStyle = color\n ctx.fillRect(x, top, right - x, bottom - top)\n }\n}\n\n// the bar of the bracket mark, in the gutter `cladeGutterWidth` reserves at the\n// right of the tree area. The label beside it is DOM text on screen and a\n// <text> in the export, since the canvas layer has no rotation.\nfunction renderCladeBrackets({\n ctx,\n model,\n theme,\n offsetY,\n blockSizeYOverride,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n offsetY: number\n blockSizeYOverride?: number\n}) {\n const {\n resolvedClades,\n cladeGutterWidth,\n rowHeight,\n effectiveTreeAreaWidth,\n marginLeft,\n blockSize,\n } = model\n if (cladeGutterWidth === 0) {\n return\n }\n const by = blockSizeYOverride ?? blockSize\n const x =\n effectiveTreeAreaWidth -\n marginLeft -\n cladeGutterWidth +\n bracketGap +\n bracketBarWidth / 2\n ctx.lineWidth = bracketBarWidth\n for (const { rows, mark, markColor } of resolvedClades) {\n const top = rows[0] * rowHeight + 1\n const bottom = (rows[1] + 1) * rowHeight - 1\n if (mark !== 'bracket' || bottom < offsetY || top > offsetY + by) {\n continue\n }\n ctx.strokeStyle = markColor ?? theme.palette.text.primary\n ctx.beginPath()\n ctx.moveTo(x, top)\n ctx.lineTo(x, bottom)\n ctx.stroke()\n }\n ctx.lineWidth = 1\n ctx.strokeStyle = theme.palette.text.primary\n}\n\n// the `rowTint` encoding, the reference row and the row sets of `highlights`,\n// washed across the tree area under the labels, with each set's label in the\n// gutter at its first row\nfunction renderRowHighlights({\n ctx,\n model,\n theme,\n offsetY,\n blockSizeYOverride,\n}: {\n ctx: RenderCtx\n model: MsaViewModel\n theme: Theme\n offsetY: number\n blockSizeYOverride?: number\n}) {\n const {\n resolvedHighlights,\n rowTints,\n referenceRowIndex,\n rowHeight,\n effectiveTreeAreaWidth,\n marginLeft,\n blockSize,\n } = model\n const by = blockSizeYOverride ?? blockSize\n const pad = blockPad(model)\n const placed: LabelBox[] = []\n const fillRow = (index: number) => {\n ctx.fillRect(\n -marginLeft,\n index * rowHeight,\n effectiveTreeAreaWidth,\n rowHeight,\n )\n }\n if (rowTints) {\n const top = Math.max(0, Math.floor((offsetY - pad) / rowHeight))\n const bottom = Math.min(\n rowTints.length - 1,\n Math.ceil((offsetY + by + pad) / rowHeight),\n )\n for (let index = top; index <= bottom; index++) {\n const color = rowTints[index]\n if (color) {\n ctx.fillStyle = color\n fillRow(index)\n }\n }\n }\n if (referenceRowIndex !== undefined) {\n ctx.fillStyle = referenceColor\n fillRow(referenceRowIndex)\n }\n for (const { rowIndices, label, color } of resolvedHighlights) {\n ctx.fillStyle = color ?? highlightRowFill\n for (const index of rowIndices) {\n if (inYBlock(index * rowHeight + rowHeight / 2, offsetY, by, pad)) {\n fillRow(index)\n }\n }\n const first = firstRow(rowIndices)\n if (\n label &&\n rowIndices.length &&\n inYBlock(first * rowHeight, offsetY, by, pad)\n ) {\n drawHighlightLabel({\n ctx,\n theme,\n label,\n x: -marginLeft + 2,\n y: first * rowHeight,\n spanWidth: effectiveTreeAreaWidth,\n bounds: { min: -marginLeft, max: effectiveTreeAreaWidth - marginLeft },\n placed,\n })\n }\n }\n}\n\nexport function renderTreeCanvas({\n model,\n clickMap,\n ctx,\n offsetY,\n theme,\n highResScaleFactorOverride,\n blockSizeYOverride,\n}: {\n model: MsaViewModel\n offsetY: number\n ctx: RenderCtx\n clickMap?: ClickMapIndex\n theme: Theme\n highResScaleFactorOverride?: number\n blockSizeYOverride?: number\n}) {\n clickMap?.clear()\n\n // Defer the finish call until after all inserts are done\n const {\n noTree,\n drawTree,\n drawNodeBubbles,\n drawNodeLabels,\n highResScaleFactor,\n fontSize,\n showTreeText,\n marginLeft,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n rowHeight: _rowHeight, // read so the draw autorun re-fires after a zoom change\n } = model\n\n ctx.resetTransform()\n\n const k = highResScaleFactorOverride ?? highResScaleFactor\n ctx.scale(k, k)\n ctx.translate(marginLeft, -offsetY)\n\n setFontSize(ctx, fontSize)\n\n // memoized on the model and shared across the tree/bubble/label passes (and\n // across all tree blocks) rather than re-traversing the hierarchy in each\n const { maxDepthToLeaf, effectiveTreeWidth: tipX } = model\n // built once for all three passes: each of them asks about a different node on\n // every block of every redraw, and `collapsed` is a list\n const collapsedSet = new Set(model.collapsed)\n\n renderCladeHighlights({\n ctx,\n model,\n offsetY,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n })\n renderRowHighlights({ ctx, model, theme, offsetY, blockSizeYOverride })\n setFontSize(ctx, fontSize)\n\n if (!noTree && drawTree) {\n renderTree({\n ctx,\n offsetY,\n model,\n theme,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n })\n\n renderCollapsedTriangles({\n ctx,\n clickMap,\n offsetY,\n model,\n theme,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n })\n\n renderNodeBubbles({\n ctx,\n theme,\n offsetY,\n clickMap,\n model,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n draw: drawNodeBubbles,\n })\n\n if (drawNodeLabels) {\n renderNodeLabels({\n ctx,\n theme,\n offsetY,\n model,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n })\n }\n }\n\n if (showTreeText) {\n renderTreeLabels({\n ctx,\n offsetY,\n model,\n clickMap,\n theme,\n tipX,\n maxDepthToLeaf,\n blockSizeYOverride,\n collapsedSet,\n })\n }\n\n renderCladeBrackets({ ctx, model, theme, offsetY, blockSizeYOverride })\n\n // Finish the index so it's ready for queries\n clickMap?.finish()\n}\n", "import { descendants } from '../../hierarchy.ts'\nimport { makeOffscreenCanvas } from '../msa/msaRaster.ts'\nimport { getNodeX } from './renderTreeCanvas.ts'\n\nimport type { HierarchyNode } from '../../hierarchy.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { RasterCanvas } from '../msa/msaRaster.ts'\nimport type { RenderCtx } from '../renderCtx.ts'\nimport type { Theme } from '@mui/material'\n\n// the tree draws this far inside the band, so a box around the first or the\n// last row keeps both of its edges\nconst pad = 1\n\ninterface OverviewArgs {\n model: MsaViewModel\n ctx: RenderCtx\n theme: Theme\n width: number\n height: number\n}\n\nfunction rowScale(numTips: number, height: number) {\n const inner = height - pad * 2\n return (row: number) => pad + (row / numTips) * inner\n}\n\n/**\n * The whole tree at the size of the overview band, with the clade highlights\n * under it.\n *\n * A branch that moves less than a pixel on both axes is dropped. The 230k-tip\n * COVID tree has 460k of them over a 120px band, and the ones landing on the\n * pixel their parent already covers cost a path segment each and change no\n * pixel; the test in renderTreeOverview.test.ts measures a 200k-tip tree.\n */\nexport function drawTreeOverview({\n model,\n ctx,\n theme,\n width,\n height,\n}: OverviewArgs) {\n const layout = model.treeOverviewLayout\n if (!layout) {\n return\n }\n const { root, numTips, maxDepthToLeaf, showBranchLen } = layout\n const innerWidth = width - pad * 2\n const rowY = rowScale(numTips, height)\n const nodeX = (node: HierarchyNode) =>\n pad + (getNodeX(node, showBranchLen, 1, maxDepthToLeaf) ?? 0) * innerWidth\n\n for (const { rows, color } of model.treeOverviewClades) {\n ctx.fillStyle = color\n ctx.fillRect(0, rowY(rows[0]), width, rowY(rows[1] + 1) - rowY(rows[0]))\n }\n\n ctx.strokeStyle = theme.palette.text.primary\n ctx.beginPath()\n for (const source of descendants(root)) {\n if (!source.children) {\n continue\n }\n const sx = nodeX(source)\n const sy = rowY(source.x)\n for (const target of source.children) {\n const tx = nodeX(target)\n const ty = rowY(target.x)\n if (Math.abs(tx - sx) < 1 && Math.abs(ty - sy) < 1) {\n continue\n }\n ctx.moveTo(sx, sy)\n ctx.lineTo(sx, ty)\n ctx.lineTo(tx, ty)\n }\n }\n ctx.stroke()\n}\n\n/**\n * A box across the overview around a run of tip rows: the focused subtree's\n * extent, or the one a hovered pixel would focus.\n */\nexport function drawTreeOverviewBox({\n model,\n ctx,\n color,\n rows,\n width,\n height,\n}: Omit<OverviewArgs, 'theme'> & {\n color: string\n rows: [number, number]\n}) {\n const layout = model.treeOverviewLayout\n if (!layout) {\n return\n }\n const rowY = rowScale(layout.numTips, height)\n const top = rowY(rows[0])\n ctx.strokeStyle = color\n ctx.strokeRect(0.5, top, width - 1, Math.max(2, rowY(rows[1] + 1) - top))\n}\n\n/**\n * The overview as the figure carries it: the tree, the clade highlights and\n * the focus box. The SVG export draws it straight onto a svgcanvas Context,\n * and the live canvas blits `treeOverviewImage` in place of the first two.\n */\nexport function renderTreeOverview(args: OverviewArgs) {\n drawTreeOverview(args)\n const rows = args.model.treeOverviewFocusRows\n if (rows) {\n drawTreeOverviewBox({\n ...args,\n rows,\n color: args.theme.palette.text.primary,\n })\n }\n}\n\ninterface OverviewCache {\n keys: unknown[]\n canvas: RasterCanvas | undefined\n}\n\nconst caches = new WeakMap<object, OverviewCache>()\n\n/**\n * Everything the drawn tree depends on. `treeOverviewLayout` and\n * `treeOverviewClades` are computed views, which recompute on every read\n * outside a reaction, so the key holds the values behind them instead.\n */\nfunction overviewKeys({\n model,\n theme,\n width,\n height,\n scale,\n}: {\n model: MsaViewModel\n theme: Theme\n width: number\n height: number\n scale: number\n}) {\n return [\n model.data.tree,\n model.data.msa,\n model.currentAlignment,\n model.collapsed.join(','),\n JSON.stringify(model.clades),\n model.showBranchLen,\n width,\n height,\n scale,\n theme.palette.text.primary,\n ]\n}\n\nfunction canStroke(ctx: unknown): ctx is CanvasRenderingContext2D {\n return typeof (ctx as CanvasRenderingContext2D | null)?.stroke === 'function'\n}\n\n/**\n * The tree and its clade highlights on an offscreen canvas, drawn once per\n * change of anything they depend on and blitted every frame after that. A\n * 230k-branch tree takes hundreds of milliseconds to walk and cannot be redrawn\n * as the focus box follows the pointer.\n *\n * Returns undefined where a canvas has no 2d context (jsdom), and the caller\n * then draws the tree itself.\n */\nexport function treeOverviewImage({\n model,\n theme,\n width,\n height,\n scale,\n}: {\n model: MsaViewModel\n theme: Theme\n width: number\n height: number\n scale: number\n}) {\n const keys = overviewKeys({ model, theme, width, height, scale })\n const prev = caches.get(model)\n if (prev && keys.every((key, i) => key === prev.keys[i])) {\n return prev.canvas\n }\n const made = makeOffscreenCanvas(\n Math.max(1, Math.round(width * scale)),\n Math.max(1, Math.round(height * scale)),\n canStroke,\n )\n if (made) {\n made.ctx.scale(scale, scale)\n drawTreeOverview({ model, ctx: made.ctx, theme, width, height })\n }\n const next = { keys, canvas: made?.canvas }\n caches.set(model, next)\n return next.canvas\n}\n", "import { colord } from 'colord'\nimport { flushSync } from 'react-dom'\nimport { createRoot } from 'react-dom/client'\n\nimport type React from 'react'\n\n/**\n * Render a React element to a static markup string, for the SVG export.\n *\n * Inlined because core removed `renderToStaticMarkup` from the\n * `@jbrowse/core/util` barrel in jbrowse-components 0d034e2bd8; see the\n * `@jbrowse/core` note in CLAUDE.md. `react-dom` and `react-dom/client` are\n * host externals, so this adds a few hundred bytes to the plugin bundle and no\n * duplicate react.\n */\nexport function renderToStaticMarkup(node: React.ReactElement) {\n const div = document.createElement('div')\n const root = createRoot(div)\n let html: string\n try {\n flushSync(() => {\n root.render(node)\n })\n html = div.innerHTML\n } finally {\n // effects run in a client root, so every `observer` holds a MobX reaction;\n // a mounted export of a large alignment would keep tens of thousands of\n // detached nodes re-rendering on every pan and zoom\n root.unmount()\n }\n return html\n}\n\nconst tag = /<[a-zA-Z][^>]*>/g\nconst colorAttr = /\\b(fill|stroke|stop-color)=\"([^\"]+)\"/g\n\n/**\n * Rewrites every color an SVG 1.1 presentation attribute cannot hold.\n *\n * `fill`, `stroke` and `stop-color` take a keyword, a hex triplet or rgb(). MUI\n * palette values use rgba() and the percent-identity scheme uses hsl(), and\n * Illustrator and older Inkscape drop an element whose fill they cannot parse.\n * Alpha moves to the matching -opacity attribute unless the element already\n * carries one.\n */\nexport function svgSafeColors(html: string) {\n return html.replaceAll(tag, el =>\n el.replaceAll(colorAttr, (match, attr: string, value: string) => {\n if (!/^(rgba|hsl)/i.test(value)) {\n return match\n }\n const color = colord(value)\n if (!color.isValid()) {\n return match\n }\n const alpha = color.alpha()\n const hex = color.alpha(1).toHex()\n return alpha === 1 || el.includes(`${attr}-opacity=`)\n ? `${attr}=\"${hex}\"`\n : `${attr}=\"${hex}\" ${attr}-opacity=\"${alpha}\"`\n }),\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["require_mobx", "__commonJSMin", "exports", "module", "require_react_dom", "__commonJSMin", "exports", "module", "require_client", "__commonJSMin", "exports", "module", "import_react", "import_mobx", "visibleRowRange", "model", "offsetY", "blockSizeY", "rowHeight", "getVisibleLeaves", "yStart", "yEnd", "import_react", "import_react", "import_material", "import_react", "useDragScroll", "axis", "onScroll", "scheduled", "mouseDown", "setMouseDown", "onMove", "event", "client", "startClient", "startScroll", "onUp", "scrollbarThumbFill", "hitSlop", "variants", "theme", "axis", "DragHandle", "variant", "getStart", "onDrag", "style", "hovered", "setHovered", "startDrag", "useDragScroll", "fill", "fillHovered", "cursor", "position", "zIndex", "React", "event", "tileColorFn", "model", "dynamicColorSchemeName", "colClustalX", "col", "letter", "colConsensus", "consensus", "colorScheme", "_col", "tileColorTable", "rasterTileSize", "maxCachedTiles", "maxThumbnailColumns", "maxColorCacheEntries", "littleEndian", "packRgba", "r", "g", "b", "a", "scratch", "colorCache", "cssColorToPixel", "css", "hit", "makeRasterCanvas", "packed", "cellPixelFn", "spec", "toPixel", "columns", "relativeTo", "colorAt", "bg", "hover", "bgPixel", "hoverPixel", "reference", "name", "col", "letter", "color", "rasterPixels", "col0", "row0", "width", "height", "colStep", "rowStep", "colSpan", "rowSpan", "out", "averagePixels", "rowNames", "cellPixel", "str", "base", "c", "cells", "rShift", "gShift", "bShift", "aShift", "names", "strs", "dr", "sumR", "sumG", "sumB", "sumA", "i", "dc", "p", "usableRasterCtx", "ctx", "makeOffscreenCanvas", "usable", "settings", "canvas", "paint", "fill", "made", "image", "supported", "rasterApplies", "model", "caches", "rasterKeys", "theme", "tileColorTable", "getCache", "keys", "prev", "key", "next", "node", "tileColorFn", "cellsPerPixel", "devicePixelsPerCell", "getTile", "cache", "tileRow", "tileCol", "stale", "drawMsaRaster", "offsetX", "offsetY", "colWidth", "rowHeight", "blockSize", "highResScaleFactor", "pixelWidth", "pixelHeight", "tileWidth", "tileHeight", "firstCol", "lastCol", "firstRow", "lastRow", "tile", "canvasHref", "maxImagePixels", "maxImageSide", "rasterImageHref", "numCols", "numRows", "msaThumbnail", "numColumns", "w", "h", "getMinimapLayout", "model", "scrollX", "minimapHeight", "totalWidth", "msaCanvasWidth", "unit", "s", "w", "polygonHeight", "polygonPoints", "MinimapSVG", "model", "theme", "msaCanvasWidth", "s", "w", "polygonPoints", "getMinimapLayout", "href", "canvasHref", "msaThumbnail", "React", "scrollbarThumbFill", "r", "t", "n", "u", "e", "o", "a", "i", "s", "d", "h", "b", "f", "g", "c", "v", "l", "p", "m", "y", "N", "x", "M", "H", "$", "j", "w", "k", "r", "y", "u", "E", "R", "q", "w", "n", "i", "t", "e", "o", "g", "p", "c", "A", "C", "D", "$", "o", "t", "r", "n", "a", "i", "e", "v", "u", "d", "e", "f", "a", "d", "l", "i", "n", "o", "t", "b", "c", "g", "u", "r", "D", "e", "r", "contrastAdjustCache", "adjustColorForContrast", "color", "bg", "cacheKey", "cached", "c", "A", "bgIsDark", "i", "result", "withAlpha", "alpha", "parsed", "outlineColor", "fill", "transform", "obj", "cb", "contrastTextCaches", "contrastTextFn", "theme", "cache", "fallback", "hit", "out", "dropBlanks", "blanks", "arr", "set", "_", "skipBlanks", "str", "chunks", "lastEnd", "blankIdx", "computeRowInsertions", "seq", "insertions", "blanksLen", "displayPos", "currentInsertPos", "letterChars", "len", "a", "spanRows", "leaves", "bandsByRow", "rows", "leaf", "bands", "featureSpanMarks", "layout", "xOf", "colors", "labelOf", "labelDrawn", "measureText", "xMin", "xMax", "out", "y", "headLen", "rise", "labelled", "minFeatureLabelHeight", "fontSize", "shapes", "labels", "placed", "band", "xStart", "xEnd", "w", "t", "fill", "stroke", "strand", "head", "geneArrow", "text", "drawFeatureSpans", "ctx", "contrastText", "source", "font", "setFont", "next", "box", "outline", "i", "x", "h", "tip", "tail", "flange", "bottom", "crown", "point", "renderBoxFeatureCanvasBlock", "model", "theme", "offsetX", "offsetY", "ctx", "highResScaleFactorOverride", "blockSizeXOverride", "blockSizeYOverride", "blockSize", "rowHeight", "highResScaleFactor", "actuallyShowDomains", "k", "bx", "by", "drawFeatureSpans", "domainOverlaySource", "getVisibleLeaves", "contrastTextFn", "leaves", "subFeatureRows", "colWidth", "featureColors", "featureLabels", "segmentLabels", "showMsaLetters", "domainUnderline", "domainBands", "barHeight", "labelled", "spanRows", "laneCount", "y", "lane", "h", "band", "setFontSize", "ctx", "fontSize", "bold", "referenceColor", "treeHoverColor", "multiRowHoverColor", "hoverColor", "clickColor", "selectionFill", "selectionBorder", "highlightFill", "highlightBorder", "highlightRowFill", "labelFontSize", "labelPad", "highlightLabelHeight", "drawHighlightLabel", "ctx", "theme", "label", "x", "y", "spanWidth", "bounds", "placed", "setFontSize", "boxWidth", "boxHeight", "left", "top", "overlaps", "box", "renderHighlights", "model", "offsetX", "offsetY", "width", "height", "resolvedClades", "resolvedHighlights", "rowTints", "colWidth", "rowHeight", "firstRow", "lastRow", "fillRow", "index", "rows", "color", "mark", "rowIndices", "startCol", "endCol", "renderSelection", "resolvedSelection", "rowRuns", "w", "first", "last", "h", "selectionFill", "selectionBorder", "renderPersistentHighlights", "referenceRowIndex", "highlightedColumnRuns", "referenceColor", "start", "end", "domainBandCursor", "bands", "next", "active", "col", "band", "top", "visibleColRange", "offsetX", "blockWidth", "colWidth", "renderMSABlock", "model", "offsetX", "offsetY", "ctx", "theme", "highResScaleFactorOverride", "blockSizeXOverride", "blockSizeYOverride", "rasterTiles", "colWidth", "blockSize", "rowHeight", "fontSize", "highResScaleFactor", "actuallyShowDomains", "bgColor", "k", "bx", "by", "setFontSize", "xStart", "xEnd", "visibleColRange", "visibleLeaves", "getVisibleLeaves", "relativeTo", "columns", "referenceSeq", "drawTilesAndText", "drawInsertionIndicators", "drawTiles", "showMsaLetters", "subFeatureRows", "domainUnderline", "domainBandsByStart", "featureColors", "tiles", "paintTiles", "tileColor", "tileColorFn", "contrastText", "contrastTextFn", "offsetXAligned", "halfColWidth", "baselineOffset", "overDomains", "i", "l1", "node", "name", "y", "str", "tileY", "textY", "bandAt", "domainBandCursor", "j", "l2", "col", "letter", "x", "isMatchingReference", "color", "covering", "adjustColorForContrast", "hideGapsEffective", "drawZigZag", "offset", "insertionPositions", "insertions", "pos", "top", "bottom", "currentY", "goRight", "nextY", "nextX", "headerRunsAcross", "panelWidth", "rowPanelHeaderHeight", "rowPadding", "renderFeaturePanel", "ctx", "model", "theme", "panel", "x", "offsetY", "blockSizeYOverride", "highResScaleFactorOverride", "rowHeight", "blockSize", "highResScaleFactor", "by", "k", "drawFeatureSpans", "featurePanelSource", "getVisibleLeaves", "contrastTextFn", "leaves", "spanRows", "laneCount", "y", "lane", "h", "span", "renderStrip", "ctx", "model", "panel", "x", "offsetY", "blockSizeYOverride", "highResScaleFactorOverride", "rowHeight", "blockSize", "highResScaleFactor", "by", "k", "leaf", "getVisibleLeaves", "color", "renderRowPanel", "panel", "rest", "renderFeaturePanel", "renderStrip", "renderRowPanels", "model", "slotOfCode", "c", "letterOfSlot", "_", "slot", "slotOf", "code", "isGapSlot", "ColumnCounts", "numColumns", "row", "counts", "totals", "slotTotals", "n", "col", "letter", "base", "cb", "count", "nonGapTotal", "entropy", "_slot", "freq", "entries", "letters", "letterOfResidueSlot", "residueSlotOfLetter", "numResidueSlots", "columnCountsFromRows", "rows", "max", "maxBitsFor", "sequenceType", "columnLogoStack", "colStats", "col", "maxBits", "total", "nonGapTotal", "informationContent", "stack", "slot", "count", "letterOfResidueSlot", "a", "b", "drawConservationBars", "ctx", "values", "color", "colWidth", "trackHeight", "offsetX", "blockSize", "xStart", "xEnd", "visibleColRange", "i", "barHeight", "x", "barTrackValues", "model", "trackId", "supplied", "drawArcs", "arcs", "maxSpan", "arc", "apexRoom", "x1", "x2", "apex", "drawTextTrackContent", "data", "colorScheme", "contrastText", "bgColor", "drawLetters", "rowHeight", "str", "letter", "upper", "fill", "rulerStep", "minPixels", "step", "mantissas", "rulerCols", "end", "cols", "first", "n", "RULER_FONT_SIZE", "TICK_HEIGHT", "drawColumnRuler", "numColumns", "label", "textColor", "setFontSize", "col", "text", "CAP_HEIGHT_RATIO", "MIN_LETTER_PX", "drawSequenceLogo", "colStats", "maxBits", "referenceFontSize", "capHeight", "stack", "columnLogoStack", "bottom", "bits", "h", "width", "drawTrackBlock", "track", "offsetY", "theme", "blockSizeXOverride", "highResScaleFactorOverride", "highResScaleFactor", "id", "kind", "barColor", "arcColor", "customColorScheme", "blockSizeX", "k", "relativeTo", "pos", "fontSize", "showMsaLetters", "contrastTextFn", "renderAllTracks", "currentY", "import_react", "ScaleBarSVG", "bar", "marginLeft", "y", "color", "React", "ctxHandle", "getCtx", "CHAR_WIDTH_RATIO", "measureTextCanvas", "text", "fontSize", "ctx", "setFontSize", "bracketBarWidth", "bracketGap", "maxCladeGutterWidth", "cladeInGutter", "clade", "cladeHeight", "rowHeight", "cladeLabelHorizontal", "fontSize", "cladeLabelOffset", "cladeGutterWidth", "clades", "widest", "text", "measureTextCanvas", "labelFitFontSize", "cladeLabelBoxes", "model", "resolvedClades", "effectiveTreeAreaWidth", "gutterLeft", "index", "label", "markColor", "rows", "left", "ellipsize", "measure", "text", "room", "width", "n", "truncated", "truncatedWidth", "hierarchy", "data", "childrenAccessor", "LaidOutNode", "source", "parent", "frame", "scale", "rootToTipLength", "layoutTree", "root", "nodes", "leafNodes", "rootHeight", "stack", "node", "collapsedSubtreeMaxLength", "i", "sum", "min", "max", "depthToLeaf", "child", "collapse", "calcDepthToLeaf", "roots", "n", "acc", "kids", "descendants", "maxDepth", "leafIndex", "index", "leaf", "leaves", "name", "mrca", "names", "other", "nodeCoveringRows", "top", "bottom", "c", "radius", "d", "blockPad", "model", "highlightLabelHeight", "inYBlock", "y", "offsetY", "by", "pad", "forEachNodeInBlock", "root", "cb", "top", "bottom", "stack", "node", "child", "cladeName", "unnamed", "id", "name", "label", "getNodeX", "showBranchLen", "tipX", "maxDepthToLeaf", "depthToLeaf", "calcDepthToLeaf", "renderTree", "ctx", "theme", "blockSizeYOverride", "hierarchy", "blockSize", "branchColors", "defaultStroke", "source", "sy", "sx", "target", "ty", "tx", "y1", "y2", "renderCollapsedTriangles", "clickMap", "collapsedSet", "rowHeight", "fontSize", "ml", "halfHeight", "apexX", "inBlock", "baseX", "count", "renderNodeBubbles", "draw", "x", "data", "isCollapsed", "renderNodeLabels", "setFontSize", "renderTreeLabels", "tipLabelColors", "labelsAlignRight", "drawTree", "treeAreaWidthMinusMargin", "marginLeft", "noTree", "treeDrawn", "visibleLeaves", "getVisibleLeaves", "emHeight", "displayName", "yp", "xp", "fit", "room", "ellipsize", "text", "boxWidth", "width", "offset", "labelRight", "labelX", "firstRow", "rowIndices", "min", "index", "renderCladeHighlights", "resolvedClades", "effectiveTreeAreaWidth", "right", "rows", "color", "mark", "nodeCoveringRows", "renderCladeBrackets", "cladeGutterWidth", "bracketGap", "bracketBarWidth", "markColor", "renderRowHighlights", "resolvedHighlights", "rowTints", "referenceRowIndex", "placed", "fillRow", "referenceColor", "highlightRowFill", "first", "drawHighlightLabel", "renderTreeCanvas", "highResScaleFactorOverride", "drawNodeBubbles", "drawNodeLabels", "highResScaleFactor", "showTreeText", "_rowHeight", "k", "pad", "rowScale", "numTips", "height", "inner", "row", "drawTreeOverview", "model", "ctx", "theme", "width", "layout", "root", "maxDepthToLeaf", "showBranchLen", "innerWidth", "rowY", "nodeX", "node", "getNodeX", "rows", "color", "source", "descendants", "sx", "sy", "target", "tx", "ty", "drawTreeOverviewBox", "top", "renderTreeOverview", "args", "caches", "overviewKeys", "scale", "canStroke", "treeOverviewImage", "keys", "prev", "key", "i", "made", "makeOffscreenCanvas", "next", "import_react_dom", "import_client", "renderToStaticMarkup", "node", "div", "root", "html", "tag", "colorAttr", "svgSafeColors", "el", "match", "attr", "value", "color", "A", "alpha", "hex", "renderToSvg", "model", "opts", "Context", "layers", "markup", "renderToStaticMarkup", "React", "MsaSvg", "getLayout", "svgSafeColors", "match", "id", "ctx", "theme", "layout", "width", "trackHeight", "includeMinimap", "legendWidth", "topHeight", "effectiveTreeAreaWidth", "rowPanelsWidth", "totalWidth", "height", "exportPageSize", "legendTop", "props", "body", "TrackRendering", "CoreRendering", "MinimapSVG", "RowPanelHeadersSVG", "TreeOverviewSVG", "TreeScaleBarSVG", "LegendSVG", "overviewHeight", "renderTreeOverview", "ClipGroup", "marginLeft", "bar", "treeOverviewHeight", "ScaleBarSVG", "treeScaleBarHeight", "bandHeight", "resolvedRowPanels", "fontSize", "y", "panel", "across", "headerRunsAcross", "size", "center", "x", "room", "LEGEND_PAD", "ellipsize", "t", "measureTextCanvas", "CladeLabelsSVG", "offsetY", "boxes", "cladeLabelBoxes", "box", "top", "rows", "legendRows", "boxHeight", "legendHeight", "LEGEND_TEXT_X", "row", "i", "LEGEND_ROW_H", "LEGEND_SWATCH", "outlineColor", "LEGEND_FONT", "LEGEND_CHAR_W", "contentHeight", "offsetX", "msaAreaWidth", "treeCtx", "renderTreeCanvas", "rowPanelsCtx", "renderRowPanels", "raster", "rasterBackground", "msaCtx", "renderBoxFeatureCanvasBlock", "renderMSABlock", "renderPersistentHighlights", "colWidth", "rowHeight", "rasterApplies", "xStart", "xEnd", "visibleColRange", "yStart", "yEnd", "visibleRowRange", "numCols", "numRows", "href", "rasterImageHref", "renderAllTracks", "TrackLabelsSVG", "turnedOnTracks", "drawLabels", "labels", "track", "name", "acc", "baseline", "panelId", "clipId", "transform", "underlay"]
7
+ }