jbrowse-plugin-graphgenomeviewer 6.2.0 → 6.3.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 (43) hide show
  1. package/dist/chunks/{GbzBaseSyntenyAdapter-TLI5IUU7.js → GbzBaseSyntenyAdapter-PT4IARIU.js} +2 -2
  2. package/dist/chunks/{GbzBaseSyntenyAdapter-TLI5IUU7.js.map → GbzBaseSyntenyAdapter-PT4IARIU.js.map} +1 -1
  3. package/dist/chunks/{GraphGenomeView-5OPCROMQ.js → GraphGenomeView-6CRBLHNG.js} +2 -2
  4. package/dist/chunks/{GraphTrackSettingsDialog-FGLLUIEE.js → GraphTrackSettingsDialog-2QQYWNWW.js} +2 -2
  5. package/dist/chunks/{LinearGraphDisplay-NBJHGOYX.js → LinearGraphDisplay-KNEXJAAV.js} +2 -2
  6. package/dist/chunks/{MinigraphBubbleAdapter-LQUIL3MD.js → MinigraphBubbleAdapter-MQRO5J7Z.js} +2 -2
  7. package/dist/chunks/{RgfaTabixAdapter-3BFNY4SB.js → RgfaTabixAdapter-ALEXRTPS.js} +2 -2
  8. package/dist/chunks/{bandage-layout-3AR6BCUD-I6CCWYSR.js → bandage-layout-3AR6BCUD-BW536UT3.js} +1 -1
  9. package/dist/chunks/{bandage-layout-3AR6BCUD-I6CCWYSR.js.map → bandage-layout-3AR6BCUD-BW536UT3.js.map} +1 -1
  10. package/dist/chunks/{chunk-EKMGHBWM.js → chunk-3MJ4ZXML.js} +1 -1
  11. package/dist/chunks/{chunk-EKMGHBWM.js.map → chunk-3MJ4ZXML.js.map} +1 -1
  12. package/dist/chunks/{chunk-O5EHYU3Y.js → chunk-4F2MWXJF.js} +2 -2
  13. package/dist/chunks/{chunk-NGQRKSHY.js → chunk-4LEFC42C.js} +2 -2
  14. package/dist/chunks/{chunk-NGQRKSHY.js.map → chunk-4LEFC42C.js.map} +2 -2
  15. package/dist/chunks/{chunk-F7V6ZPKD.js → chunk-5GRQIE5Q.js} +1 -1
  16. package/dist/chunks/{chunk-F7V6ZPKD.js.map → chunk-5GRQIE5Q.js.map} +1 -1
  17. package/dist/chunks/{chunk-JYZAMHIP.js → chunk-6IK6ZDSI.js} +2 -2
  18. package/dist/chunks/{chunk-JYZAMHIP.js.map → chunk-6IK6ZDSI.js.map} +1 -1
  19. package/dist/chunks/{chunk-X24J6VF4.js → chunk-C4PHHPUP.js} +1 -1
  20. package/dist/chunks/{chunk-X24J6VF4.js.map → chunk-C4PHHPUP.js.map} +1 -1
  21. package/dist/chunks/{chunk-XWGKHQYO.js → chunk-CJ47OHWP.js} +2 -2
  22. package/dist/chunks/{chunk-XWGKHQYO.js.map → chunk-CJ47OHWP.js.map} +1 -1
  23. package/dist/chunks/{chunk-7MWOPEIC.js → chunk-ETTZTJNK.js} +1 -1
  24. package/dist/chunks/{chunk-7MWOPEIC.js.map → chunk-ETTZTJNK.js.map} +1 -1
  25. package/dist/chunks/chunk-PZE3GABA.js +2 -0
  26. package/dist/chunks/chunk-PZE3GABA.js.map +7 -0
  27. package/dist/chunks/{chunk-ZKLOV6MW.js → chunk-SYHZ5T54.js} +2 -2
  28. package/dist/chunks/{chunk-ZKLOV6MW.js.map → chunk-SYHZ5T54.js.map} +1 -1
  29. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
  30. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +3 -3
  31. package/package.json +2 -3
  32. package/src/GraphGenomeView/pane/hostViews.ts +1 -1
  33. package/src/GraphGenomeView/pane/paneBase.ts +1 -1
  34. package/src/GraphGenomeView/renderer/GraphRenderer.ts +2 -2
  35. package/src/version.ts +1 -1
  36. package/dist/chunks/chunk-LZUNK4MQ.js +0 -2
  37. package/dist/chunks/chunk-LZUNK4MQ.js.map +0 -7
  38. /package/dist/chunks/{GraphGenomeView-5OPCROMQ.js.map → GraphGenomeView-6CRBLHNG.js.map} +0 -0
  39. /package/dist/chunks/{GraphTrackSettingsDialog-FGLLUIEE.js.map → GraphTrackSettingsDialog-2QQYWNWW.js.map} +0 -0
  40. /package/dist/chunks/{LinearGraphDisplay-NBJHGOYX.js.map → LinearGraphDisplay-KNEXJAAV.js.map} +0 -0
  41. /package/dist/chunks/{MinigraphBubbleAdapter-LQUIL3MD.js.map → MinigraphBubbleAdapter-MQRO5J7Z.js.map} +0 -0
  42. /package/dist/chunks/{RgfaTabixAdapter-3BFNY4SB.js.map → RgfaTabixAdapter-ALEXRTPS.js.map} +0 -0
  43. /package/dist/chunks/{chunk-O5EHYU3Y.js.map → chunk-4F2MWXJF.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["global-externals:@jbrowse/core/Plugin", "global-externals:@jbrowse/core/pluggableElementTypes/AdapterType", "global-externals:@jbrowse/core/configuration", "global-externals:@jbrowse/core/data_adapters/dataAdapterCache", "global-externals:@jbrowse/core/pluggableElementTypes", "global-externals:@jbrowse/core/pluggableElementTypes/ViewType", "global-externals:@jbrowse/core/util/withLaunchInput", "global-externals:@jbrowse/core/pluggableElementTypes/models", "global-externals:@jbrowse/render-core/RenderLifecycleMixin", "global-externals:@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain", "global-externals:@jbrowse/core/pluggableElementTypes/DisplayType", "global-externals:@jbrowse/display-kit/trackHeightConfigSchemaFields", "global-externals:@jbrowse/display-kit/TrackHeightMixin", "global-externals:@jbrowse/render-core/displayPhase", "../src/index.ts", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/BubbleChart.mjs", "../src/GbzBaseSyntenyAdapter/index.ts", "../src/GbzBaseSyntenyAdapter/configSchema.ts", "../src/GetGraphReads.ts", "../src/GetSubgraph.ts", "../src/GraphAddTrackWorkflow/index.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-7XHHVYG7.js", "../src/GraphComputeLayout.ts", "../src/GraphGenomeView/index.ts", "../src/GraphGenomeView/viewModel.ts", "../src/GraphGenomeView/pane/launchActions.ts", "../src/GraphGenomeView/pane/paneBase.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-IGVV37VI.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-PUG7LXDF.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-CDLPYR5O.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-72N5DJHZ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-JVLURPFW.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-WZATPZNH.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XVSBZ4ZW.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4UBWXZVX.js", "../src/GraphGenomeView/lenientEnum.ts", "../src/GraphGenomeView/pane/renderingActions.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-VHW7FDHU.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/layout/trimToWindow.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/tubeMap/coarsen.js", "../src/GraphGenomeView/pane/loadActions.ts", "../src/GraphGenomeView/pane/settingActions.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-LOCJN3BZ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-47DYCZOK.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BUBZ32IC.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-3LXG54PN.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-CNGKWYUC.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-7ESIZZO7.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-H5S2ONCJ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KQFOCDFY.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-VZQ4FKLR.js", "../src/GraphGenomeView/pane/fitViews.ts", "../src/GraphGenomeView/host.ts", "../src/GraphGenomeView/pane/launchViews.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-ISEI2FH3.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4S47XRYA.js", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KEVQ46GG.js", "../src/GraphGenomeView/pane/graphViews.ts", "../src/panSNAliases/trackAdapterConfig.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@7.5.1/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BXEPA4KS.js", "../src/GraphGenomeView/genes/geneFeatures.ts", "../src/GraphGenomeView/repeats/repeatFeatures.ts", "../src/launchFromGraph/launchFromGraph.ts", "../src/isRecord.ts", "../src/launchFromGraph/linearViewTarget.ts", "../src/GraphGenomeView/pane/walkRowViews.ts", "../src/GraphGenomeView/pane/hostViews.ts", "../src/hoverSync/lgvHover.ts", "../src/hoverSync/rowWalks.ts", "../src/launchFromGraph/launchTracks.ts", "../src/launchFromGraph/syntenyTracks.ts", "../src/GraphGenomeView/download.ts", "../src/GraphGenomeView/model.ts", "../src/graphTrackConfig.ts", "../src/GraphTrack/index.ts", "../src/LaunchGraphGenomeView.ts", "../src/LinearGraphDisplay/index.ts", "../src/LinearGraphDisplay/configSchema.ts", "../src/LinearGraphDisplay/model.ts", "../src/LinearGraphDisplay/denseWindow.ts", "../src/MinigraphBubbleAdapter/index.ts", "../src/MinigraphBubbleAdapter/configSchema.ts", "../src/RgfaTabixAdapter/index.ts", "../src/RgfaTabixAdapter/configSchema.ts", "../src/graphTrackDefaults/index.ts", "../src/hoverSync/GraphNodeHighlight.tsx", "../src/hoverSync/graphViewHighlights.ts", "../src/hoverSync/index.tsx", "../src/panSNAliases/index.ts", "../src/pluginName.ts", "../src/version.ts"],
4
- "sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/Plugin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/AdapterType\"];", "module.exports = JBrowseExports[\"@jbrowse/core/configuration\"];", "module.exports = JBrowseExports[\"@jbrowse/core/data_adapters/dataAdapterCache\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"];", "module.exports = JBrowseExports[\"@jbrowse/core/util/withLaunchInput\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/models\"];", "module.exports = JBrowseExports[\"@jbrowse/render-core/RenderLifecycleMixin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/TrackHeightMixin\"];", "module.exports = JBrowseExports[\"@jbrowse/render-core/displayPhase\"];", "import Plugin from '@jbrowse/core/Plugin'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\n\nimport GbzBaseSyntenyAdapterF from './GbzBaseSyntenyAdapter/index'\nimport GetGraphReads from './GetGraphReads'\nimport GetSubgraph from './GetSubgraph'\nimport GraphAddTrackWorkflowF from './GraphAddTrackWorkflow/index'\nimport GraphComputeLayout from './GraphComputeLayout'\nimport GraphGenomeViewF from './GraphGenomeView/index'\nimport GraphTrackF from './GraphTrack/index'\nimport LaunchGraphGenomeViewF from './LaunchGraphGenomeView'\nimport LinearGraphDisplayF from './LinearGraphDisplay/index'\nimport MinigraphBubbleAdapterF from './MinigraphBubbleAdapter/index'\nimport RgfaTabixAdapterF from './RgfaTabixAdapter/index'\nimport GraphTrackDefaultsF from './graphTrackDefaults/index'\nimport GraphHoverSyncF from './hoverSync/index'\nimport PanSNAliasesF from './panSNAliases/index'\nimport { PLUGIN_NAME } from './pluginName'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class GraphGenomeViewPlugin extends Plugin {\n name = PLUGIN_NAME\n version = version\n\n install(pluginManager: PluginManager) {\n GraphGenomeViewF(pluginManager)\n LinearGraphDisplayF(pluginManager)\n GraphTrackF(pluginManager)\n LaunchGraphGenomeViewF(pluginManager)\n GraphHoverSyncF(pluginManager)\n RgfaTabixAdapterF(pluginManager)\n MinigraphBubbleAdapterF(pluginManager)\n GbzBaseSyntenyAdapterF(pluginManager)\n GraphAddTrackWorkflowF(pluginManager)\n GraphTrackDefaultsF(pluginManager)\n PanSNAliasesF(pluginManager)\n pluginManager.addRpcMethod(() => new GraphComputeLayout(pluginManager))\n pluginManager.addRpcMethod(() => new GetSubgraph(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphReads(pluginManager))\n }\n\n // A throw from configure() takes the whole session to its error page, and a\n // menu entry is not worth that: hubs 1.0.9 did exactly this to every\n // jbrowse.org/ucsc launch by appending to a menu a released host defines as\n // a function. The view is still reachable without the entry.\n configure(pluginManager: PluginManager) {\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n onClick: (session: AbstractSessionModel) => {\n session.addView('GraphGenomeView', {})\n },\n })\n }\n } catch (e) {\n console.warn('[GraphGenomeView] could not add the Add menu entry', e)\n }\n }\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"7.2\",\n cy: \"14.4\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"14.8\",\n cy: \"18\",\n r: \"2\"\n}, \"1\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"15.2\",\n cy: \"8.8\",\n r: \"4.8\"\n}, \"2\")], 'BubbleChart');", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function GbzBaseSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'GbzBaseSyntenyAdapter',\n displayName: 'gbz-base pangenome adapter',\n configSchema,\n // The same opened database serves the graph display's subgraph.\n // headerLanes: getHeader declares every haplotype as a lane, which is\n // what makes MultiWaySyntenyDisplay read the header of an untiered\n // adapter and offer its lane picker over the whole graph.\n // lanePairsOnAnchor: a window of the anchor answers any two lanes'\n // alignment to each other, so the display fetches each adjacent pair\n // rather than composing it through the reference.\n // lanePairBatches: every pair on a window comes from one cut\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./GbzBaseSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { GBZ_CUT_DEFAULTS } from '@jbrowse/bandage-core/gbzWindow'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config GbzBaseSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | gbz-base pangenome database | Haplotype alignments read from the graph at query time, no PAF conversion\n * Serves a pangenome graph stored as a gbz-base SQLite database (`.gbz.db`) as\n * haplotype-versus-reference alignments, the shape `MultiWaySyntenyDisplay`\n * draws as one lane per haplotype. A window on the reference is located on the\n * graph's reference path, every haplotype's walk through the nodes it covers\n * is recovered and named, and each haplotype becomes one alignment record with\n * a CIGAR, so the graph is read through HTTP range requests with no offline\n * conversion. Naming the walks takes the companion haplotype index that\n * `gbz-haplotype-index` writes; without it the graph cannot say which\n * haplotype a walk belongs to.\n *\n * Only the fine tier exists: a whole-chromosome view stays on a PIF's coarse\n * tier. A query on a haplotype lane answers nothing, so the multi-way display\n * composes its lane-to-lane links through the reference.\n *\n * #example\n * ```js\n * {\n * type: 'GbzBaseSyntenyAdapter',\n * uri: 'hprc-v2.gbz.db',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38#0' },\n * }\n * ```\n */\nconst GbzBaseSyntenyAdapter = ConfigurationSchema(\n 'GbzBaseSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the graph's reference\n * sample is loaded as. A haplotype needs no entry: its lane draws on the\n * session assembly named or aliased by its PanSN prefix (`HG002.1` with the\n * alias `HG002#1`), or the one `assemblyNameToPanSN` maps to it. A further\n * entry names an assembly by its sample (`HG002`), which takes both of the\n * sample's lanes. A haplotype with no assembly is still a lane, labelled by\n * its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * The `.gbz.db` written by `gbz-base construct`; read by HTTP range\n * requests, so it can be large.\n */\n gbzDbLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.gbz.db',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * The haplotype index `gbz-haplotype-index` writes beside the graph\n * database, which names its walks. One with stray rows (the tool from\n * 0.2.0) lets a fetch for a chosen set of lanes walk only those\n * haplotypes. Empty means `graph.haplotype-index.db` beside\n * `graph.gbz.db` if there is one; otherwise the walks go unnamed.\n */\n haplotypeIndexLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * Reads aligned to the graph as GAF, which the tube map layouts draw under\n * the haplotypes. Its segment names have to be the cut's: numeric node ids,\n * or `vg giraffe --named-coordinates` on a graph whose segments were\n * renamed or chopped. Empty means no reads.\n */\n readsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * The `tabix -p gaf` index of a bgzipped `readsLocation`, which fetches the\n * reads over each window's node ids. Empty reads the GAF whole, up to 50 MB.\n */\n readsIndex: ConfigurationSchema('GbzBaseReadsIndex', {\n /**\n * #slot\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot\n */\n location: {\n type: 'fileLocation',\n defaultValue: { uri: '', locationType: 'UriLocation' },\n },\n }),\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by (\"Group by\u2026\"). Its header row names the columns\n * (`population`, `superpopulation`, ...), and its first column is the\n * walk's sample (`HG00097`) or haplotype (`HG00097#1`). Empty means no\n * grouping.\n */\n samplesTsvLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * How the graph view's subgraph is extended past the nodes the reference\n * window touches. `contained` adds every top-level snarl with both\n * boundary nodes in the window, which is what brings back the bubbles a\n * reference-only walk leaves out; a haplotype still breaks into a new W\n * line wherever it leaves the window's nodes (a 60 kb C4 window on the\n * HPRC graph: 2,703 nodes, 8,083 walks for 464 haplotypes). `overlapping`\n * also follows snarls that leave the window, so every haplotype is one\n * walk (464), at the price of every node in those snarls (4,184 there,\n * 24,547 across the KIV-2 repeat). `none` leaves only the bp `context`.\n */\n subgraphSnarls: {\n type: 'stringEnum',\n model: types.enumeration('SnarlOutput', [\n 'none',\n 'contained',\n 'overlapping',\n ]),\n defaultValue: GBZ_CUT_DEFAULTS.snarls,\n },\n /**\n * #slot\n * The graph sample the anchor window is located on. Empty means the sample\n * the anchor's PanSN prefix names, or the database's one reference sample\n * (`gbwt_reference_samples`) when the anchor names none; a database with\n * several reference samples then needs this set.\n */\n referenceSample: {\n type: 'string',\n defaultValue: '',\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38#0', 'HG002.1': 'HG002#1' }`). Each\n * session assembly with a `sample#haplotype` alias (`HG002#1`) is mapped to\n * it already, so this is the override: an entry takes its prefix from any\n * assembly aliased to it. An assembly in neither maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * Graph context around the window, in bp, on top of `subgraphSnarls`: the\n * cut, its reference walk and every haplotype walk extend this far past\n * the window on each side. A haplotype walk breaks into pieces wherever it\n * leaves the cut's nodes, so context and snarls together decide whether a\n * lane's bubble is one record or several. A window inside a snarl far\n * larger than itself (MHC class II on the HPRC graph, 90 kb) is 1.1M pieces\n * at 0 and 464 walks at 1000, three times faster.\n */\n context: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.context,\n advanced: true,\n },\n /**\n * #slot\n * The most graph nodes one window may load before the query fails rather\n * than reading a whole chromosome into the worker.\n */\n nodeLimit: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.limit,\n advanced: true,\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n *\n * preprocessor to allow minimal config, where a `.gz` `reads` is taken to\n * be bgzipped with a `.tbi` beside it:\n * ```json\n * {\n * \"type\": \"GbzBaseSyntenyAdapter\",\n * \"uri\": \"graph.gbz.db\",\n * \"reads\": \"reads.gaf.gz\",\n * \"assemblyNames\": [\"hg38\"]\n * }\n * ```\n */\n preProcessSnapshot: snap => {\n const { uri, baseUri, reads } = snap\n return {\n ...snap,\n ...(uri ? { gbzDbLocation: { uri, baseUri } } : {}),\n ...(typeof reads === 'string'\n ? {\n readsLocation: { uri: reads, baseUri },\n ...(reads.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${reads}.tbi`, baseUri } } }\n : {}),\n }\n : {}),\n }\n },\n },\n)\n\nexport type GbzBaseSyntenyAdapterConfig = Instance<typeof GbzBaseSyntenyAdapter>\n\nexport default GbzBaseSyntenyAdapter\n", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { GafReads } from './gaf/gafFile'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The reads aligned over a cut's segments, from an adapter whose config names\n// a GAF (GbzBaseSyntenyAdapter's `readsLocation`). Asked after the cut is\n// parsed, because the segment names are what a GAF index is keyed by.\n\nexport interface GetGraphReadsArgs {\n adapterConfig: Record<string, unknown>\n nodeNames: string[]\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphReads: {\n args: GetGraphReadsArgs\n return: GafReads\n }\n }\n}\n\ninterface ReadsAdapter {\n getReads(\n nodeNames: string[],\n opts: { signal?: AbortSignal },\n ): Promise<GafReads>\n}\n\nfunction isReadsAdapter(adapter: object): adapter is ReadsAdapter {\n return (\n 'getReads' in adapter &&\n typeof (adapter as ReadsAdapter).getReads === 'function'\n )\n}\n\nconst isNamed = (location: unknown) =>\n typeof location === 'object' &&\n location !== null &&\n Object.entries(location).some(\n ([key, value]) =>\n ['uri', 'localPath', 'blobId'].includes(key) &&\n typeof value === 'string' &&\n value !== '',\n )\n\n// Whether an adapter config as written names reads, so a graph without them\n// makes no round trip to ask\nexport function namesReads(adapterConfig: Record<string, unknown>) {\n return (\n (typeof adapterConfig.reads === 'string' && adapterConfig.reads !== '') ||\n isNamed(adapterConfig.readsLocation)\n )\n}\n\nexport default class GetGraphReads extends RpcMethodType<'GetGraphReads'> {\n name = 'GetGraphReads' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphReads'>) {\n const { adapterConfig, nodeNames, sessionId, signal } = args\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n return isReadsAdapter(dataAdapter)\n ? dataAdapter.getReads(nodeNames, { signal })\n : { records: [], total: 0 }\n }\n}\n", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\nimport { RpcMethodTypeWithRenameRegion } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\nimport type { Region } from '@jbrowse/core/util'\n\n// No `sessionId`, `signal` or `statusCallback` here: those belong to the\n// CALL, not to this payload, and core's `EntriesDeclaringCallLevelFields` fails\n// the build for a registry entry that declares one. `execute` still receives\n// them, because `RpcExecuteArgs` intersects `RpcCallContext` in.\n// `hops` is how far past the window a cut follows links, which only the rGFA\n// cut reads; the GBZ cut has its own bp `context` slot. `haplotypes` is the\n// set the cut is for, lane assembly names or PanSN prefixes, which only the GBZ\n// cut reads: it keeps those walks and the nodes they visit. Undefined or empty\n// is every haplotype. `tier` picks which of an rGFA track's two index pairs the\n// cut reads, the adapter's own or its `coarse` one; fine when absent.\nexport type SubgraphTier = 'fine' | 'coarse'\n\nexport interface SubgraphCutOptions {\n hops?: number\n haplotypes?: string[]\n tier?: SubgraphTier\n // which snarls a GBZ cut follows past the window, over the track's\n // `subgraphSnarls`; 'overlapping' when the layout measures whole walks\n snarls?: 'none' | 'contained' | 'overlapping'\n}\n\n// What an adapter's cut is handed: the payload, plus the call's own signal so\n// a cut the view has moved on from stops reading.\nexport interface SubgraphAdapterOptions extends SubgraphCutOptions {\n signal?: AbortSignal\n}\n\nexport interface SubgraphRegion {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport interface GetSubgraphArgs {\n adapterConfig: Record<string, unknown>\n region: Region\n opts?: SubgraphCutOptions\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetSubgraph: {\n args: GetSubgraphArgs\n return: string\n }\n }\n}\n\n// Adapters that can cut a local subgraph out of a graph file implement this:\n// RgfaTabixAdapter and GbzBaseSyntenyAdapter today.\ninterface SubgraphAdapter {\n getSubgraph(region: Region, opts?: SubgraphAdapterOptions): Promise<string>\n}\n\nfunction isSubgraphAdapter(adapter: object): adapter is SubgraphAdapter {\n return (\n 'getSubgraph' in adapter &&\n typeof (adapter as SubgraphAdapter).getSubgraph === 'function'\n )\n}\n\n// RpcMethodTypeWithRenameRegion, not the plain RpcMethodType: the base class is\n// what maps `region.refName` from the assembly's spelling onto the adapter's own\n// before the call crosses to the worker. Without it a launch on an hg38 whose\n// contigs are bare (`6`, which is what every GRCh38 FASTA on jbrowse.org uses)\n// asked RgfaTabixAdapter for `GRCh38#0#6`, matched nothing, and opened a view\n// reading \"0 nodes, 0 edges\" with no error. The segments track drew the whole\n// time, because CoreGetFeatures renames and this did not, so the graph looked\n// broken while its own track looked fine. `assemblyNameToPanSN` covers the\n// sample half of a PanSN name only; the contig half is refName aliasing, which\n// the assembly already knows and this now consults.\nexport default class GetSubgraph extends RpcMethodTypeWithRenameRegion<'GetSubgraph'> {\n name = 'GetSubgraph' as const\n\n // Parameterized by the registry key, not left at the default `string`: a bare\n // RpcMethodTypeWithRenameRegion resolves RpcExecuteArgs to `unknown`, so\n // `execute` type-checks against nothing at all. `invoke` has already run\n // `deserializeArguments` by the time this is called, so it does not.\n async execute(args: RpcExecuteArgs<'GetSubgraph'>) {\n // `signal` arrives on every call and has to be named to be forwarded:\n // unnamed, a cut the view had replaced went on querying to the end, one\n // tabix read per off-reference segment per hop.\n const { adapterConfig, region, sessionId, opts, signal } = args\n\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n if (isSubgraphAdapter(dataAdapter)) {\n return dataAdapter.getSubgraph(region, { ...opts, signal })\n }\n // An empty result is how the view and the launch menu detect \"this track\n // can't do subgraphs\" \u2014 see the pane's cutSubgraph.\n console.warn(\n `[GetSubgraph] ${dataAdapter.constructor.name} does not implement getSubgraph`,\n )\n return ''\n }\n}\n", "import { lazy } from 'react'\n\nimport { AddTrackWorkflowType } from '@jbrowse/core/pluggableElementTypes'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst GraphAddTrackWidget = lazy(() => import('./AddTrackWorkflow'))\n\nexport default function GraphAddTrackWorkflowF(pluginManager: PluginManager) {\n pluginManager.addAddTrackWorkflowType(\n () =>\n new AddTrackWorkflowType({\n name: 'Pangenome graph track',\n displayName: 'Add pangenome graph track',\n ReactComponent: GraphAddTrackWidget,\n stateModel: types.model({}),\n }),\n )\n}\n", "// src/loadBandage.ts\nvar cached;\nfunction loadBandage() {\n cached ??= import(\"./bandage-layout-3AR6BCUD.js\").then((mod) => mod.default()).catch((e) => {\n cached = void 0;\n throw e;\n });\n return cached;\n}\n\nexport {\n loadBandage\n};\n", "import loadBandage from '@jbrowse/bandage-core/loadBandage'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The payload is the pipeline's EngineRequest, the same request a standalone\n// page hands the engine. `sessionId` and `statusCallback` are the CALL's, not\n// the payload's: core's `EntriesDeclaringCallLevelFields` fails the build for a\n// registry entry that declares either. `execute` still receives both, through\n// `RpcExecuteArgs`'s intersection with `RpcCallContext`.\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GraphComputeLayout: {\n args: EngineRequest\n return: { result: LayoutResult; duration: number }\n }\n }\n}\n\nexport default class GraphComputeLayout extends RpcMethodType<'GraphComputeLayout'> {\n name = 'GraphComputeLayout' as const\n\n async execute(args: RpcExecuteArgs<'GraphComputeLayout'>) {\n const { graph, options, statusCallback } = args\n\n statusCallback?.('Loading layout engine')\n const module = await loadBandage()\n\n statusCallback?.('Computing layout')\n const startTime = performance.now()\n const result = module.computeLayout(graph, options)\n const duration = performance.now() - startTime\n\n return { result, duration }\n }\n}\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\nimport { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput'\n\nimport modelFactory from './viewModel'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// This view has NO launch keys, and saying so is what turns the check on.\n//\n// A launch key is a spec field the launcher interprets rather than assigns \u2014 an\n// LGV's `assembly` and `loc`, resolved into `displayedRegions`. Every field of\n// a graph launch is a plain persisted prop instead (see\n// LaunchGraphGenomeView), so the registration is empty; what it buys is\n// `ViewType.acceptedKeys`, which is `undefined` until a view declares its\n// launch vocabulary, and which `loadSessionSpec` needs to report\n// `ignored unknown key(s)`.\n//\n// Without it a session spec's typo in a GraphGenomeView entry is silent: the\n// key lands in the snapshot, MST drops it, and the view opens on the import\n// form with nothing said. That surface is written by hand with no compiler\n// behind it \u2014 `sessionSpec()` takes a bare `object` \u2014 and the docs build two\n// dozen graph figures through it, `loadedRegion` and `loadedTrackId` among the\n// fields a misspelling would silently cost.\n//\n// Ignored by a host that predates `acceptedKeys`: its ViewType constructor\n// reads the options it knows and this is not one of them.\nconst graphLaunchKeys = defineLaunchKeys<object>()({})\n\nexport default function GraphGenomeViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'GraphGenomeView',\n displayName: 'Graph genome view',\n stateModel: modelFactory(),\n launchKeys: graphLaunchKeys,\n ReactComponent: lazy(() => import('./components/GraphGenomeView')),\n })\n })\n}\n", "import { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer, types } from '@jbrowse/mobx-state-tree'\nimport { reaction } from 'mobx'\n\nimport { GraphPaneMixin, MAX_GRAPH_REGION_BP, formatSpanBp } from './model'\nimport {\n graphReferenceAssembly,\n offReferenceProblem,\n} from '../graphTrackConfig'\nimport { trackAdapterConfig } from '../panSNAliases/trackAdapterConfig'\n\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n// the last segment of a file's path, its query dropped, or a blob's own name\nfunction fileName(location: FileLocation) {\n const path =\n 'uri' in location\n ? location.uri.split(/[?#]/)[0]!\n : 'localPath' in location\n ? location.localPath\n : 'name' in location\n ? location.name\n : ''\n return path.split(/[\\\\/]/).at(-1) ?? ''\n}\n\nexport default function stateModelFactory() {\n return types\n .compose(\n 'GraphGenomeView',\n BaseViewModel,\n GraphPaneMixin(),\n types.model({\n type: types.literal('GraphGenomeView'),\n // a whole GFA the view loads on attach, kept so the source round-trips\n // through a session snapshot\n gfaLocation: types.maybe(types.frozen<FileLocation>()),\n // the reference window the file or the cut was stated beside\n loadedRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // A session track the view cuts `loadedRegion` from once, as 4.0\n // sessions and the docs' figure specs state it. Following the linear\n // view is the track's job (LinearGraphDisplay).\n loadedTrackId: types.optional(types.string, ''),\n subgraphContext: types.optional(types.number, 1),\n subgraphHaplotypes: types.maybe(types.frozen<string[]>()),\n maxRegionBp: types.optional(types.number, MAX_GRAPH_REGION_BP),\n }),\n )\n .views(self => ({\n get rpcSessionId() {\n return self.id\n },\n // a view is not its own containing view\n get paneWidth() {\n return self.width\n },\n get cutHaplotypes() {\n return self.subgraphHaplotypes\n },\n get sourceGfaLocation() {\n return self.gfaLocation\n },\n get sourceTrack(): AnyConfigurationModel | undefined {\n return self.loadedTrackId\n ? getSession(self).tracks.find(t => t.trackId === self.loadedTrackId)\n : undefined\n },\n get canRetryLoad() {\n return (\n self.gfaLocation !== undefined ||\n (self.loadedTrackId !== '' && self.loadedRegion !== undefined)\n )\n },\n }))\n .views(self => ({\n get hasPendingSource() {\n return self.canRetryLoad && !self.graph && !self.loadCanceled\n },\n menuItems() {\n return self.launchMenuItems()\n },\n }))\n .actions(self => {\n const clearPane = self.clearGraph\n return {\n // the stated source goes too, or a reloaded session would load the\n // dismissed graph again\n clearGraph() {\n clearPane()\n self.gfaLocation = undefined\n self.loadedRegion = undefined\n self.loadedTrackId = ''\n },\n load() {\n const region = self.loadedRegion\n if (self.gfaLocation) {\n // a whole file has no assembly to name the view by\n if (!self.displayName) {\n self.setDisplayName(fileName(self.gfaLocation))\n }\n return self.loadGFAFromLocation(self.gfaLocation, region)\n }\n if (!self.loadedTrackId || !region) {\n return\n }\n const track = self.sourceTrack\n const span = region.end - region.start\n const problem = track\n ? offReferenceProblem(\n graphReferenceAssembly(track),\n region.assemblyName,\n )\n : undefined\n if (!track) {\n self.setError(\n new Error(\n `The track this graph was cut from, \"${self.loadedTrackId}\", is not in this session`,\n ),\n )\n } else if (problem) {\n self.setError(new Error(problem))\n } else if (span > self.maxRegionBp) {\n self.setError(\n new Error(\n `Region too large (${formatSpanBp(span)}) \u2014 zoom in to view graph (max ${formatSpanBp(self.maxRegionBp)})`,\n ),\n )\n } else {\n return self.cutSubgraph(trackAdapterConfig(self, track), region, {\n hops: self.subgraphContext,\n haplotypes: self.subgraphHaplotypes,\n ...(self.cutsWholeWalks\n ? { snarls: 'overlapping' as const }\n : {}),\n })\n }\n return undefined\n },\n }\n })\n .actions(self => ({\n retryLoad() {\n void self.load()\n },\n // walk rows, and the strip of them under a node layout, measure whole\n // walks, which a GBZ cut only follows when asked, so a change in whether\n // the drawing needs them cuts the track again; the strip's toggle does\n // the same (afterAttach)\n switchLayout(mode: LayoutModeValue) {\n const before = self.cutsWholeWalks\n self.setLayoutMode(mode)\n return self.loadedTrackId && self.cutsWholeWalks !== before\n ? self.load()\n : self.recomputeLayout()\n },\n // Here rather than when the rendering backend starts: the canvas only\n // mounts once there is a graph, so a view whose graph must be fetched\n // would never fetch it.\n afterAttach() {\n if (!self.graph) {\n void self.load()\n }\n addDisposer(\n self,\n reaction(\n () => self.walkStrip,\n () => {\n if (\n self.loadedTrackId &&\n !layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ) {\n void self.load()\n }\n },\n ),\n )\n },\n }))\n}\n\nexport type GraphGenomeViewModel = Instance<\n ReturnType<typeof stateModelFactory>\n>\n", "import { COLOR_SCHEMES } from '@jbrowse/bandage-core/colorSchemes'\nimport { FACET_FIELDS } from '@jbrowse/bandage-core/facetGrid'\nimport { LAYOUT_MODES } from '@jbrowse/bandage-core/layoutModes'\nimport { WALK_FIELDS, WALK_SCHEMES } from '@jbrowse/bandage-core/walkEncoding'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n TUBE_MAP_FOLDS,\n TUBE_MAP_MODES,\n WALK_MENU_ITEMS,\n} from './paneBase'\nimport { withRenderingActions } from './renderingActions'\nimport { graphLaunchMenuItems } from '../../launchFromGraph/graphMenuItems'\nimport {\n highlightInLinearView,\n launchSyntenyView,\n showInLinearView,\n} from '../../launchFromGraph/launchFromGraph'\nimport { launchTracks } from '../../launchFromGraph/launchTracks'\nimport { launchableSyntenyTracks } from '../../launchFromGraph/syntenyTracks'\nimport { downloadText } from '../download'\n\nimport type { GraphLocation } from '../../launchFromGraph/contributors'\nimport type { MenuItem } from '@jbrowse/core/ui'\n\nexport const withLaunchActions = withRenderingActions\n .actions(self => ({\n // Move the linear view already on screen, or open one if there is none,\n // and pair with whichever it was. A view being created gets the session's\n // annotation for the assembly it opens on (see launchTracks), led by the\n // graph's own segments track when the launch is on the reference \u2014 the one\n // assembly that track is configured for.\n //\n // Only a view on the reference is paired with. A node's hover band is on\n // that assembly, so paired with a view on another the band fails that\n // view's assembly check and the reference view's id check, and is drawn\n // nowhere.\n showInLinearView(target: { location: GraphLocation; assembly: string }) {\n const session = getSession(self)\n const onReference = target.assembly === self.graphRegion?.assemblyName\n const viewId = showInLinearView({\n session,\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.connectedViewId,\n tracks: launchTracks({\n session,\n assemblyName: target.assembly,\n first: onReference ? self.sourceTrackId : undefined,\n }),\n })\n if (onReference) {\n self.pairWithLinearView(viewId)\n }\n },\n // Mark the node's reference interval in the linear view beside the graph.\n // Not an action that opens anything: with no view to mark, the menu does\n // not offer it (see nodeLaunchMenuItems).\n highlightInLinearView(target: {\n location: GraphLocation\n assembly: string\n }) {\n highlightInLinearView({\n session: getSession(self),\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.connectedViewId,\n })\n },\n showSyntenyView(trackId: string) {\n launchSyntenyView({\n session: getSession(self),\n contributors: self.launchableAssemblies,\n trackId,\n graphTrackId: self.sourceTrackId,\n })\n },\n }))\n .views(self => ({\n // Synteny datasets that could fill the panels of a multi-genome launch.\n // Below two openable contributors there is nothing to compare, so the scan\n // is skipped rather than run and discarded.\n get syntenyLaunchTracks() {\n const samples = self.launchableAssemblies.map(c => c.sample)\n return samples.length >= 2\n ? launchableSyntenyTracks(getSession(self), samples)\n : []\n },\n }))\n .views(self => ({\n // The graph's way out, in the same shared \"Launch view\" submenu every\n // other view contributes to. Until this existed the triangle had two edges:\n // a linear view could open a graph or a synteny view of a locus, and the\n // graph could open nothing at all.\n // Which samples' walks walk rows show: every one, those whose walk and\n // the picked repeat's call disagree, or a set picked by name\n walkRowSampleMenuItems(): MenuItem[] {\n const { disagreeing } = self.walkRowSampleChoices\n const shown = self.walkRowSamples\n const same = (a: string[]) => a.join('\\n') === shown?.join('\\n')\n return [\n {\n type: 'radio',\n label: 'Every sample',\n checked: shown === undefined,\n onClick: () => {\n self.setWalkRowSamples(undefined)\n },\n },\n ...(disagreeing.length > 0\n ? [\n {\n type: 'radio' as const,\n label: 'Where walk and call disagree',\n checked: same(disagreeing),\n onClick: () => {\n self.setWalkRowSamples(disagreeing)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Choose samples...',\n checked: shown !== undefined && !same(disagreeing),\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseSamplesDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n },\n // Which sample table column walk rows stack into sections by\n walkRowGroupMenuItems(): MenuItem[] {\n const field = self.walkRowGroups ? self.walkRowGroupBy?.field : undefined\n return [\n {\n type: 'radio',\n label: 'None',\n checked: field === undefined,\n onClick: () => {\n self.setWalkRowGroupBy(undefined)\n },\n },\n ...self.walkRowGroupFields.map(column => ({\n type: 'radio' as const,\n label: column,\n checked: field === column,\n onClick: () => {\n self.setWalkRowGroupBy({ field: column })\n },\n })),\n ]\n },\n graphMenuItems(): MenuItem[] {\n const walks = self.walkChoices\n return [\n {\n label: 'Layout',\n subMenu: LAYOUT_MODES.map(mode => ({\n type: 'radio' as const,\n label: mode.label,\n checked: self.chosenLayoutMode === mode.value,\n disabled: self.graph ? !mode.available(self.graph) : false,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n })),\n },\n {\n label: 'Color',\n subMenu: COLOR_SCHEMES.map(scheme => ({\n type: 'radio' as const,\n label: scheme.label,\n checked: self.chosenColorScheme === scheme.value,\n onClick: () => {\n self.setColorScheme(scheme.value)\n },\n })),\n },\n ...(walks.length > 0 && self.liftsWalks\n ? [\n {\n label: 'Walk',\n subMenu: [\n {\n label: 'None',\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n {\n label: 'Side by side',\n subMenu: FACET_FIELDS.map(({ value, label }) => ({\n type: 'radio' as const,\n label,\n checked: self.facet.field === value,\n onClick: () => {\n self.setFacet(value)\n },\n })),\n },\n ]\n : []),\n ...(self.facetPanels &&\n self.facet.field === 'walk' &&\n !self.hostPlacesX\n ? [\n {\n label: 'Columns',\n subMenu: [\n undefined,\n ...self.facetPanels.map((_, i) => i + 1),\n ].map(columns => ({\n type: 'radio' as const,\n label:\n columns === undefined ? 'Auto' : `${columns}`,\n checked: self.facet.columns === columns,\n onClick: () => {\n self.setFacetColumns(columns)\n },\n })),\n },\n ]\n : []),\n ...(walks.length > WALK_MENU_ITEMS\n ? [\n {\n label: 'Choose walks...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(walks.length > WALK_MENU_ITEMS\n ? walks.filter(walk =>\n self.walkLayers.some(l => l.walk === walk.name),\n )\n : walks\n ).map(walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: self.walkLayers.some(l => l.walk === walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n })),\n ...self.drawnWalks.map(lifted => ({\n label: `Colour ${self.walkLabel(lifted.name)}`,\n subMenu: [\n { type: 'subHeader' as const, label: 'Colour by' },\n ...WALK_FIELDS.map(field => ({\n type: 'radio' as const,\n label: field.label,\n checked: lifted.encoding.field === field.value,\n onClick: () => {\n self.setWalkColor(lifted.name, {\n field: field.value,\n })\n },\n })),\n { type: 'subHeader' as const, label: 'Palette' },\n // the rainbow is the reference-position ramp\n ...WALK_SCHEMES.filter(\n scheme =>\n scheme.value !== 'rainbow' ||\n lifted.encoding.field === 'reference',\n ).map(scheme => ({\n type: 'radio' as const,\n label: scheme.label,\n checked: lifted.encoding.scheme === scheme.value,\n onClick: () => {\n self.setWalkColor(lifted.name, {\n scheme: scheme.value,\n })\n },\n })),\n ],\n })),\n ],\n },\n ]\n : []),\n ...(TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? [\n {\n label: 'Fold variants',\n subMenu: TUBE_MAP_FOLDS.map(({ bp, label }) => ({\n type: 'radio' as const,\n label,\n checked: self.tubeMapFold === bp,\n disabled: bp > 0 && self.graph?.reads !== undefined,\n onClick: () => {\n self.setTubeMapFold(bp)\n void self.recomputeLayout()\n },\n })),\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.repeatChoices.length > 0\n ? [\n {\n label: 'Repeat',\n subMenu: [\n {\n type: 'radio' as const,\n label: 'Whole window',\n checked: self.repeatKey === '',\n onClick: () => {\n self.setRepeatKey('')\n },\n },\n ...self.repeatChoices.map(({ key, name, unit }) => ({\n type: 'radio' as const,\n label: `${name} \u00B7 ${unit.toLocaleString()} bp unit`,\n checked: self.repeatKey === key,\n onClick: () => {\n self.setRepeatKey(key)\n },\n })),\n ],\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' && self.walkRowBars\n ? [{ label: 'Samples', subMenu: this.walkRowSampleMenuItems() }]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.walkRowBars &&\n self.walkRowGroupFields.length > 0\n ? [{ label: 'Group by\u2026', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n {\n label: 'Zoom in',\n onClick: () => {\n self.zoom(\n 1.5,\n self.viewBox.width / 2,\n self.viewBox.height / 2,\n )\n },\n },\n {\n label: 'Zoom out',\n onClick: () => {\n self.zoom(\n 1 / 1.5,\n self.viewBox.width / 2,\n self.viewBox.height / 2,\n )\n },\n },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.zoomToFit()\n },\n },\n ]),\n {\n type: 'checkbox',\n label: 'Mark bubbles',\n checked: self.showBubbles,\n onClick: () => {\n self.setShowBubbles(!self.showBubbles)\n },\n },\n {\n type: 'checkbox',\n label: 'Show deletion edges',\n checked: self.showDeletionEdges,\n onClick: () => {\n void self.toggleDeletionEdges()\n },\n },\n {\n type: 'checkbox',\n label: 'Genes on the backbone',\n checked: self.showGenes,\n onClick: () => {\n self.setShowGenes(!self.showGenes)\n },\n },\n ...(!self.host &&\n self.modeDrawsNodes &&\n (self.graph?.paths?.length ?? 0) > 1\n ? [\n {\n type: 'checkbox' as const,\n label: 'Walk rows under the graph',\n checked: self.walkStrip,\n onClick: () => {\n self.setWalkStrip(!self.walkStrip)\n },\n },\n ]\n : []),\n ...(self.referenceStripApplies\n ? [\n {\n type: 'checkbox' as const,\n label: 'Reference strip at bp',\n checked: self.showReferenceStrip,\n onClick: () => {\n self.setShowReferenceStrip(!self.showReferenceStrip)\n },\n },\n ]\n : []),\n {\n label: 'Export SVG',\n disabled: self.figureUnavailable !== undefined,\n disabledHelpText: self.figureUnavailable,\n onClick: () => {\n const svg = self.figure()\n if (svg) {\n downloadText(\n svg,\n `${(self.graph?.name ?? 'graph').replaceAll(/[^\\w.-]+/g, '_')}.svg`,\n )\n }\n },\n },\n {\n label: 'Copy figure spec',\n disabled: self.figureSpecUnavailable !== undefined,\n disabledHelpText: self.figureSpecUnavailable,\n onClick: () => {\n const spec = self.figureSpec()\n const session = getSession(self)\n navigator.clipboard\n .writeText(`${JSON.stringify(spec, null, 2)}\\n`)\n .then(() => {\n session.notify(\n 'Figure spec copied. Save it as spec.json and run: npx -p @jbrowse/bandage-core bandage-figure spec.json -o figure.svg',\n 'info',\n )\n })\n .catch((e: unknown) => {\n session.notify(`Could not copy the figure spec: ${String(e)}`)\n })\n },\n },\n ]\n },\n launchMenuItems(): MenuItem[] {\n const items: MenuItem[] = []\n for (const item of graphLaunchMenuItems({\n contributors: self.launchableAssemblies,\n syntenyTracks: self.syntenyLaunchTracks,\n onShowLinear: target => {\n self.showInLinearView(target)\n },\n onShowSynteny: trackId => {\n self.showSyntenyView(trackId)\n },\n })) {\n pushLaunchViewMenuItem(items, item)\n }\n return items\n },\n }))\n", "import { lazy } from 'react'\n\nimport { BUBBLE_SPREAD_VALUES } from '@jbrowse/bandage-core/bubbleSpreads'\nimport { COLOR_SCHEME_VALUES } from '@jbrowse/bandage-core/colorSchemes'\nimport { facetSettingOf } from '@jbrowse/bandage-core/facetGrid'\nimport { createForceLayoutCache } from '@jbrowse/bandage-core/layout/forceCache'\nimport { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { NODE_WIDTH_VALUES } from '@jbrowse/bandage-core/nodeWidths'\nimport { viewportOf } from '@jbrowse/bandage-core/viewport'\nimport { types } from '@jbrowse/mobx-state-tree'\nimport { RenderLifecycleMixin } from '@jbrowse/render-core/RenderLifecycleMixin'\n\nimport { lenientMaybeEnum, lenientOptionalEnum } from '../lenientEnum'\nimport { groupByOf } from '../walkRowGroups'\n\nimport type { SubgraphRegion } from '../../GetSubgraph'\nimport type { RepeatArray } from '../repeats/repeatFeatures'\nimport type { SampleRow, WalkRowGroupBy } from '../walkRowGroups'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { FacetInput } from '@jbrowse/bandage-core/facetGrid'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { AxisScale } from '@jbrowse/bandage-core/util/geometry'\nimport type { WalkLayer } from '@jbrowse/bandage-core/walkEncoding'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\n// Ceiling on the pane, and what it falls back to before there is a layout to\n// size against. A roughly square drawing (FMMM) hits this and keeps the\n// scrollable pane it has always had.\nexport const MAX_CANVAS_HEIGHT = 600\n// Floor, so a window holding only backbone \u2014 one row, no height at all \u2014 still\n// leaves room to hover a node and read its tooltip.\nexport const MIN_CANVAS_HEIGHT = 160\n// the pane's background, as the renderer clears to it and as CSS\nexport const PAPER_LIGHT: [number, number, number, number] = [1, 1, 1, 1]\nexport const PAPER_DARK: [number, number, number, number] = [\n 0.12, 0.12, 0.12, 1,\n]\nexport const paperCss = ([r, g, b]: number[]) =>\n `rgb(${[r, g, b].map(v => Math.round(v! * 255)).join(', ')})`\n// The thinnest a fit draws a tube map's tubes\nexport const MIN_FIT_TUBE_PX = 5\n\nexport const TUBE_MAP_MODES = new Set<string>(['tubemap', 'tubemapref'])\n\nexport const ChooseSamplesDialog = lazy(\n () => import('../components/ChooseSamplesDialog'),\n)\nexport const ChooseWalksDialog = lazy(\n () => import('../components/ChooseWalksDialog'),\n)\n\n// Past this many walks the Walk menu lists only the lifted ones and offers a\n// searchable picker\nexport const WALK_MENU_ITEMS = 12\n\n// The facet as a session writes it, in the shape every JBrowse display's\n// `facet` takes: a bare field, or the field with the panels' order and how\n// many go across. A field this pane cannot split on reads as none.\nconst facetModel = types.snapshotProcessor(\n types.model('GraphFacet', {\n field: types.optional(types.enumeration(['', 'walk', 'sample']), ''),\n domain: types.optional(types.frozen<string[]>(), []),\n columns: types.maybe(types.number),\n }),\n {\n preProcessor: (snap: FacetInput | undefined) => facetSettingOf(snap),\n },\n)\n\n// The sizes a tube map folds variants under. MICB's 22 kb cut draws 475\n// columns whole, 34 under 3 bp and one under 50, where only its structural\n// variants would stand: human windows are mostly SNPs.\nexport const TUBE_MAP_FOLDS = [\n { bp: 0, label: 'None' },\n { bp: 3, label: 'Under 3 bp' },\n { bp: 10, label: 'Under 10 bp' },\n { bp: 50, label: 'Under 50 bp, leaving structural variants' },\n { bp: 1000, label: 'Under 1 kb' },\n]\n\nconst SEGMENTS_SUFFIX = '.segs.bed.gz'\n\n// The rGFA index prefix an adapter config names, from either spelling the\n// config schema accepts: the `uri` shorthand or an explicit segments location.\nexport function bubblePrefix(adapterConfig: Record<string, unknown>) {\n if (typeof adapterConfig.uri === 'string') {\n return adapterConfig.uri\n }\n const segments = adapterConfig.segmentsLocation as\n { uri?: string } | undefined\n const uri = segments?.uri\n return typeof uri === 'string' && uri.endsWith(SEGMENTS_SUFFIX)\n ? uri.slice(0, -SEGMENTS_SUFFIX.length)\n : undefined\n}\nexport const HOVER_BRIGHTEN = 1.4\nexport const SELECT_BRIGHTEN = 1.6\nexport const VIEWPORT_DEBOUNCE_MS = 150\nexport const VIEWPORT_PANES_BUILT = 1\n// How many walk rows read their haplotype's genes, the first rows down\nexport const WALK_GENE_ROWS = 40\n\n// What the canvas draws under the tube map, whose ink is all TubeMapOverlay's\nexport const EMPTY_BATCH: RenderBatch = {\n nodeStrokes: [],\n nodeStrokeRuns: new Map(),\n arrows: [],\n arrowRuns: new Map(),\n edgeCurves: [],\n edgeCurveRuns: new Map(),\n}\n\n// MobX tracks every observable read while a computed or autorun runs, so\n// passing values here registers them as dependencies without otherwise using\n// them.\nexport function dependOn(..._values: unknown[]) {}\n\n// Hard size cap for the single-mode graph view. Past it the view declines with a\n// \"zoom in\" message rather than switching to a degraded rendering mode \u2014 one mode\n// only, since the large-region case is a linear synteny view, not a graph.\n// (The `adr-027` citation this used to carry was stale: that number was reused\n// for wheel-input semantics after the large-mode ADR was removed in 9d8102f0b5.)\n//\n// This bounds the *fetch*, and it is the only cap that can be applied before one\n// happens. It is a poor proxy for cost, because cost tracks node count, so the\n// number is chosen against the density of the graphs it can actually guard: a\n// region is fetched through `getSubgraph`, and the rGFA cut is what this number\n// was chosen against (the GBZ cut is base-level and has its own `nodeLimit`,\n// which trips long before 5 Mb). Both measured rGFAs are sparse, and at 5 Mb\n// both land at or under the ~2k nodes that redraw in under 10 ms (see agent-docs/GRAPH_SCALE_AND_LOD.md):\n//\n// HPRC MC GRCh38 ~7,000 bp/segment whole 4.9 Mb MHC 1,173 nodes\n// ecoli minigraph 3,078 bp/segment whole 4.6 Mb genome 2,415 nodes\n//\n// Fetch cost does not scale with the window either: against the hosted HPRC\n// index a 4.9 Mb links query and a 100 kb one both cost ~1.3 s, being dominated\n// by HTTP setup. FMMM is the slowest consumer at this size and stays tolerable,\n// ~0.1-3 s for ~1k nodes depending on layout quality (bandage-layout-js), and it\n// runs off the main thread.\n//\n// A dense graph is what this cannot protect against, because bp per node varies\n// by orders of magnitude between graph types \u2014 a base-level pggb graph runs ~17\n// bp/node, where 5 Mb would be hundreds of thousands. Such a graph has no region\n// query to reach this check with today, and the node budget below is the cap that\n// catches it if one ever does.\nexport const MAX_GRAPH_REGION_BP = 5_000_000\n\n// The cap in a message, in the unit that reads: `5 Mb`, not `5000 kb`.\nexport function formatSpanBp(bp: number) {\n return bp >= 1_000_000\n ? `${+(bp / 1_000_000).toFixed(1)} Mb`\n : `${Math.round(bp / 1000)} kb`\n}\n\n// What the view will actually draw, checked once the graph is parsed and so\n// applying to a whole-file import as much as to a subgraph fetch. Measured on\n// bubble-chain graphs: ~1-2k nodes redraws in under 10 ms, 10k takes ~43 ms of\n// geometry and ~125k canvas draw calls per frame (single-digit fps while\n// panning), and 100k needs 632 ms and 75 MB of vertex buffers. So this is set\n// where the tab stops being usable rather than where it stops being smooth, and\n// it is a view prop rather than a constant so a session can raise it \u2014 the same\n// escape hatch strangepg gives with `-T N`.\nexport const DEFAULT_MAX_GRAPH_NODES = 20_000\n\n// A url bandage-figure can read again, or undefined for a local file\nexport function uriOf(location: FileLocation | undefined) {\n return location && 'uri' in location && location.uri\n ? new URL(location.uri, location.baseUri ?? window.location.href).href\n : undefined\n}\n\ntype ViewportOwner = 'fit' | 'user' | 'host'\n\ninterface BuiltViewport {\n scale: number\n bounds: Bounds\n viewportDirty: number\n}\n\nexport function geometryPainted(model: {\n viewportRebuildPending: boolean\n viewportDirty: number\n builtViewport?: BuiltViewport\n paintedViewport?: BuiltViewport\n}) {\n return (\n model.builtViewport !== undefined &&\n model.paintedViewport === model.builtViewport &&\n model.builtViewport.viewportDirty === model.viewportDirty &&\n !model.viewportRebuildPending\n )\n}\n\n// What the pane shows, in layout units: what each panel shows while faceted\nexport function paneViewportOf(model: {\n translateX: number\n translateY: number\n axisScale: AxisScale\n viewBox: { width: number; height: number }\n}): Bounds {\n const { width, height } = model.viewBox\n return viewportOf(model, model.axisScale, width, height)\n}\n\n// Force layouts already computed for a graph, keyed by the view props the\n// engine reads. Every layout mode is local and costs a millisecond except this\n// one, which is seconds: measured on the committed engine, a 1,201-node bubble\n// chain is 0.6 s proportional, 4.3 s at 'Wide bubbles' and 3.4 s at the highest\n// quality.\n//\n// Worth keeping because a session revisits the same layout. The two drawings\n// answer different questions and the README's own figure is one subgraph in\n// both, so Anchored <-> Force is a round trip a reader makes repeatedly \u2014 and\n// every control in the settings dialog calls `recomputeLayout` on change\n// whether or not the current mode reads what it changed, which made picking a\n// reference path in force mode a multi-second re-run of an identical layout.\n// Both are hits. The cache itself is core's, which BandageJS keeps too.\nexport const forceLayouts = createForceLayoutCache()\n\nexport const paneBase = types\n .compose(\n 'GraphPane',\n RenderLifecycleMixin(),\n types.model({\n // FMMM's iteration budget, 0-4, the same scale Bandage's own settings\n // dialog exposes: 3+1 iterations at 0, 15+10 at 1, 30+20 at 2, 60+40 at\n // 3, 120+60 at 4 (BandageNG layout/graphlayoutworker.cpp).\n //\n // 2 because that is what the engine we vendor ships as its default\n // (`graphLayoutQuality = IntSetting(2, 0, 4)`, program/settings.cpp).\n // This was 1 for no recorded reason, i.e. one step BELOW upstream, and a\n // first sight of any graph is the default: review kept asking whether\n // the drawing could be iterated more (\"are you sure you can't iterate it\n // more times for better layout?\") of figures that were simply on a lower\n // setting than the tool they come from. Cost at the sizes this view\n // draws is milliseconds, and the header states the layout time so the\n // difference is visible rather than asserted.\n layoutQuality: types.optional(types.number, 2),\n linearLayout: types.optional(types.boolean, false),\n // unset takes the host's default: force in a view of its own, the\n // display config's in a track\n layoutMode: lenientMaybeEnum(LAYOUT_MODE_VALUES),\n colorScheme: lenientMaybeEnum(COLOR_SCHEME_VALUES),\n // How far the force layout opens a bubble, which on a variation graph is\n // the difference between a legible drawing and a rope. See\n // BUBBLE_SPREADS; no effect on the reference-anchored layouts, which\n // place a node from its coordinates rather than from a force sim.\n bubbleSpread: lenientOptionalEnum(BUBBLE_SPREAD_VALUES, 'auto'),\n // Node thickness by depth, Bandage's own device; see NODE_WIDTHS.\n nodeWidth: lenientOptionalEnum(NODE_WIDTH_VALUES, 'depth'),\n // Whether the node layouts draw each bubble as a halo along its nodes\n // with a label that opens it. Off by default: on a base-level cut\n // every SNP's halo is a blob.\n showBubbles: types.optional(types.boolean, false),\n showDeletionEdges: types.optional(types.boolean, true),\n // The session's genes drawn onto the backbone: exons along the nodes\n // that carry them, names pinned at their midpoints. See genes/.\n showGenes: types.optional(types.boolean, true),\n // Whether a drawing in its own coordinates inside a linear view gets\n // the strip of reference segments at their bp. See referenceStrip.ts.\n showReferenceStrip: types.optional(types.boolean, true),\n // Variants under this many bp fold into the reference before a tube map\n // is laid out, each kept as a tick on its walk's tube (coarsen.ts); 0\n // draws every one\n tubeMapFold: types.optional(types.number, 0),\n // Which track the genes come from; empty picks the assembly's\n // annotation track (pickGeneTrack).\n geneTrackId: types.optional(types.string, ''),\n // Which track the walk rows read tandem repeat arrays from; empty\n // picks a track whose name says repeats (pickRepeatTrack).\n repeatTrackId: types.optional(types.string, ''),\n // The array the walk rows measure between and tile by, as\n // RepeatArray.key; empty measures the whole window untiled.\n repeatKey: types.optional(types.string, ''),\n // Samples whose walks the walk rows show, by the name before the\n // haplotype number; undefined shows every walk the cut holds.\n walkRowSamples: types.maybe(types.frozen<string[]>()),\n // The sample table column walk rows stack into sections by, read from\n // the source track's samplesTsvLocation; a bare field name or\n // `{ field, domain }`, anything else reading as ungrouped\n walkRowGroupBy: types.maybe(\n types.snapshotProcessor(types.frozen<WalkRowGroupBy | undefined>(), {\n preProcessor: (snap: unknown) => groupByOf(snap),\n }),\n ),\n // Walk rows in a strip under a layout that draws nodes, linked to the\n // drawing: a node's passes tick each bar, a bar's point lights its node\n walkStrip: types.optional(types.boolean, false),\n // Walks lifted out of the drawing, each a layer with a lane of its own\n // and the rest fading, coloured by the encoding it states or by the\n // default one. See walkEncoding.ts. Empty lifts none.\n walkLayers: types.optional(types.frozen<WalkLayer[]>(), []),\n // Facets, as a grammar of graphics splits a plot: `walk` draws the\n // pane once per lifted walk, side by side on the same layout, each\n // panel with that walk alone; `sample` puts a sample's haplotypes in\n // a row; `domain` orders the panels and `columns` fixes how many go\n // across. See facetPanels and facetCells.\n facet: types.optional(facetModel, {}),\n // Which of a general GFA's paths the anchored layouts put on x. A path\n // GFA's names are arbitrary and none of them is marked as the\n // reference, so this is a choice; empty means \"infer\", which is the\n // assembly a subgraph was cut against, and the first path in the file\n // for a whole-file import. No effect on an rGFA, whose segments carry\n // their own coordinates. See pathAnchoring.ts.\n referencePath: types.optional(types.string, ''),\n // Whether the toolbar spells out `fetch 12371ms \u00B7 layout 4ms \u00B7 geom 9ms`.\n // Off by default because it was in the toolbar of every published graph\n // figure, where a machine's fetch time is noise a reader has to skip\n // past. The numbers themselves are always on the element as `data-*`\n // attributes, which is what browser tests assert against, so hiding the\n // text costs no coverage.\n showPerf: types.optional(types.boolean, false),\n contigThickness: types.optional(types.number, 6),\n connectorThickness: types.optional(types.number, 2),\n darkMode: types.optional(types.boolean, false),\n scale: types.optional(types.number, 1),\n translateX: types.optional(types.number, 0),\n translateY: types.optional(types.number, 0),\n drawPaths: types.optional(types.boolean, false),\n // Ceiling on the drawing pane, in css px, for a session or a figure that\n // wants a shorter one than the drawing asks for. Unset means the built-in\n // MAX_CANVAS_HEIGHT, which is what every existing session gets.\n //\n // Why this is a knob rather than a smaller default: the pane is as tall\n // as the drawing's own aspect ratio (see canvasHeight), which is right \u2014\n // a graph that is twice as tall as it is wide should not be squeezed\n // into a strip. But one very long node in a cut of short ones makes that\n // aspect ratio all arc: the HPRC CHM13 figure draws a 142 kb allele\n // among sub-kb backbone segments, pins the 600 px ceiling and spends\n // most of it on the loop, with the chain squashed along the bottom edge.\n // Lowering the ceiling there scales the whole drawing down, which is\n // exactly the trade that figure wants and the wrong default for a graph\n // whose height is carrying information.\n paneHeight: types.maybe(types.number),\n // Raise to draw a bigger graph than the default budget allows; see\n // DEFAULT_MAX_GRAPH_NODES for what the numbers cost.\n maxGraphNodes: types.optional(types.number, DEFAULT_MAX_GRAPH_NODES),\n // The reference span the reference-position ramp runs over, for a graph\n // with no region of its own to span it\n colorDomain: types.maybe(types.frozen<{ start: number; end: number }>()),\n // the linear view a graph of its own is paired with for the hover sync\n connectedViewId: types.maybe(types.string),\n }),\n )\n .volatile(() => ({\n graph: undefined as Graph | undefined,\n // the reference window the graph on screen was cut for, set with it\n graphRegion: undefined as SubgraphRegion | undefined,\n // The walk the track's graph lies on for the region's assembly, which\n // the track's config declares; x starts along it unless the user chose\n // another. Undefined for an rGFA, whose backbone is fixed, and for a\n // graph with no region.\n loadedReferencePath: undefined as string | undefined,\n layoutResult: undefined as LayoutResult | undefined,\n // what the legends in the pane's top-right corner measure, so no label\n // is placed under them\n legendSize: { width: 0, height: 0 },\n // The bubble index rows over the cut window, when the source track has\n // one beside its segments. Undefined for a graph with no index, whose\n // bubbles are `derivedBubbles` instead.\n indexBubbles: undefined as MinigraphBubble[] | undefined,\n // the gene track's features over the cut window, read once per cut\n geneTrackFeatures: undefined as Feature[] | undefined,\n // each walk row's genes, read from its haplotype's own assembly, by walk\n // name\n walkGeneFeatures: undefined as Map<string, GeneModel[]> | undefined,\n // the source track's samples TSV, which walk rows group by\n walkRowSampleTable: undefined as SampleRow[] | undefined,\n // the tandem repeat arrays over the cut window, from the repeat track\n repeatArrays: undefined as RepeatArray[] | undefined,\n // The graphs the open bubble was popped out of, outermost first, each\n // with what closing back to it restores without a refetch. A stack so a\n // popped superbubble can be mapped and popped again.\n popStack: [] as {\n graph: Graph\n layoutMode: LayoutModeValue\n label: string\n indexBubbles: MinigraphBubble[] | undefined\n }[],\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n error: undefined as unknown,\n isLoading: false,\n loadCanceled: false,\n statusMessage: '',\n hoveredNode: null as string | null,\n // the walks of the per-sample lane row the linear view's pointer is on\n hoveredRowWalks: [] as string[],\n // the bubble whose label the pointer is on\n hoveredBubble: null as MinigraphBubble | null,\n // whether the pointer is over this pane, whose own hit test then says\n // what it is on\n pointerInPane: false,\n // the strip point the pointer is over, which lights its node above\n stripHover: null as { row: string; offset: number } | null,\n // the walk row the pointer is on, by walk name\n hoveredWalkRow: null as string | null,\n hoveredEdge: null as number | null,\n selectedNode: null as string | null,\n viewportDirty: 0,\n // Bumped when the layout's positions are mutated IN PLACE, which only a\n // node drag does. Separate from `viewportDirty` because that one also\n // fires on pan and zoom, and the things keyed off this \u2014 the two hit\n // indexes and the label placement's per-layout caches \u2014 do not depend on\n // the transform at all. Rebuilding a 12k-edge hit index because the user\n // panned cost ~14 ms of the first mousemove after every gesture.\n positionsVersion: 0,\n // Bumped per upload, so the hover autorun re-states its highlights\n // against the batch the renderer now holds.\n geometryVersion: 0,\n // The zoom and the window the current batch was built for; a pan that\n // stays inside it needs no rebuild.\n builtViewport: undefined as BuiltViewport | undefined,\n // The builtViewport whose batch is on the canvas\n paintedViewport: undefined as BuiltViewport | undefined,\n draggingNode: null as string | null,\n // Dragging the background rather than a node. Lives here beside\n // draggingNode instead of in a component ref+state pair, so the two\n // mutually exclusive drag modes are one piece of state read from one place.\n isPanning: false,\n // Who places the view. 'fit' refits it to every new layout, 'user' leaves\n // it where a gesture or a restored session put it, and 'host' takes x\n // from the linear view the pane sits in. Not derived from\n // `isDefaultViewport`, which zoomToFit itself invalidates on its first\n // run \u2014 that made the fit fire once against not-yet-measured dimensions\n // and then never re-fit.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n viewportOwner: 'fit' as ViewportOwner,\n viewportDirtyTimer: undefined as ReturnType<typeof setTimeout> | undefined,\n // 0 is never a live rAF handle, so it doubles as \"nothing pending\"\n positionsDirtyFrame: 0,\n // Performance instrumentation, surfaced in GraphStats for browser tests\n // to assert against budgets. `fetchMs` is the GetSubgraph RPC round-trip,\n // `layoutMs` is the Bandage FMMM compute time reported by the\n // GraphComputeLayout RPC, `geometryMs` is the main-thread buildGeometry\n // pass and `geometryStrokeCount` the node strokes it produced.\n lastFetchMs: undefined as number | undefined,\n // how many of the cut's reads the tube map was handed, of how many\n readsShown: undefined as { shown: number; total: number } | undefined,\n lastLayoutMs: undefined as number | undefined,\n lastGeometryMs: undefined as number | undefined,\n lastGeometryStrokeCount: undefined as number | undefined,\n viewportRebuildPending: false,\n }))\n", "import {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\nimport {\n drawnNodeLength\n} from \"./chunk-6JEWNXCQ.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/referenceSeeds.ts\nvar LANE_GAP = 30;\nfunction referenceSeeds(graph, scaling) {\n const { opts } = scaling;\n const drawn = new Map(\n scaling.nodes.map((node) => [node.id, drawnNodeLength(opts, node.length)])\n );\n const drawnOf = (id) => drawn.get(id) ?? opts.minimumNodeLength;\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const seeds = /* @__PURE__ */ new Map();\n let x = 0;\n for (const node of backbone) {\n seeds.set(node.id, { x, y: 0 });\n x += drawnOf(node.id) + opts.edgeLength;\n }\n const adjacent = buildNeighbors(graph);\n const depth = new Map(backbone.map((node) => [node.id, 0]));\n const queue = backbone.map((node) => node.id);\n for (const id of queue) {\n const at = seeds.get(id);\n const next = depth.get(id) + 1;\n for (const neighbour of adjacent.get(id) ?? []) {\n if (depth.has(neighbour)) {\n continue;\n }\n depth.set(neighbour, next);\n seeds.set(neighbour, { x: at.x + drawnOf(id) / 2, y: LANE_GAP * next });\n queue.push(neighbour);\n }\n }\n let unreached = 0;\n for (const node of graph.nodes) {\n if (!seeds.has(node.id)) {\n seeds.set(node.id, {\n x: unreached++ * x / graph.nodes.length,\n y: LANE_GAP * 3\n });\n }\n }\n return seeds;\n}\nfunction seededNodes(graph, scaling) {\n const seeds = referenceSeeds(graph, scaling);\n return scaling.nodes.map((node) => ({ ...node, ...seeds.get(node.id) }));\n}\n\nexport {\n referenceSeeds,\n seededNodes\n};\n", "import {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/orientToReference.ts\nfunction orientToReference(graph, positions) {\n const backbone = graph.nodes.filter(\n (node) => isBackbone(node) && (positions[node.id]?.length ?? 0) > 0\n );\n if (backbone.length < 2) {\n return positions;\n }\n const points = backbone.map((node) => {\n const segments = positions[node.id];\n const mid = segments[Math.floor(segments.length / 2)];\n return {\n x: mid.x,\n y: mid.y,\n r: node.stable.start + node.length / 2,\n w: node.length\n };\n });\n const weight = points.reduce((sum, p) => sum + p.w, 0);\n const cx = points.reduce((sum, p) => sum + p.x * p.w, 0) / weight;\n const cy = points.reduce((sum, p) => sum + p.y * p.w, 0) / weight;\n const cr = points.reduce((sum, p) => sum + p.r * p.w, 0) / weight;\n let sxr = 0;\n let syr = 0;\n for (const p of points) {\n sxr += p.w * (p.x - cx) * (p.r - cr);\n syr += p.w * (p.y - cy) * (p.r - cr);\n }\n const angle = -Math.atan2(syr, sxr);\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const out = {};\n for (const [id, segments] of Object.entries(positions)) {\n out[id] = segments.map((p) => {\n const x = p.x - cx;\n const y = p.y - cy;\n return { x: cx + c * x - s * y, y: cy + s * x + c * y };\n });\n }\n let below = 0;\n let above = 0;\n for (const node of graph.nodes) {\n if (isBackbone(node)) {\n continue;\n }\n for (const p of out[node.id] ?? []) {\n if (p.y > cy) {\n below++;\n } else {\n above++;\n }\n }\n }\n if (above > below) {\n for (const segments of Object.values(out)) {\n for (const p of segments) {\n p.y = 2 * cy - p.y;\n }\n }\n }\n return out;\n}\n\nexport {\n orientToReference\n};\n", "// src/gfa-core/gfaParser.ts\nfunction parseTag(tag, tags) {\n const nameEnd = tag.indexOf(\":\");\n const typeEnd = tag.indexOf(\":\", nameEnd + 1);\n if (nameEnd !== -1 && typeEnd !== -1) {\n const name = tag.slice(0, nameEnd);\n const type = tag.slice(nameEnd + 1, typeEnd);\n const val = tag.slice(typeEnd + 1);\n if (type === \"i\" || type === \"f\") {\n tags[name] = +val;\n } else if (type === \"Z\") {\n tags[name] = val;\n }\n }\n}\nfunction parseTags(fields) {\n const tags = {};\n for (const field of fields) {\n parseTag(field, tags);\n }\n return tags;\n}\nfunction stableCoordinate(node) {\n const { SN, SO, SR } = node.tags;\n return typeof SN === \"string\" && typeof SO === \"number\" && typeof SR === \"number\" ? { refName: SN, start: SO, rank: SR } : void 0;\n}\nvar GT = 62;\nvar LT = 60;\nfunction parseWalkBody(body) {\n const segments = [];\n let strand = \"+\";\n let start = 0;\n function push(end) {\n if (end > start) {\n segments.push({ id: body.slice(start, end), strand });\n }\n }\n for (let i = 0; i < body.length; i++) {\n const ch = body.charCodeAt(i);\n if (ch === GT || ch === LT) {\n push(i);\n strand = ch === GT ? \"+\" : \"-\";\n start = i + 1;\n }\n }\n push(body.length);\n return segments;\n}\nfunction parseGFA(file) {\n const graph = {\n nodes: [],\n links: [],\n paths: [],\n walks: [],\n header: [],\n id: \"\"\n };\n for (const rawLine of file.split(\"\\n\")) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith(\"H\")) {\n const [, ...rest] = line.split(\"\t\");\n graph.header.push(parseTags(rest));\n } else if (line.startsWith(\"S\")) {\n const [, name, ...rest] = line.split(\"\t\");\n let len;\n let seq;\n let tagfields;\n let gfa1 = false;\n const first = rest[0] ?? \"*\";\n if (/^\\d+$/.test(first)) {\n len = +first;\n seq = rest[1] ?? \"*\";\n tagfields = rest.slice(2);\n } else {\n gfa1 = true;\n seq = first;\n len = seq === \"*\" ? 0 : seq.length;\n tagfields = rest.slice(1);\n }\n const tags = parseTags(tagfields);\n if (gfa1 && \"LN\" in tags) {\n len = +tags.LN;\n }\n graph.nodes.push({ id: name, length: len, sequence: seq, tags });\n } else if (line.startsWith(\"E\")) {\n const [, , source, target, , , , , cigar, ...rest] = line.split(\"\t\");\n if (source && target) {\n graph.links.push({\n source: source.slice(0, -1),\n target: target.slice(0, -1),\n strand1: source.at(-1),\n strand2: target.at(-1),\n cigar: cigar ?? \"*\",\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"L\")) {\n const [, source, strand1, target, strand2, cigar, ...rest] = line.split(\"\t\");\n if (source && target && strand2) {\n graph.links.push({\n source,\n target,\n strand1,\n strand2,\n cigar: cigar ?? \"*\",\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"W\")) {\n const [, sample, hap, contig, start, end, body, ...rest] = line.split(\"\t\");\n if (sample && hap && contig && start && end && body) {\n graph.walks.push({\n sample,\n haplotype: +hap,\n contig,\n start: start === \"*\" ? -1 : +start,\n end: end === \"*\" ? -1 : +end,\n segments: parseWalkBody(body),\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"P\")) {\n const [, name, path, ...rest] = line.split(\"\t\");\n if (name && path) {\n graph.paths.push({ name, path, rest });\n }\n }\n }\n return graph;\n}\n\nexport {\n stableCoordinate,\n parseGFA\n};\n", "import {\n stableCoordinate\n} from \"./chunk-CDLPYR5O.js\";\nimport {\n pathOrigin,\n surveyPaths\n} from \"./chunk-ST2IBUAN.js\";\n\n// src/gfa/gfaConverter.ts\nfunction surveySegments(gfaGraph) {\n const canonical = /* @__PURE__ */ new Map();\n const traversals = /* @__PURE__ */ new Map();\n function claim(id, strand) {\n if (!canonical.has(id)) {\n canonical.set(id, strand);\n }\n }\n function traverse(id, strand) {\n claim(id, strand);\n traversals.set(id, (traversals.get(id) ?? 0) + 1);\n }\n for (const link of gfaGraph.links) {\n claim(link.source, link.strand1 === \"-\" ? \"-\" : \"+\");\n claim(link.target, link.strand2 === \"-\" ? \"-\" : \"+\");\n }\n for (const gfaPath of gfaGraph.paths) {\n for (const segment of gfaPath.path.split(\",\")) {\n traverse(segment.slice(0, -1), segment.endsWith(\"-\") ? \"-\" : \"+\");\n }\n }\n for (const walk of gfaGraph.walks) {\n for (const seg of walk.segments) {\n traverse(seg.id, seg.strand === \"-\" ? \"-\" : \"+\");\n }\n }\n return { canonical, traversals };\n}\nvar walkStart = (w) => w.start === -1 ? 0 : w.start;\nfunction anchorablePaths(gfaGraph) {\n return [\n ...gfaGraph.paths.map((p) => ({\n ...pathOrigin(p.name),\n steps: p.path.split(\",\").map((segment) => ({\n id: segment.slice(0, -1),\n strand: segment.endsWith(\"-\") ? \"-\" : \"+\"\n }))\n })),\n ...gfaGraph.walks.map((w) => ({\n name: `${w.sample}#${w.haplotype}#${w.contig}`,\n start: walkStart(w),\n steps: w.segments.map((s) => ({\n id: s.id,\n strand: s.strand === \"-\" ? \"-\" : \"+\"\n }))\n }))\n ];\n}\nfunction carriedSamples(gfaNode) {\n const sm = gfaNode.tags.SM;\n if (typeof sm !== \"string\") {\n return void 0;\n }\n const samples = sm.split(\",\").map((s) => s.trim()).filter(Boolean);\n return samples.length > 0 ? samples : void 0;\n}\nvar positive = (v) => typeof v === \"number\" && v > 0 ? v : void 0;\nfunction statedDepth({ tags, length }) {\n const count = positive(tags.RC) ?? positive(tags.FC) ?? positive(tags.KC);\n return positive(tags.dp) ?? positive(tags.DP) ?? (count !== void 0 && length > 0 ? count / length : void 0);\n}\nfunction makeNode(gfaNode, strand, depth) {\n return {\n id: `${gfaNode.id}${strand}`,\n name: gfaNode.id,\n length: gfaNode.length,\n depth,\n stable: stableCoordinate(gfaNode),\n samples: carriedSamples(gfaNode)\n };\n}\nfunction convertGFAToGraph(gfaGraph, name = \"Imported GFA\") {\n const nodes = [];\n const edges = [];\n const { canonical, traversals } = surveySegments(gfaGraph);\n const nodeId = (segmentId) => `${segmentId}${canonical.get(segmentId) ?? \"+\"}`;\n for (const gfaNode of gfaGraph.nodes) {\n const depth = statedDepth(gfaNode) ?? Math.max(traversals.get(gfaNode.id) ?? 1, 1);\n nodes.push(makeNode(gfaNode, canonical.get(gfaNode.id) ?? \"+\", depth));\n }\n for (const link of gfaGraph.links) {\n edges.push({\n from: nodeId(link.source),\n to: nodeId(link.target),\n fromStrand: link.strand1 === \"-\" ? \"-\" : \"+\",\n toStrand: link.strand2 === \"-\" ? \"-\" : \"+\"\n });\n }\n const paths = [];\n const edgeToPathsMap = /* @__PURE__ */ new Map();\n const edgeKey = (a, b) => [a, b].sort().join(\"--\");\n function recordPathEdges(nodeIds, name2) {\n for (let i = 0; i < nodeIds.length - 1; i++) {\n const key = edgeKey(nodeIds[i], nodeIds[i + 1]);\n if (!edgeToPathsMap.has(key)) {\n edgeToPathsMap.set(key, /* @__PURE__ */ new Set());\n }\n edgeToPathsMap.get(key).add(name2);\n }\n }\n for (const gfaPath of gfaGraph.paths) {\n const nodeIds = gfaPath.path.split(\",\").map((segment) => nodeId(segment.slice(0, -1)));\n paths.push({\n name: gfaPath.name,\n nodeIds,\n start: pathOrigin(gfaPath.name).start\n });\n recordPathEdges(nodeIds, gfaPath.name);\n }\n for (const walk of gfaGraph.walks) {\n const nodeIds = walk.segments.map((seg) => nodeId(seg.id));\n const name2 = `${walk.sample}#${walk.haplotype}#${walk.contig}`;\n paths.push({\n name: name2,\n nodeIds,\n start: walkStart(walk),\n sample: walk.sample,\n haplotype: walk.haplotype,\n contig: walk.contig\n });\n recordPathEdges(nodeIds, name2);\n }\n for (const edge of edges) {\n const pathIds = edgeToPathsMap.get(edgeKey(edge.from, edge.to));\n if (pathIds && pathIds.size > 0) {\n edge.pathIds = [...pathIds];\n }\n }\n const lengths = new Map(gfaGraph.nodes.map((n) => [n.id, n.length]));\n const anchoring = gfaGraph.paths.length > 0 || gfaGraph.walks.length > 0 ? surveyPaths(anchorablePaths(gfaGraph), (id) => lengths.get(id) ?? 0) : void 0;\n return {\n name,\n nodes,\n edges,\n paths: paths.length > 0 ? paths : void 0,\n anchorPaths: anchoring?.anchorPaths,\n pathVisits: anchoring?.pathVisits,\n // rGFA's own tags win wherever they are present; pathAnchoring only ever\n // fills in for a graph that carries none.\n anchoredBy: nodes.some((n) => n.stable) ? \"tags\" : void 0\n };\n}\n\nexport {\n convertGFAToGraph\n};\n", "// src/layout/deletionRoutes.ts\nvar ROUTE_ID = \"\\0deletion:\";\nvar ROUTE_FRACTION = 0.5;\nfunction withDeletionRoutes(graph, deletions, dropped = /* @__PURE__ */ new Set()) {\n const routes = new Map(\n deletions.map((d) => [d.edgeIndex, `${ROUTE_ID}${d.edgeIndex}`])\n );\n const edges = [];\n graph.edges.forEach((edge, ei) => {\n const id = routes.get(ei);\n if (dropped.has(ei)) {\n return;\n }\n if (id === void 0) {\n edges.push(edge);\n } else {\n const { fromStrand, toStrand } = edge;\n edges.push(\n { from: edge.from, to: id, ...fromStrand ? { fromStrand } : {} },\n { from: id, to: edge.to, ...toStrand ? { toStrand } : {} }\n );\n }\n });\n return {\n graph: {\n ...graph,\n nodes: [\n ...graph.nodes,\n ...[...routes.values()].map((id) => ({\n id,\n name: id,\n length: 0,\n depth: 0\n }))\n ],\n edges\n },\n routes,\n ids: new Set(routes.values())\n };\n}\nfunction routeNodes(graph, deletions, routes, drawnOf, opts) {\n const lengths = new Map(graph.nodes.map((n) => [n.id, n.length]));\n return deletions.map((d) => {\n const skipped = d.bypassed.reduce(\n (sum, id2) => sum + (lengths.get(id2) ?? 0),\n 0\n );\n const drawn = Math.max(\n opts.minimumNodeLength,\n drawnOf(skipped) * ROUTE_FRACTION\n );\n const id = routes.get(d.edgeIndex);\n return {\n id,\n name: id,\n length: Math.round(drawn * 1e6 / opts.nodeLengthPerMegabase),\n depth: 0\n };\n });\n}\nfunction takeRoutes(positions, routes) {\n const nodePositions = { ...positions };\n const deletionRoutes = {};\n for (const [edgeIndex, id] of routes) {\n const route = nodePositions[id];\n delete nodePositions[id];\n if (route?.length) {\n deletionRoutes[edgeIndex] = route;\n }\n }\n return { nodePositions, deletionRoutes };\n}\n\nexport {\n ROUTE_ID,\n withDeletionRoutes,\n routeNodes,\n takeRoutes\n};\n", "import {\n seededNodes\n} from \"./chunk-IGVV37VI.js\";\nimport {\n orientToReference\n} from \"./chunk-PUG7LXDF.js\";\nimport {\n convertGFAToGraph\n} from \"./chunk-72N5DJHZ.js\";\nimport {\n parseGFA\n} from \"./chunk-CDLPYR5O.js\";\nimport {\n anchorGraph\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n mergeRuns,\n splitRuns\n} from \"./chunk-TAMCZHLW.js\";\nimport {\n routeNodes,\n takeRoutes,\n withDeletionRoutes\n} from \"./chunk-JVLURPFW.js\";\nimport {\n spreadFor\n} from \"./chunk-UVBGRJQX.js\";\nimport {\n drawnLengthOf,\n drawnNodeLength,\n layoutScaling\n} from \"./chunk-6JEWNXCQ.js\";\nimport {\n closableDeletions,\n deletionEdges\n} from \"./chunk-N6FECAXP.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/pipeline.ts\nfunction loadGraph(text, name, opts = {}) {\n const graph = anchorGraph(\n convertGFAToGraph(parseGFA(text), name),\n opts.referencePath\n );\n if (graph.nodes.length === 0) {\n throw new Error(`No graph segments in ${name}`);\n }\n if (opts.maxNodes !== void 0 && graph.nodes.length > opts.maxNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${opts.maxNodes.toLocaleString()}). Zoom in to a smaller region, or raise maxGraphNodes on this view.`\n );\n }\n return graph;\n}\nvar ENGINE_DEFAULTS = {\n engine: \"fmmm\",\n quality: 2,\n linearLayout: false,\n bubbleSpread: \"auto\",\n spacing: 1,\n componentSeparation: 1,\n showDeletionEdges: true\n};\nfunction engineSettingsOf(s = {}) {\n return {\n engine: s.engine ?? ENGINE_DEFAULTS.engine,\n quality: s.quality ?? ENGINE_DEFAULTS.quality,\n linearLayout: s.linearLayout ?? ENGINE_DEFAULTS.linearLayout,\n bubbleSpread: s.bubbleSpread ?? ENGINE_DEFAULTS.bubbleSpread,\n spacing: s.spacing ?? ENGINE_DEFAULTS.spacing,\n componentSeparation: s.componentSeparation ?? ENGINE_DEFAULTS.componentSeparation,\n showDeletionEdges: s.showDeletionEdges ?? ENGINE_DEFAULTS.showDeletionEdges\n };\n}\nvar COMPONENT_SEPARATION = 15;\nfunction engineRequest(graph, scaling, settings) {\n const anchored = graph.nodes.some(isBackbone);\n const spaced = {\n ...scaling,\n opts: {\n ...scaling.opts,\n edgeLength: scaling.opts.edgeLength * (settings.spacing ?? 1)\n }\n };\n return {\n graph: {\n nodes: anchored ? seededNodes(graph, spaced) : spaced.nodes,\n edges: graph.edges\n },\n options: {\n quality: settings.quality,\n linearLayout: settings.linearLayout,\n ...spaced.opts,\n componentSeparation: COMPONENT_SEPARATION * (settings.componentSeparation ?? 1),\n ...anchored ? { rotateComponents: false } : {},\n engine: settings.engine ?? \"fmmm\"\n }\n };\n}\nfunction engineKey(graph, settings) {\n const anchored = graph.nodes.some(isBackbone);\n return `${settings.engine ?? \"fmmm\"}|${settings.quality}|${settings.linearLayout}|${settings.bubbleSpread}|${settings.spacing ?? 1}|${settings.componentSeparation ?? 1}|${settings.showDeletionEdges !== false}|${anchored}|${graph.referencePath ?? \"\"}`;\n}\nasync function forceLayout(graph, settings, engine) {\n const spread = spreadFor(settings.bubbleSpread);\n const found = deletionEdges(graph);\n const dropped = settings.showDeletionEdges === false ? closableDeletions(graph, found) : /* @__PURE__ */ new Set();\n const deletions = found.filter((d) => !dropped.has(d.edgeIndex));\n const routed = withDeletionRoutes(graph, deletions, dropped);\n const merged = mergeRuns(routed.graph, routed.ids);\n const runs = {\n ...merged.graph,\n nodes: merged.graph.nodes.filter((n) => !routed.ids.has(n.id))\n };\n const engineScaling = layoutScaling(runs, spread);\n const { result, duration } = await engine(\n engineRequest(\n merged.graph,\n {\n ...engineScaling,\n nodes: [\n ...engineScaling.nodes,\n ...routeNodes(\n graph,\n deletions,\n routed.routes,\n drawnLengthOf(runs, spread),\n engineScaling.opts\n )\n ]\n },\n settings\n )\n );\n const scaling = layoutScaling(graph, spread);\n const drawn = new Map(\n scaling.nodes.map((n) => [n.id, drawnNodeLength(scaling.opts, n.length)])\n );\n const positions = splitRuns(\n result.nodePositions,\n merged.runs,\n (id) => drawn.get(id) ?? 0\n );\n const { nodePositions, deletionRoutes } = takeRoutes(\n graph.nodes.some(isBackbone) ? orientToReference(graph, positions) : positions,\n routed.routes\n );\n return {\n result: {\n ...result,\n nodePositions,\n stranded: true,\n ...deletions.length ? { deletionRoutes, extent: layoutExtent(deletionRoutes) } : {}\n },\n duration\n };\n}\nfunction layoutExtent(nodePositions) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const segments of Object.values(nodePositions)) {\n for (const seg of segments) {\n minX = Math.min(minX, seg.x);\n minY = Math.min(minY, seg.y);\n maxX = Math.max(maxX, seg.x);\n maxY = Math.max(maxY, seg.y);\n }\n }\n return { minX, minY, maxX, maxY };\n}\nvar FIT_PADDING = 40;\nvar MIN_ZOOM = 1e-6;\nvar MAX_ZOOM = 100;\nfunction clampZoom(zoom) {\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoom));\n}\nfunction fittedTranslateY(bounds, usableHeight, yScale, padTop = FIT_PADDING) {\n const leftoverY = usableHeight - bounds.h * yScale;\n return padTop - bounds.minY * yScale + Math.max(0, leftoverY) / 2;\n}\nfunction fitTransform(bounds, paneWidth, paneHeight, pixelRows, {\n minScale = 0,\n padLeft = FIT_PADDING,\n padTop = FIT_PADDING,\n padRight = FIT_PADDING,\n padBottom = FIT_PADDING\n} = {}) {\n const usableWidth = paneWidth - padLeft - padRight;\n const usableHeight = paneHeight - padTop - padBottom;\n if (usableWidth <= 0 || usableHeight <= 0 || !(bounds.w > 0 || !pixelRows && bounds.h > 0)) {\n return void 0;\n }\n const fitX = bounds.w > 0 ? usableWidth / bounds.w : Infinity;\n const fitY = bounds.h > 0 ? usableHeight / bounds.h : Infinity;\n const scale = clampZoom(\n Math.max(minScale, pixelRows ? fitX : Math.min(fitX, fitY))\n );\n const leftoverX = usableWidth - bounds.w * scale;\n return {\n scale,\n translateX: padLeft - bounds.minX * scale + Math.max(0, leftoverX) / 2,\n translateY: fittedTranslateY(\n bounds,\n usableHeight,\n pixelRows ? 1 : scale,\n padTop\n )\n };\n}\nfunction drawingBounds(layout, opts = {}) {\n let { minX, minY, maxX, maxY } = layoutExtent(layout.nodePositions);\n const { region } = opts;\n if (layout.referenceAxis && region && region.end > region.start) {\n minX = region.start;\n maxX = region.end;\n }\n const extent = opts.extent ?? layout.extent;\n if (extent) {\n minX = Math.min(minX, extent.minX ?? minX);\n minY = Math.min(minY, extent.minY ?? minY);\n maxX = Math.max(maxX, extent.maxX ?? maxX);\n maxY = Math.max(maxY, extent.maxY ?? maxY);\n }\n return { minX, minY, w: maxX - minX, h: maxY - minY };\n}\n\nexport {\n loadGraph,\n ENGINE_DEFAULTS,\n engineSettingsOf,\n engineRequest,\n engineKey,\n forceLayout,\n layoutExtent,\n FIT_PADDING,\n clampZoom,\n fittedTranslateY,\n fitTransform,\n drawingBounds\n};\n", "import {\n engineKey,\n forceLayout\n} from \"./chunk-WZATPZNH.js\";\n\n// src/layout/forceCache.ts\nvar DEFAULT_SIZE = 4;\nfunction createForceLayoutCache(size = DEFAULT_SIZE) {\n const caches = /* @__PURE__ */ new WeakMap();\n const cacheOf = (graph) => {\n let cache = caches.get(graph);\n if (!cache) {\n cache = /* @__PURE__ */ new Map();\n caches.set(graph, cache);\n }\n return cache;\n };\n return {\n layout(graph, settings, engine) {\n const cache = cacheOf(graph);\n const key = engineKey(graph, settings);\n const hit = cache.get(key);\n if (hit) {\n return hit.run;\n }\n if (cache.size >= size) {\n cache.delete(cache.keys().next().value);\n }\n const started = performance.now();\n const entry = {\n run: forceLayout(graph, settings, engine).then((r) => {\n entry.done = r.result;\n return { ...r, duration: r.duration || performance.now() - started };\n })\n };\n entry.run.catch(() => cache.delete(key));\n cache.set(key, entry);\n return entry.run;\n },\n ready(graph, settings) {\n return caches.get(graph)?.get(engineKey(graph, settings))?.done;\n },\n inherit(from, to) {\n const cache = caches.get(from);\n if (cache && from !== to) {\n caches.set(to, cache);\n }\n }\n };\n}\n\nexport {\n createForceLayoutCache\n};\n", "import {\n clampZoom\n} from \"./chunk-WZATPZNH.js\";\n\n// src/viewport.ts\nfunction axisScaleOf(scale, pixelRows) {\n return { scaleX: scale, scaleY: pixelRows ? 1 : scale, pixelRows };\n}\nfunction viewportOf(t, axis, width, height) {\n return {\n minX: -t.translateX / axis.scaleX,\n minY: -t.translateY / axis.scaleY,\n maxX: (width - t.translateX) / axis.scaleX,\n maxY: (height - t.translateY) / axis.scaleY\n };\n}\nfunction padded(v, panes) {\n const w = (v.maxX - v.minX) * panes;\n const h = (v.maxY - v.minY) * panes;\n return {\n minX: v.minX - w,\n minY: v.minY - h,\n maxX: v.maxX + w,\n maxY: v.maxY + h\n };\n}\nfunction contains(outer, inner) {\n return inner.minX >= outer.minX && inner.maxX <= outer.maxX && inner.minY >= outer.minY && inner.maxY <= outer.maxY;\n}\nfunction zoomAbout(t, factor, centerX, centerY, pixelRows) {\n const scale = clampZoom(t.scale * factor);\n const ratio = scale / t.scale;\n return {\n scale,\n translateX: centerX - (centerX - t.translateX) * ratio,\n translateY: pixelRows ? t.translateY : centerY - (centerY - t.translateY) * ratio\n };\n}\nfunction screenToLayout(x, y, t, axis) {\n return {\n x: (x - t.translateX) / axis.scaleX,\n y: (y - t.translateY) / axis.scaleY\n };\n}\n\nexport {\n axisScaleOf,\n viewportOf,\n padded,\n contains,\n zoomAbout,\n screenToLayout\n};\n", "import { types } from '@jbrowse/mobx-state-tree'\n\n// Persisted choices that read a value outside `values` as unset. A plain\n// `types.enumeration` throws on one, so a session saved by a build that had an\n// option this one dropped failed to load at all; here it opens on the default.\nfunction knownOrUnset<T extends string>(values: readonly T[]) {\n return (value: string | undefined) =>\n values.includes(value as T) ? (value as T) : undefined\n}\n\nexport function lenientMaybeEnum<T extends string>(values: T[]) {\n return types.snapshotProcessor(types.maybe(types.enumeration(values)), {\n preProcessor: knownOrUnset(values),\n })\n}\n\nexport function lenientOptionalEnum<T extends string>(\n values: T[],\n fallback: T,\n) {\n return types.snapshotProcessor(\n types.optional(types.enumeration(values), fallback),\n { preProcessor: knownOrUnset(values) },\n )\n}\n", "import { contains } from '@jbrowse/bandage-core/viewport'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer } from '@jbrowse/mobx-state-tree'\nimport { autorun, reaction, untracked } from 'mobx'\n\nimport { withLoadActions } from './loadActions'\nimport { EMPTY_BATCH, dependOn, paneViewportOf } from './paneBase'\nimport {\n hoverInRegion,\n nodeForLgvHover,\n readLgvHover,\n} from '../../hoverSync/lgvHover'\nimport { walksForRow } from '../../hoverSync/rowWalks'\n\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\n\nexport const withRenderingActions = withLoadActions\n .actions(self => ({\n startRenderingBackend(backend: Renderer) {\n if (!self.autorunsInstalled) {\n // Autorun: keep the view fitted to the graph until the user moves it.\n // Reading fittedTransform tracks everything the fit depends on, so\n // it re-fits as the layout arrives, the canvas is measured and the\n // genes over a tube map claim their rows. A manual pan/zoom (or a\n // restored-session transform) makes the viewport the user's, and a\n // host makes it the linear view's.\n addDisposer(\n self,\n autorun(() => {\n if (\n self.fittedTransform &&\n untracked(() => self.viewportOwner === 'fit')\n ) {\n self.zoomToFit()\n }\n }),\n )\n\n addDisposer(\n self,\n // Faceting on or off, its columns, its count of panels and what\n // they split by each reshape the boxes the drawing is fitted into\n reaction(\n () => {\n const grid = self.facetGrid\n return grid\n ? `${self.facet.field} ${self.facetPanels?.length} ${grid.columns}`\n : ''\n },\n () => {\n self.refitView()\n },\n ),\n )\n // The walk rows' genes follow the rows: a new cut, a repeat pick or\n // a sample filter changes which haplotypes and spans they read\n addDisposer(\n self,\n reaction(\n () => ({\n graph: self.graph,\n reads: JSON.stringify(self.walkGeneReads?.reads ?? []),\n }),\n () => {\n void self.loadWalkGenes()\n },\n {\n fireImmediately: true,\n equals: (a, b) => a.graph === b.graph && a.reads === b.reads,\n },\n ),\n )\n // Walk rows read the source track's samples TSV, for Group by\u2026\n addDisposer(\n self,\n reaction(\n () =>\n self.chosenLayoutMode === 'walkrows'\n ? JSON.stringify(self.walkRowSamplesTsv ?? null)\n : undefined,\n key => {\n if (key !== undefined) {\n void self.loadWalkRowSampleTable()\n }\n },\n { fireImmediately: true },\n ),\n )\n // A host fits the rows once, when it takes the pane over, which is\n // before the legend measures the room it needs above them\n addDisposer(\n self,\n reaction(\n () => self.fitPadTop,\n () => {\n if (self.viewportOwner === 'host') {\n self.zoomToFit()\n }\n },\n ),\n )\n\n // Autorun: mirror a connected linear view's hover onto the graph. An\n // LGV writes `{hoverPosition, hoverFeature}` to session.hovered on\n // every mousemove; neither field names the source view, so the guard\n // is that the position lies in the region this graph was cut from.\n // A pointer over the pane itself is the host's too, at a bp its x\n // only means on a reference-axis layout, so there the pane's own hit\n // test is the hover.\n //\n // Only `hovered` is tracked \u2014 the graph reads are untracked, so a\n // geometry rebuild can't re-fire this and clobber a hover the canvas\n // itself set. Assigning an unchanged id doesn't notify, so a hover\n // that travels within one segment costs nothing downstream.\n addDisposer(\n self,\n autorun(() => {\n const hover = readLgvHover(getSession(self).hovered)\n untracked(() => {\n const region = self.graphRegion\n const graph = self.graph\n const inRegion =\n hover && region && hoverInRegion(hover, region)\n ? hover\n : undefined\n // a row naming a walk is the hover, not the node at its bp,\n // whose band would cover the row's own cells\n const rowWalks =\n inRegion?.featureName && graph?.paths\n ? walksForRow(inRegion.featureName, graph.paths)\n : []\n if (region && graph && !self.pointerInPane) {\n self.setHoveredNode(\n inRegion && rowWalks.length === 0\n ? nodeForLgvHover({ hover: inRegion, nodes: graph.nodes })\n : null,\n )\n }\n self.setHoveredRowWalks(rowWalks)\n })\n }),\n )\n\n // Reaction: drop a hover the pointer cannot still be over.\n //\n // A hover is set by a mousemove on the canvas, and here the drawing\n // moves under a STATIONARY cursor on three axes \u2014 the wheel zoom, the\n // toolbar's zoom and fit buttons, and a pan \u2014 none of which fire a\n // pointer event. Left alone the tooltip goes on naming the node that\n // used to be under the cursor, `hoverHighlight` goes on publishing its\n // span, and the paired linear view paints a band over the wrong\n // sequence until the mouse happens to move.\n //\n // This is jbrowse-components' `installClearHoverOnViewportChange`\n // (BaseLinearDisplay), whose three axes are bpPerPx / offsetPx /\n // scrollTop; a graph view's are its own transform. Its rule is worth\n // restating rather than just citing: a sticky canvas gets no\n // mousemove and no mouseleave for any of them. Not imported because\n // it lives in the LGV plugin and reads a containing LGV, and this\n // plugin deliberately takes no runtime dependency on that plugin\n // (see hoverSync/index.tsx).\n //\n // A `reaction`, not an autorun, for the reason stated there: the\n // effect touches hover state, and an autorun would re-enter itself.\n // Selection is untouched \u2014 a click is a choice, and the content\n // moving does not unmake it.\n addDisposer(\n self,\n reaction(\n () => `${self.scale}-${self.translateX}-${self.translateY}`,\n () => {\n self.setHoveredNode(null)\n self.setHoveredBubble(null)\n self.setHoveredEdge(null)\n },\n { name: 'GraphClearHoverOnViewportChange' },\n ),\n )\n\n // Autorun: a zoom, or a pan that leaves the window the last build\n // covered, schedules a debounced rebuild. A pan inside it costs a\n // repaint and nothing else. Skips the first run.\n let firstViewport = true\n addDisposer(\n self,\n autorun(() => {\n const { scale } = self\n const viewport = paneViewportOf(self)\n if (firstViewport) {\n firstViewport = false\n return\n }\n const built = untracked(() => self.builtViewport)\n if (built?.scale === scale && contains(built.bounds, viewport)) {\n return\n }\n self.scheduleViewportDirty()\n }),\n )\n\n // Autorun: hover and selection. Tracks `geometryVersion` because an\n // upload drops the renderer's edge highlight.\n addDisposer(\n self,\n autorun(() => {\n const b = self.currentRenderingBackend as Renderer | undefined\n dependOn(self.geometryVersion)\n if (b) {\n self.applyHighlights(b)\n self.renderNow()\n }\n }),\n )\n }\n\n // The second argument is a SETUP THUNK, not the callbacks themselves:\n // anything it closes over lives exactly as long as the callbacks that\n // read it, which is what lets a per-backend memo work.\n self.attachRenderingBackend<Renderer>(backend, () => ({\n // Autorun: rebuild geometry when graph data or display options\n // change. scale/translate are untracked so they don't trigger a full\n // rebuild \u2014 only the debounced viewportDirty flag does.\n upload: (b: Renderer) => {\n b.resize(self.paneWidth, self.canvasHeight)\n if (self.layoutResult?.tubeMap) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, 0, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => paneViewportOf(self)),\n })\n return true\n }\n if (self.facetPanels) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, 0, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => self.viewportToBuild()),\n })\n return true\n }\n const geometryStart = performance.now()\n const built = self.buildDrawing(\n self.walkLift,\n self.effectiveDrawPaths,\n )\n if (built) {\n b.uploadGeometry(built.batch)\n self.setGeometryMetrics(\n performance.now() - geometryStart,\n built.batch.nodeStrokes.length,\n {\n scale: untracked(() => self.scale),\n bounds: built.viewportBounds,\n },\n )\n return true\n }\n // Nothing reached the backend, so the autorun may skip the redraw\n // it would otherwise force. Safe despite the resize above: with no\n // positions there is nothing to draw, which is the same case\n // `render` below returns false for.\n return false\n },\n // Autorun: re-render on pan/zoom/darkMode without rebuilding geometry\n render: (b: Renderer) => {\n if (!self.nodePositions) {\n return false\n }\n self.paint(b)\n self.markPainted()\n return true\n },\n releaseTargets: (b: Renderer) => {\n b.releaseOffscreenTargets()\n },\n }))\n },\n }))\n .actions(self => ({\n // A layout picked from a menu: the mode, then the drawing it makes.\n switchLayout(mode: LayoutModeValue) {\n self.setLayoutMode(mode)\n return self.recomputeLayout()\n },\n // Deletion edges shape a force layout, so it is laid out again without them\n toggleDeletionEdges() {\n self.setShowDeletionEdges(!self.showDeletionEdges)\n return self.usesLayoutEngine ? self.recomputeLayout() : undefined\n },\n // loads the source again, for a host that has one\n retryLoad() {},\n afterAttach() {\n // A restored session that already carries a non-default transform is\n // the user's own view \u2014 mark it so the fit autorun leaves it alone.\n if (!self.isDefaultViewport) {\n self.viewportOwner = 'user'\n }\n },\n }))\n", "import {\n trimOrigins\n} from \"./chunk-ST2IBUAN.js\";\n\n// src/bubbles/popBubble.ts\nfunction bubbleSubgraph(graph, segmentIds) {\n const keep = new Set(segmentIds);\n const nodes = graph.nodes.filter((n) => keep.has(n.name));\n const ids = new Set(nodes.map((n) => n.id));\n const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));\n const kept = /* @__PURE__ */ new Map();\n const paths = graph.paths?.flatMap((p) => {\n const first = p.nodeIds.findIndex((id) => ids.has(id));\n if (first < 0) {\n return [];\n }\n const nodeIds = p.nodeIds.filter((id) => ids.has(id));\n kept.set(p.name, { first, nodeIds });\n const before = p.nodeIds.slice(0, first).reduce((sum, id) => sum + (lengthOf.get(id) ?? 0), 0);\n return [\n {\n ...p,\n nodeIds,\n ...p.start === void 0 ? {} : { start: p.start + before }\n }\n ];\n });\n return {\n name: graph.name,\n nodes,\n edges: graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to)),\n ...paths?.length ? { paths } : {},\n anchorPaths: trimOrigins(graph, kept),\n pathVisits: graph.pathVisits,\n anchoredBy: graph.anchoredBy,\n referencePath: graph.referencePath\n };\n}\n\nexport {\n bubbleSubgraph\n};\n", "import {\n pathOrigin,\n trimOrigins\n} from \"../chunks/chunk-ST2IBUAN.js\";\nimport \"../chunks/chunk-BPLIXMH7.js\";\nimport {\n isBackbone,\n overlapsWindow\n} from \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/layout/trimToWindow.ts\nfunction trimToWindow(graph, window) {\n const inWindow = new Set(\n graph.nodes.filter((n) => isBackbone(n) && overlapsWindow(n, window)).map((n) => n.id)\n );\n const paths = graph.paths ?? [];\n if (inWindow.size === 0 || paths.length === 0) {\n return graph;\n }\n const spans = paths.map((path) => {\n let first = -1;\n let last = -1;\n path.nodeIds.forEach((id, i) => {\n if (inWindow.has(id)) {\n if (first < 0) {\n first = i;\n }\n last = i;\n }\n });\n return first < 0 ? void 0 : { first, last };\n });\n if (spans.every(\n (span, i) => span?.first === 0 && span.last === paths[i].nodeIds.length - 1\n )) {\n return graph;\n }\n const kept = /* @__PURE__ */ new Set();\n const trimmed = [];\n const stretches = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n const span = spans[i];\n if (span) {\n const nodeIds = path.nodeIds.slice(span.first, span.last + 1);\n for (const id of nodeIds) {\n kept.add(id);\n }\n trimmed.push({ ...path, nodeIds });\n stretches.set(path.name, { first: span.first, nodeIds });\n }\n });\n return {\n ...graph,\n nodes: graph.nodes.filter((n) => kept.has(n.id)),\n edges: graph.edges.filter((e) => kept.has(e.from) && kept.has(e.to)),\n paths: trimmed,\n pathVisits: graph.pathVisits && trimVisits(\n graph.pathVisits,\n paths,\n spans,\n new Map(graph.nodes.map((n) => [n.id, n.name]))\n ),\n anchorPaths: trimOrigins(graph, stretches)\n };\n}\nfunction trimVisits(visits, paths, spans, nameOf) {\n const cursor = /* @__PURE__ */ new Map();\n const out = /* @__PURE__ */ new Map();\n paths.forEach((path, p) => {\n const origin = pathOrigin(path.name).name;\n const span = spans[p];\n path.nodeIds.forEach((id, i) => {\n const segment = nameOf.get(id) ?? id;\n const list = visits.get(segment);\n if (!list) {\n return;\n }\n const key = `${origin}\t${segment}`;\n let at = cursor.get(key) ?? 0;\n while (at < list.length && list[at].path !== origin) {\n at++;\n }\n const visit = list[at];\n cursor.set(key, at + 1);\n if (visit && span && i >= span.first && i <= span.last) {\n const keptVisits = out.get(segment);\n if (keptVisits) {\n keptVisits.push(visit);\n } else {\n out.set(segment, [visit]);\n }\n }\n });\n });\n return out;\n}\nexport {\n trimToWindow\n};\n", "import {\n visitStrands\n} from \"../chunks/chunk-AYOSNXLQ.js\";\nimport {\n canonicalStrand\n} from \"../chunks/chunk-TEDQJPMI.js\";\nimport \"../chunks/chunk-C44YRP5F.js\";\nimport \"../chunks/chunk-7GBL7SJY.js\";\nimport \"../chunks/chunk-3ZZSX5HN.js\";\nimport \"../chunks/chunk-AB35TJST.js\";\nimport {\n pathOrigin\n} from \"../chunks/chunk-ST2IBUAN.js\";\nimport \"../chunks/chunk-BPLIXMH7.js\";\nimport \"../chunks/chunk-TAMCZHLW.js\";\nimport \"../chunks/chunk-N6FECAXP.js\";\nimport \"../chunks/chunk-2CVHXFK7.js\";\nimport \"../chunks/chunk-CPMHA4W5.js\";\nimport {\n isBackbone\n} from \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/tubeMap/coarsen.ts\nfunction readWalk(path, nodeById, strands) {\n const visitName = pathOrigin(path.name).name;\n const seen = /* @__PURE__ */ new Map();\n const runs = [];\n const open = () => ({ a: -Infinity, b: Infinity, detour: [], bp: 0 });\n const gaps = [open()];\n for (const id of path.nodeIds) {\n const node = nodeById.get(id);\n if (!node) {\n continue;\n }\n const k = seen.get(node.name) ?? 0;\n seen.set(node.name, k + 1);\n const strand = strands.get(`${visitName}\t${node.name}`)?.[k] ?? canonicalStrand(node);\n const gap = gaps.at(-1);\n const last = runs.at(-1);\n if (isBackbone(node)) {\n const start = node.stable.start;\n const end = start + node.length;\n const inverted = strand !== (node.stable.strand ?? \"+\");\n const joins = last !== void 0 && gap.detour.length === 0;\n if (joins && !last.inverted && !inverted && last.end === start) {\n last.end = end;\n } else if (joins && last.inverted && inverted && last.start === end) {\n last.start = start;\n } else {\n runs.push({ start, end, inverted });\n gaps.push(open());\n }\n } else {\n gap.detour.push({ node, strand });\n gap.bp += node.length;\n }\n }\n runs.forEach((run, i) => {\n gaps[i].b = run.start;\n gaps[i + 1].a = run.end;\n });\n return { path, runs, gaps };\n}\nfunction isSmall(gap, sigma) {\n return Number.isFinite(gap.a) && Number.isFinite(gap.b) && gap.b >= gap.a && Math.max(gap.b - gap.a, gap.bp) < sigma;\n}\nfunction strictlyInside(cuts, a, b) {\n let lo = 0;\n let hi = cuts.length;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n if (cuts[mid] <= a) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n return lo < cuts.length && cuts[lo] < b;\n}\nfunction referenceGaps(backbone) {\n const cuts = /* @__PURE__ */ new Map();\n for (let i = 1; i < backbone.length; i++) {\n const prev = backbone[i - 1];\n const node = backbone[i];\n const end = prev.stable.start + prev.length;\n if (end !== node.stable.start) {\n cuts.set(end, \"reference-gap\");\n cuts.set(node.stable.start, \"reference-gap\");\n }\n }\n return cuts;\n}\nfunction findCuts(walks, sigma, cuts) {\n const cut = (bp, cause) => {\n if (Number.isFinite(bp) && !cuts.has(bp)) {\n cuts.set(bp, cause);\n }\n };\n for (const { runs, gaps } of walks) {\n const first = runs[0];\n const last = runs.at(-1);\n if (first && last) {\n cut(first.start, \"walk-end\");\n cut(last.end, \"walk-end\");\n }\n for (const run of runs) {\n if (run.inverted && run.end - run.start >= sigma) {\n cut(run.start, \"inversion\");\n cut(run.end, \"inversion\");\n }\n }\n for (const gap of gaps) {\n if (gap.b < gap.a) {\n cut(gap.a, \"backward\");\n cut(gap.b, \"backward\");\n } else if (!isSmall(gap, sigma)) {\n cut(gap.a, \"variant\");\n cut(gap.b, \"variant\");\n }\n }\n }\n for (let changed = true; changed; ) {\n changed = false;\n const sorted = [...cuts.keys()].sort((x, y) => x - y);\n const spans = walks.flatMap(({ runs, gaps }) => [\n ...gaps.filter((g) => isSmall(g, sigma)).map((g) => [g.a, g.b]),\n ...runs.filter((r) => r.inverted && r.end - r.start < sigma).map((r) => [r.start, r.end])\n ]);\n for (const [a, b] of spans) {\n if (strictlyInside(sorted, a, b)) {\n changed ||= !cuts.has(a) || !cuts.has(b);\n cut(a, \"overlap\");\n cut(b, \"overlap\");\n }\n }\n }\n return cuts;\n}\nfunction mergeReference(backbone, cuts) {\n const merged = [];\n let group = [];\n const close = () => {\n const first = group[0];\n const last = group.at(-1);\n if (first && last) {\n const bp0 = first.stable.start;\n const bp1 = last.stable.start + last.length;\n const name = `${bp0}-${bp1}`;\n merged.push({\n node: {\n id: `${name}+`,\n name,\n length: bp1 - bp0,\n depth: 0,\n stable: {\n refName: first.stable.refName,\n start: bp0,\n rank: 0,\n strand: \"+\"\n }\n },\n members: group\n });\n }\n group = [];\n };\n for (const node of backbone) {\n if (cuts.has(node.stable.start)) {\n close();\n }\n group.push(node);\n }\n close();\n return merged;\n}\nfunction coarsenTubeMap(graph, sigma) {\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const paths = graph.paths ?? [];\n if (backbone.length === 0 || paths.length === 0) {\n return void 0;\n }\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const strands = visitStrands(graph);\n const walks = paths.map((p) => readWalk(p, nodeById, strands));\n const cuts = findCuts(walks, sigma, referenceGaps(backbone));\n const sortedCuts = [...cuts.keys()].sort((x, y) => x - y);\n const merged = mergeReference(backbone, cuts);\n const starts = merged.map((m) => m.node.stable.start);\n const mergedAt = (bp) => {\n let lo = 0;\n let hi = starts.length - 1;\n while (lo < hi) {\n const mid = lo + hi + 1 >> 1;\n if (starts[mid] <= bp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo;\n };\n const members = /* @__PURE__ */ new Map();\n const coarseOf = /* @__PURE__ */ new Map();\n for (const m of merged) {\n members.set(\n m.node.id,\n m.members.map((n) => n.id)\n );\n for (const n of m.members) {\n coarseOf.set(n.id, m.node.id);\n }\n }\n const routes = /* @__PURE__ */ new Map();\n const routeFor = (gap) => {\n const key = `${gap.a}\t${gap.b}\t${gap.detour.map((s) => s.node.id + s.strand).join(\",\")}`;\n let node = routes.get(key);\n if (!node) {\n const name = `r${routes.size}`;\n node = {\n id: `${name}+`,\n name,\n length: gap.bp,\n depth: 0,\n stable: {\n refName: backbone[0].stable.refName,\n start: Number.isFinite(gap.a) ? gap.a : gap.b,\n rank: 1,\n strand: \"+\"\n }\n };\n routes.set(key, node);\n members.set(\n node.id,\n gap.detour.map((s) => s.node.id)\n );\n for (const s of gap.detour) {\n if (!coarseOf.has(s.node.id)) {\n coarseOf.set(s.node.id, node.id);\n }\n }\n }\n return node;\n };\n const deviations = /* @__PURE__ */ new Map();\n const coarsePaths = [];\n const pathVisits = /* @__PURE__ */ new Map();\n const edges = /* @__PURE__ */ new Map();\n const depth = /* @__PURE__ */ new Map();\n for (const { path, runs, gaps } of walks) {\n const steps = [];\n const devs = [];\n let continuing = false;\n const append = (node, strand) => {\n const last = steps.at(-1);\n if (!(continuing && last?.node === node && last.strand === strand)) {\n steps.push({ node, strand });\n }\n continuing = true;\n };\n const structural = (gap) => {\n continuing = false;\n if (gap.detour.length > 0) {\n append(routeFor(gap), \"+\");\n continuing = false;\n }\n };\n const fold = (gap) => {\n if (gap.bp > 0 || gap.b > gap.a) {\n devs.push({ start: gap.a, end: gap.b, bp: gap.bp });\n }\n const home = merged[mergedAt(gap.b > gap.a ? gap.a : gap.a - 1)];\n for (const s of gap.detour) {\n if (!coarseOf.has(s.node.id)) {\n coarseOf.set(s.node.id, home.node.id);\n members.get(home.node.id).push(s.node.id);\n }\n }\n };\n runs.forEach((run, i) => {\n const gap = gaps[i];\n if (isSmall(gap, sigma) && !strictlyInside(sortedCuts, gap.a, gap.b)) {\n fold(gap);\n } else {\n structural(gap);\n }\n const i0 = mergedAt(run.start);\n const i1 = mergedAt(run.end - 1);\n const small = run.end - run.start < sigma;\n if (run.inverted && !small) {\n continuing = false;\n for (let j = i1; j >= i0; j--) {\n append(merged[j].node, \"-\");\n }\n continuing = false;\n } else {\n if (run.inverted) {\n devs.push({\n start: run.start,\n end: run.end,\n bp: run.end - run.start,\n inverted: true\n });\n }\n for (let j = i0; j <= i1; j++) {\n append(merged[j].node, \"+\");\n }\n }\n });\n structural(gaps.at(-1));\n const visitName = pathOrigin(path.name).name;\n let pos = 0;\n steps.forEach(({ node, strand }, i) => {\n depth.set(node.id, (depth.get(node.id) ?? 0) + 1);\n const visits = pathVisits.get(node.name) ?? [];\n visits.push({\n path: visitName,\n sample: path.sample ?? visitName,\n start: pos,\n strand\n });\n pathVisits.set(node.name, visits);\n pos += node.length;\n const next = steps[i + 1];\n if (next) {\n const key = `${node.id}${strand}\t${next.node.id}${next.strand}`;\n const edge = edges.get(key);\n if (edge) {\n edge.pathIds.push(path.name);\n } else {\n edges.set(key, {\n from: node.id,\n to: next.node.id,\n fromStrand: strand,\n toStrand: next.strand,\n pathIds: [path.name]\n });\n }\n }\n });\n coarsePaths.push({ ...path, nodeIds: steps.map((s) => s.node.id) });\n deviations.set(path.name, devs);\n }\n const nodes = [...merged.map((m) => m.node), ...routes.values()].filter((n) => depth.has(n.id)).map((n) => ({ ...n, depth: depth.get(n.id) }));\n return {\n graph: {\n ...graph,\n nodes,\n edges: [...edges.values()],\n paths: coarsePaths,\n pathVisits,\n reads: void 0\n },\n members,\n coarseOf,\n deviations,\n cuts\n };\n}\nexport {\n coarsenTubeMap\n};\n", "import {\n BUBBLE_KIND_NAMES,\n bubbleSegmentIds,\n classifyBubble,\n} from '@jbrowse/bandage-core/bubbles/classifyBubble'\nimport { bubbleSubgraph } from '@jbrowse/bandage-core/bubbles/popBubble'\nimport { trimToWindow } from '@jbrowse/bandage-core/layout/trimToWindow'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n anchorFromPaths,\n chooseReferencePath,\n} from '@jbrowse/bandage-core/pathAnchoring'\nimport { engineSettingsOf, loadGraph } from '@jbrowse/bandage-core/pipeline'\nimport { assemblyWalk } from '@jbrowse/bandage-core/reference'\nimport { coarsenTubeMap } from '@jbrowse/bandage-core/tubeMap/coarsen'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport {\n getRpcSessionId,\n getSession,\n statusMessageText,\n} from '@jbrowse/core/util'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { flow, isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { TUBE_MAP_MODES, bubblePrefix, forceLayouts } from './paneBase'\nimport { withSettingActions } from './settingActions'\nimport { namesReads } from '../../GetGraphReads'\nimport { locLabel } from '../../launchFromGraph/contributors'\nimport { geneModelsFrom } from '../genes/geneFeatures'\nimport { repeatArraysFrom } from '../repeats/repeatFeatures'\nimport { parseSamplesTsv } from '../walkRowGroups'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../../GetSubgraph'\nimport type { GafReads } from '../../gaf/gafFile'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport const withLoadActions = withSettingActions.actions(self => {\n let loadController: AbortController | undefined\n // the samples TSV location the table was read from, or is being read from\n let sampleTableKey: string | undefined\n\n function callEngine(request: EngineRequest) {\n const { rpcManager } = getSession(self)\n return rpcManager.call(getRpcSessionId(self), 'GraphComputeLayout', {\n ...request,\n signal: loadController?.signal,\n // A StatusCallback takes an RpcStatus, not a string \u2014 it may be a\n // bare label, a phase, or a phase that threw. `statusMessageText` is\n // core's reader for the human-facing line.\n statusCallback: status => {\n self.setStatusMessage(statusMessageText(status) ?? '')\n },\n }) as Promise<{ result: LayoutResult; duration: number }>\n }\n\n function engineSettings() {\n return engineSettingsOf({\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n })\n }\n\n // Single dispatch point for every layout mode. A mode that returns a\n // result computed it locally; one that returns undefined can't draw this\n // graph and hands off to the remote FMMM engine, which is also how\n // 'force' is expressed. See LAYOUT_MODES.\n function* computeLayout(graph: Graph) {\n const start = performance.now()\n const tubeMap = TUBE_MAP_MODES.has(self.chosenLayoutMode)\n // a tube map draws the window; the cut's context is for walk rows\n const region = self.graphRegion\n const drawn = tubeMap && region ? trimToWindow(graph, region) : graph\n // reads are placed by the cut's segment names, which a fold renames\n const coarse =\n tubeMap && self.tubeMapFold > 0 && !drawn.reads\n ? coarsenTubeMap(drawn, self.tubeMapFold)\n : undefined\n const local = layoutModeByValue(self.chosenLayoutMode).run(\n coarse?.graph ?? drawn,\n self.graphRegion,\n self.host ? self.layoutResult?.sampleRows : undefined,\n )\n if (local) {\n const result =\n coarse && local.tubeMap\n ? { ...local, tubeMap: { ...local.tubeMap, coarse } }\n : local\n return { result, duration: performance.now() - start }\n }\n const settings = engineSettings()\n const hit = forceLayouts.ready(graph, settings)\n if (hit) {\n return { result: hit, duration: performance.now() - start }\n }\n return (yield forceLayouts.layout(graph, settings, callEngine)) as {\n result: LayoutResult\n duration: number\n }\n }\n\n // Which layout request is the live one. A layout is async and nothing in\n // the UI waits for it, so several are routinely in flight: every control\n // in the settings dialog fires `recomputeLayout` on change, and a force\n // layout takes seconds where an anchored one is instant.\n //\n // The graph identity below is not enough to order them, because the\n // competing requests are usually layouts of the SAME graph. Left to\n // resolve order the last one to FINISH won rather than the last one\n // asked for, so switching away from a slow force layout \u2014 to an anchored\n // mode, a cheaper bubble spread, a lower quality \u2014 drew the abandoned\n // one over the top of the chosen one seconds later, with the dropdown\n // still naming the choice that was discarded.\n let liveRequest = 0\n // a haplotype's genes by track and contig span, kept across cuts\n const walkGeneCache = new Map<string, GeneModel[]>()\n\n // Applied under a guard because a layout is async and the user can load a\n // different graph, or ask for a different layout of it, while one is in\n // flight; the stale result must not land.\n function* layoutInto(graph: Graph) {\n const request = ++liveRequest\n const isLive = () => self.graph === graph && request === liveRequest\n const signal = loadController?.signal\n let computed\n try {\n // the node cap is a drawing's cost, and walk rows draw a bar per walk\n if (self.modeDrawsNodes && graph.nodes.length > self.maxGraphNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${self.maxGraphNodes.toLocaleString()}). Pick Layout \u2192 Walk rows, zoom in to a smaller region, or raise maxGraphNodes on this view.`,\n )\n }\n computed = yield* computeLayout(graph)\n } catch (e) {\n // A discarded layout's failure is not the user's problem: the drawing\n // they asked for is on screen or on its way, and raising a banner\n // over it reports a graph as broken because a setting they moved on\n // from could not be drawn. An aborted one was discarded by the load\n // that replaced it, even when the graph is still the same object.\n if (!isLive() || signal?.aborted) {\n return false\n }\n throw e\n }\n const live = isLive()\n if (live) {\n self.layoutResult = computed.result\n self.setLayoutMs(computed.duration)\n }\n return live\n }\n\n // The walk a path graph's track puts on the region's assembly: the one\n // that names it, else the one chooseReferencePath infers\n function loadedReference(graph: Graph, region: SubgraphRegion) {\n const paths = graph.anchorPaths\n return graph.anchoredBy === 'paths' && paths\n ? (\n assemblyWalk(graph, self.assemblySpellings(region.assemblyName)) ??\n chooseReferencePath(paths, region.assemblyName)\n )?.name\n : undefined\n }\n\n // `keepSelection` for a re-cut of the same source: node ids survive one\n // where edge indexes do not, so the selection is found again by id.\n // `readsOf` fetches the reads over the parsed graph before its one\n // layout, since the tube map lays them out with the paths.\n function* parseAndLayout(\n text: string,\n name: string,\n region: SubgraphRegion | undefined,\n keepSelection = false,\n readsOf?: (graph: Graph) => Promise<GafReads>,\n ) {\n const signal = loadController?.signal\n self.setStatusMessage('Parsing GFA')\n const parsed = loadGraph(text, name, {\n referencePath: self.referencePath || region?.assemblyName,\n })\n const loaded = region ? loadedReference(parsed, region) : undefined\n const graph =\n !self.referencePath &&\n loaded !== undefined &&\n loaded !== parsed.referencePath\n ? anchorFromPaths(parsed, loaded)\n : parsed\n if (readsOf) {\n self.setStatusMessage('Reading alignments')\n try {\n const { records, total } = (yield readsOf(graph)) as GafReads\n graph.reads = records\n self.readsShown = { shown: records.length, total }\n } catch (e) {\n if (signal?.aborted) {\n return\n }\n console.warn('[GraphGenomeView] no reads for this graph', e)\n self.readsShown = undefined\n }\n if (signal?.aborted) {\n return\n }\n } else {\n self.readsShown = undefined\n }\n const selected = keepSelection ? self.selectedNode : null\n self.graph = graph\n self.graphRegion = region\n self.loadedReferencePath = loaded\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.popStack = []\n // hoveredEdge is an index into graph.edges and hoveredNode/selectedNode\n // are ids, so all three address the graph being replaced here. Carrying\n // them over points the tooltip and the highlight at whatever now happens\n // to sit at that index.\n self.clearInteractionState()\n if (selected !== null && self.nodeById?.has(selected)) {\n self.selectedNode = selected\n }\n self.setStatusMessage('Computing layout')\n yield* layoutInto(graph)\n }\n\n // Which load is the live one, for the reason liveRequest orders layouts:\n // every change in the settings dialog re-cuts, a remote cut takes seconds,\n // and the last one to finish is not the last one asked for.\n let liveLoad = 0\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n // The bubble index that the hosted HPRC build keeps beside its segments,\n // `<prefix>.bubbles.bed.gz`, read through the bubble adapter over the same\n // window. A graph whose source has no such file, the ordinary case for a\n // graph of one's own, keeps its derived bubbles, so a failure here is not\n // the graph's problem. A coarse cut reads none: its nodes are the\n // bubbles, and the index over its window can run to a chromosome's rows.\n function* loadBubbles(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n isLive: () => boolean,\n ) {\n // The track config arrives as written, so the prefix is either the\n // `uri` shorthand or the segments location it expands to.\n const prefix = bubblePrefix(adapterConfig)\n if (adapterConfig.type !== 'RgfaTabixAdapter' || prefix === undefined) {\n return\n }\n try {\n const features = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n {\n adapterConfig: {\n type: 'MinigraphBubbleAdapter',\n uri: `${prefix}.bubbles.bed.gz`,\n baseUri: adapterConfig.baseUri,\n assemblyNameToPanSN: adapterConfig.assemblyNameToPanSN,\n },\n regions: [region],\n },\n )) as Feature[]\n if (isLive()) {\n self.indexBubbles = features.map(f => ({\n refName: region.refName,\n start: f.get('start'),\n end: f.get('end'),\n segmentCount: f.get('segmentCount') as number,\n pathCount: (f.get('pathCount') as number | undefined) ?? 0,\n inversion: f.get('inversion') as boolean,\n shortestAlleleLength: f.get('shortestAlleleLength') as number,\n longestAlleleLength: f.get('longestAlleleLength') as number,\n segments: f.get('segments') as string,\n shortestAllele: undefined,\n longestAllele: undefined,\n }))\n }\n } catch (e) {\n console.warn('[GraphGenomeView] no bubble index for this graph', e)\n }\n }\n\n // A session track's features over the cut. Undefined when the session\n // has no such track or the read fails: an annotation is never the\n // graph's problem.\n function* trackFeatures(\n trackId: string | undefined,\n region: SubgraphRegion,\n what: string,\n ) {\n const session = getSession(self)\n const config = trackId\n ? session.tracks.find(t => t.trackId === trackId)\n : undefined\n if (!config) {\n return undefined\n }\n try {\n return (yield session.rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n {\n adapterConfig: readConfObject(config, 'adapter'),\n regions: [region],\n },\n )) as Feature[]\n } catch (e) {\n console.warn(`[GraphGenomeView] no ${what} for this graph`, e)\n return undefined\n }\n }\n\n // The gene track's features over the cut, which `geneFeatures` makes genes\n // of for the backbone to carry.\n function* loadGenes(region: SubgraphRegion, isLive: () => boolean) {\n const features = yield* trackFeatures(\n self.geneTrack?.trackId,\n region,\n 'genes',\n )\n if (features && isLive()) {\n self.geneTrackFeatures = features\n }\n }\n\n // The tandem repeat arrays over the cut, from the session's repeat\n // track, for the walk rows to measure between and tile by.\n function* loadRepeats(region: SubgraphRegion, isLive: () => boolean) {\n const features = yield* trackFeatures(\n self.repeatTrack?.trackId,\n region,\n 'repeats',\n )\n if (features && isLive()) {\n self.repeatArrays = repeatArraysFrom(features)\n }\n }\n\n // Raises `isLoading` before any fetch, so a view waiting on a remote file\n // shows its loading state instead of the import form. Text already in\n // hand is parsed without yielding first. `region` is the window a\n // declared file was stated beside, which the parse anchors on.\n function* loadWholeGFA(\n name: string,\n source: string | ((signal: AbortSignal) => Promise<string>),\n region?: SubgraphRegion,\n ) {\n const { isLive, signal } = beginLoad()\n self.isLoading = true\n self.error = undefined\n try {\n const text =\n typeof source === 'string' ? source : ((yield source(signal)) as string)\n if (isLive()) {\n yield* parseAndLayout(text, name, region)\n }\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.loadWholeGFA]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n self.finishLoading()\n }\n }\n return isLive()\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n liveLoad++\n liveRequest++\n }\n\n // The graph and everything derived from it, dropped; any load in\n // flight ends too, or it would land its graph afterwards\n function dropGraph() {\n abortLoad()\n self.graph = undefined\n self.graphRegion = undefined\n self.loadedReferencePath = undefined\n self.layoutResult = undefined\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.readsShown = undefined\n self.popStack = []\n self.error = undefined\n self.isLoading = false\n self.loadCanceled = false\n self.statusMessage = ''\n self.clearInteractionState()\n self.clearPerfMetrics()\n }\n\n return {\n // back to the import form\n clearGraph() {\n dropGraph()\n },\n // The user's stop before anything is drawn. The source stays, so a\n // retry can load it again.\n cancelLoad() {\n if (self.canCancelLoad) {\n dropGraph()\n self.loadCanceled = true\n }\n },\n // The user's stop, leaving whatever is drawn under it\n stopLoad() {\n abortLoad()\n self.isLoading = false\n self.statusMessage = ''\n self.loadCanceled = true\n },\n beforeDestroy() {\n abortLoad()\n },\n loadGFA: flow(function* (text: string, name = 'Imported GFA') {\n yield* loadWholeGFA(name, text)\n }),\n loadGFAFromLocation: flow(function* (\n location: FileLocation,\n region?: SubgraphRegion,\n ) {\n self.setStatusMessage('Fetching GFA')\n const live = yield* loadWholeGFA(\n 'uri' in location ? (location.uri.split('/').pop() ?? 'GFA') : 'GFA',\n signal => openLocation(location).readFile({ encoding: 'utf8', signal }),\n region,\n )\n if (region && live && self.graph) {\n yield* loadRepeats(region, () => self.graphRegion === region)\n }\n }),\n // One cut of a region, laid out with the annotations over it. Whether\n // the region may be cut is the caller's call; overlapping cuts are\n // ordered by liveLoad, so the latest one lands.\n cutSubgraph: flow(function* (\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n opts: SubgraphCutOptions = {},\n ) {\n const { isLive, signal } = beginLoad()\n self.isLoading = true\n self.error = undefined\n self.setStatusMessage('Fetching subgraph')\n try {\n const fetchStart = performance.now()\n const gfaText = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetSubgraph',\n { adapterConfig, region, opts, signal },\n )) as string\n if (!isLive()) {\n return\n }\n self.setFetchMs(performance.now() - fetchStart)\n if (!gfaText) {\n throw new Error(\n 'Adapter returned no GFA \u2014 region may be outside indexed data or the adapter does not implement getSubgraph',\n )\n }\n yield* parseAndLayout(\n gfaText,\n locLabel(region),\n region,\n true,\n namesReads(adapterConfig)\n ? graph =>\n getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphReads',\n {\n adapterConfig,\n nodeNames: graph.nodes.map(n => n.name),\n signal,\n },\n )\n : undefined,\n )\n if (!isLive()) {\n return\n }\n // Independent remote reads, each landing as it arrives. A coarse\n // cut reads no bubble index: its nodes are the bubbles, and the\n // index over its window can run to a chromosome's rows.\n self.setStatusMessage('Reading annotations')\n yield Promise.all([\n opts.tier === 'coarse'\n ? undefined\n : flow(loadBubbles)(adapterConfig, region, isLive),\n flow(loadGenes)(region, isLive),\n flow(loadRepeats)(region, isLive),\n ])\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.cutSubgraph]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n self.finishLoading()\n }\n }\n }),\n // Re-read one annotation track alone, for a track change. The graph,\n // its layout and any open bubble stay as they are. Live only while the\n // track it read is still the one chosen, so a slow read cannot land\n // over the pick that followed it.\n reloadRepeats: flow(function* () {\n const region = self.graphRegion\n const trackId = self.repeatTrack?.trackId\n if (region) {\n yield* loadRepeats(\n region,\n () =>\n self.graphRegion === region &&\n self.repeatTrack?.trackId === trackId,\n )\n }\n }),\n // The source track's samples TSV, read once per location, for walk\n // rows to group by. A failed read leaves the rows ungrouped and says so.\n loadWalkRowSampleTable: flow(function* () {\n const location = self.walkRowSamplesTsv\n const key = location ? JSON.stringify(location) : undefined\n if (key === sampleTableKey) {\n return\n }\n sampleTableKey = key\n self.walkRowSampleTable = undefined\n if (!location) {\n return\n }\n try {\n const text = (yield openLocation(location).readFile('utf8')) as string\n if (isAlive(self) && key === sampleTableKey) {\n self.walkRowSampleTable = parseSamplesTsv(text)\n }\n } catch (e) {\n if (isAlive(self) && key === sampleTableKey) {\n getSession(self).notify(\n `Walk rows cannot be grouped: the samples table did not load (${String(e)})`,\n 'warning',\n )\n }\n }\n }),\n // The walk rows' genes, each row's from its haplotype's assembly. A\n // row's genes are its own contig's, so they take the row's name for\n // their contig, whatever the track calls it.\n loadWalkGenes: flow(function* () {\n const reads = self.walkGeneReads?.reads ?? []\n const key = JSON.stringify(reads)\n const graph = self.graph\n const fetched = new Map<string, GeneModel[]>()\n yield Promise.all(\n reads.map(({ row, trackId, region }) =>\n flow(function* () {\n const cacheKey = `${trackId} ${region.refName}:${region.start}-${region.end}`\n let genes = walkGeneCache.get(cacheKey)\n if (!genes) {\n const features = yield* trackFeatures(\n trackId,\n region,\n 'haplotype genes',\n )\n if (!features) {\n return\n }\n genes = geneModelsFrom(features).map(g => ({\n ...g,\n refName: region.refName,\n }))\n walkGeneCache.set(cacheKey, genes)\n }\n fetched.set(row, genes)\n })(),\n ),\n )\n if (\n isAlive(self) &&\n self.graph === graph &&\n JSON.stringify(self.walkGeneReads?.reads ?? []) === key\n ) {\n self.walkGeneFeatures = reads.length ? fetched : undefined\n }\n }),\n reloadGenes: flow(function* () {\n walkGeneCache.clear()\n const region = self.graphRegion\n const trackId = self.geneTrack?.trackId\n if (region) {\n yield* loadGenes(\n region,\n () =>\n self.graphRegion === region && self.geneTrack?.trackId === trackId,\n )\n }\n }),\n // Open one bubble: the graph becomes the segments the bubble row names,\n // drawn in the layout the reader is in. The graph it came from stays\n // behind it, one click away, and the popped graph gets its own derived\n // bubbles, so a superbubble opens progressively.\n popBubble: flow(function* (bubble: MinigraphBubble) {\n const graph = self.graph\n if (!graph) {\n return\n }\n const sub = bubbleSubgraph(graph, bubbleSegmentIds(bubble))\n if (sub.nodes.length === 0) {\n getSession(self).notify(\n 'None of the segments of this bubble are in the cut; widen the graph context to open it',\n 'info',\n )\n return\n }\n const { isLive } = beginLoad()\n self.popStack = [\n ...self.popStack,\n {\n graph,\n layoutMode: self.chosenLayoutMode,\n label: graph.name,\n indexBubbles: self.indexBubbles,\n },\n ]\n self.indexBubbles = undefined\n const label = `${BUBBLE_KIND_NAMES[classifyBubble(bubble, self.repeatArrays).kind]} at ${bubble.refName}:${bubble.start.toLocaleString()}`\n self.graph = { ...sub, name: label }\n self.clearInteractionState()\n self.viewportOwner = 'fit'\n self.isLoading = true\n try {\n if (yield* layoutInto(self.graph)) {\n self.finishLoading()\n }\n } catch (e) {\n if (isLive()) {\n self.error = e\n self.finishLoading()\n }\n }\n }),\n unpopBubble: flow(function* () {\n const from = self.poppedFrom\n if (!from) {\n return\n }\n self.popStack = self.popStack.slice(0, -1)\n self.graph = from.graph\n self.layoutMode = from.layoutMode\n self.indexBubbles = from.indexBubbles\n self.clearInteractionState()\n self.viewportOwner = 'fit'\n self.isLoading = true\n try {\n if (yield* layoutInto(from.graph)) {\n self.finishLoading()\n }\n } catch (e) {\n self.error = e\n self.finishLoading()\n }\n }),\n recomputeLayout: flow(function* () {\n const graph = self.graph\n if (!graph) {\n return\n }\n self.isLoading = true\n self.setStatusMessage('Computing layout')\n\n try {\n // A superseded request leaves the spinner to the request that\n // replaced it: clearing it here reports \"done\" while the layout the\n // user actually asked for is still being computed, which is the\n // common case when a cheap choice follows an expensive one.\n if (yield* layoutInto(graph)) {\n self.finishLoading()\n }\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n self.finishLoading()\n }\n }),\n }\n})\n", "import { FACET_PAD_PX } from '@jbrowse/bandage-core/facetGrid'\nimport { segmentAt } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { anchorFromPaths } from '@jbrowse/bandage-core/pathAnchoring'\nimport {\n FIT_PADDING,\n clampZoom,\n fittedTranslateY,\n} from '@jbrowse/bandage-core/pipeline'\nimport { nodeReferenceSpan } from '@jbrowse/bandage-core/referenceSpan'\nimport { zoomAbout } from '@jbrowse/bandage-core/viewport'\nimport { getSession, isSessionModelWithWidgets } from '@jbrowse/core/util'\nimport { isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { withFitViews } from './fitViews'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\n\nimport type { SampleRow, WalkRowGroupBy } from '../walkRowGroups'\nimport type { BubbleSpread } from '@jbrowse/bandage-core/bubbleSpreads'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { NodeWidth } from '@jbrowse/bandage-core/nodeWidths'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withFitViews\n .actions(self => ({\n setError(error: unknown) {\n self.error = error\n self.isLoading = false\n self.statusMessage = ''\n },\n finishLoading() {\n self.isLoading = false\n self.statusMessage = ''\n },\n setStatusMessage(message: string) {\n self.statusMessage = message\n },\n setFetchMs(ms: number) {\n self.lastFetchMs = ms\n },\n setLayoutMs(ms: number) {\n self.lastLayoutMs = ms\n },\n setGeometryMetrics(\n ms: number,\n strokeCount: number,\n built: { scale: number; bounds: Bounds },\n ) {\n self.lastGeometryMs = ms\n self.lastGeometryStrokeCount = strokeCount\n self.builtViewport = { ...built, viewportDirty: self.viewportDirty }\n self.geometryVersion++\n },\n markPainted() {\n self.paintedViewport = self.builtViewport\n },\n setLayoutQuality(quality: number) {\n self.layoutQuality = quality\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.layoutMode = mode\n },\n // Re-anchor in place rather than re-parsing: the coordinate walk is\n // already recorded on the graph, and only which path counts as rank 0\n // changes. The caller recomputes the layout, the same way it does after\n // setLayoutMode. An rGFA is left alone \u2014 its coordinates are not derived.\n setReferencePath(name: string) {\n self.referencePath = name\n const graph = self.graph\n if (graph?.anchoredBy === 'paths') {\n const reanchored = anchorFromPaths(graph, name)\n forceLayouts.inherit(graph, reanchored)\n self.graph = reanchored\n }\n },\n setDrawPaths(draw: boolean) {\n self.drawPaths = draw\n },\n setShowPerf(show: boolean) {\n self.showPerf = show\n },\n setColorScheme(scheme: ColorScheme) {\n self.colorScheme = scheme\n },\n setBubbleSpread(spread: BubbleSpread) {\n self.bubbleSpread = spread\n },\n setNodeWidth(width: NodeWidth) {\n self.nodeWidth = width\n },\n setShowBubbles(show: boolean) {\n self.showBubbles = show\n },\n setShowDeletionEdges(show: boolean) {\n self.showDeletionEdges = show\n },\n setShowGenes(show: boolean) {\n self.showGenes = show\n },\n setShowReferenceStrip(show: boolean) {\n self.showReferenceStrip = show\n },\n setTubeMapFold(bp: number) {\n self.tubeMapFold = bp\n },\n setGeneTrackId(trackId: string) {\n self.geneTrackId = trackId\n },\n setRepeatTrackId(trackId: string) {\n self.repeatTrackId = trackId\n },\n setRepeatKey(key: string) {\n self.repeatKey = key\n },\n setWalkLayers(layers: WalkLayer[]) {\n self.walkLayers = layers\n },\n // Lift the walks named, in that order, keeping the colour any of them\n // already had\n liftWalks(names: string[]) {\n const had = new Map(self.walkLayers.map(l => [l.walk, l]))\n self.walkLayers = names.map(walk => had.get(walk) ?? { walk })\n },\n // The field the panels split on; a change of field drops the order\n // written for the old one and keeps the column count\n setFacet(field: FacetSetting['field']) {\n if (field !== self.facet.field) {\n self.facet.domain = []\n }\n self.facet.field = field\n },\n setFacetColumns(columns: number | undefined) {\n self.facet.columns = columns\n },\n toggleWalk(walk: string) {\n const layers = self.walkLayers\n self.walkLayers = layers.some(l => l.walk === walk)\n ? layers.filter(l => l.walk !== walk)\n : [...layers, { walk }]\n },\n setWalkColor(walk: string, color: Partial<WalkEncoding>) {\n self.walkLayers = self.walkLayers.map(l =>\n l.walk === walk ? { ...l, color: { ...l.color, ...color } } : l,\n )\n },\n\n // Undefined restores the built-in ceiling. Nothing recomputes: the pane\n // reads canvasHeight and the drawing is placed by zoomToFit, which the\n // caller runs if it wants the drawing refitted into the new pane.\n setPaneHeight(px: number | undefined) {\n self.paneHeight = px\n },\n setWalkRowSamples(samples: string[] | undefined) {\n self.walkRowSamples = samples\n },\n setWalkRowGroupBy(groupBy: WalkRowGroupBy | undefined) {\n self.walkRowGroupBy = groupBy\n },\n setWalkRowSampleTable(table: SampleRow[] | undefined) {\n self.walkRowSampleTable = table\n },\n // Pair with a linear view for the hover sync, without ever repointing an\n // existing pairing: a graph launched *from* an LGV is already paired with\n // it, and stealing that would break the sync the user came in on. So a\n // launch out of the graph only claims the slot when it is empty.\n //\n // A slot naming a view that has been closed is empty too. Held, the view\n // the graph opened next never got its hover, since a highlight is drawn\n // only in the paired view.\n pairWithLinearView(viewId: string) {\n const paired = self.connectedViewId\n const stillOpen =\n paired !== undefined &&\n withRows([...getSession(self).views]).some(\n view => (view as { id?: unknown }).id === paired,\n )\n if (!stillOpen) {\n self.connectedViewId = viewId\n }\n },\n setHoveredNode(nodeId: string | null) {\n self.hoveredNode = nodeId\n },\n setHoveredRowWalks(walks: string[]) {\n if (walks.join('\\n') !== self.hoveredRowWalks.join('\\n')) {\n self.hoveredRowWalks = walks\n }\n },\n setHoveredWalkRow(name: string | null) {\n self.hoveredWalkRow = name\n },\n setHoveredBubble(bubble: MinigraphBubble | null) {\n self.hoveredBubble = bubble\n },\n setPointerInPane(inside: boolean) {\n self.pointerInPane = inside\n },\n setWalkStrip(show: boolean) {\n self.walkStrip = show\n self.stripHover = null\n },\n // The pointer over the strip: the node under it becomes the hovered\n // node, so the drawing, the tooltip and a linked linear view follow\n setStripHover(hover: { row: string; offset: number } | null) {\n self.stripHover = hover\n const bars = self.walkStripRows\n const frame = self.walkStripFrame\n const row =\n hover && bars\n ? [bars.reference, ...bars.rows].find(r => r.name === hover.row)\n : undefined\n const node =\n row && frame && self.graph\n ? segmentAt(self.graph, row, hover!.offset, frame.scaleX)\n : undefined\n self.hoveredNode = node ?? null\n },\n setLegendSize(size: { width: number; height: number }) {\n self.legendSize = size\n },\n setHoveredEdge(edgeIdx: number | null) {\n self.hoveredEdge = edgeIdx\n },\n setSelectedNode(nodeId: string | null) {\n self.selectedNode = nodeId\n },\n setDraggingNode(nodeId: string | null) {\n self.draggingNode = nodeId\n },\n setPanning(panning: boolean) {\n self.isPanning = panning\n },\n stopDragging() {\n self.draggingNode = null\n self.isPanning = false\n },\n // Everything that names a part of the current graph. Reset when the graph\n // is replaced, and by clearGraph.\n clearInteractionState() {\n self.hoveredNode = null\n self.hoveredWalkRow = null\n self.hoveredBubble = null\n self.hoveredEdge = null\n self.selectedNode = null\n self.draggingNode = null\n self.isPanning = false\n },\n showNodeDetails(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n const nodeById = self.nodeById\n const neighbors = self.nodeNeighbors\n if (node && nodeById && neighbors) {\n const session = getSession(self)\n const region = self.graphRegion\n // refName/start/end are what makes the widget show a location rather\n // than a bare id, and they are the same span the linear view\n // highlights on hover.\n const span = region\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n if (isSessionModelWithWidgets(session)) {\n session.showWidget(\n session.addWidget('BaseFeatureWidget', 'baseFeature', {\n featureData: {\n id: node.id,\n name: node.name,\n length: node.length,\n depth: node.depth,\n rank: node.stable?.rank,\n stableName: node.stable?.refName,\n // The assembly that contributed this segment, split off the\n // stable name. On an HPRC graph this is the only thing that\n // says which of 400-odd haplotypes an allele came from.\n contributingAssembly: nodeOwnLocation(node)?.sample,\n // and the haplotype, where the graph's names state one:\n // the assembly to load to open this node on its own\n // coordinates\n contributingHaplotype: nodeOwnLocation(node)?.haplotype,\n // Every haplotype whose path visits it, which only a path\n // GFA records. Absent on an rGFA, where\n // `contributingAssembly` is the first-seen assembly alone.\n sampleCount: node.samples?.length,\n samples: node.samples,\n ...(region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n start: span.start,\n end: span.end,\n }\n : {}),\n },\n }),\n )\n }\n }\n },\n\n // A gesture on a hosted graph moves the linear view, and the frame\n // clock brings x back here; y stays the pane's own.\n setTransform(s: number, tx: number, ty: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.horizontalScroll(self.translateX - tx)\n } else {\n self.viewportOwner = 'user'\n self.scale = clampZoom(s)\n self.translateX = tx\n }\n self.translateY = ty\n },\n zoom(factor: number, centerX: number, centerY: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.zoomTo(host.bpPerPx / factor, centerX)\n return\n }\n self.viewportOwner = 'user'\n const t = zoomAbout(self, factor, centerX, centerY, self.pixelRows)\n self.scale = t.scale\n self.translateX = t.translateX\n self.translateY = t.translateY\n },\n setViewportDirty() {\n self.viewportRebuildPending = false\n self.viewportDirty++\n },\n // The positions themselves moved, as opposed to the window onto them.\n setPositionsDirty() {\n self.positionsVersion++\n },\n zoomToFit() {\n // A host owns x, so a fit while hosted places the rows only.\n if (self.viewportOwner === 'host') {\n const bounds = self.layoutBounds\n const faceted = self.facetGrid !== undefined\n const pad = faceted ? FACET_PAD_PX : FIT_PADDING\n const padTop = faceted ? FACET_PAD_PX : self.fitPadTop\n const usableHeight = self.viewBox.height - padTop - pad\n if (bounds && usableHeight > 0) {\n self.translateY = fittedTranslateY(\n bounds,\n usableHeight,\n self.scaleY,\n padTop,\n )\n }\n return\n }\n // Nothing to fit into before the canvas is measured. The fit autorun\n // runs again once width lands, so skipping beats persisting a negative\n // scale into the session snapshot.\n const fit = self.fittedTransform\n if (fit) {\n self.scale = fit.scale\n self.translateX = fit.translateX\n self.translateY = fit.translateY\n }\n },\n clearPerfMetrics() {\n self.lastFetchMs = undefined\n self.lastLayoutMs = undefined\n self.lastGeometryMs = undefined\n self.lastGeometryStrokeCount = undefined\n self.builtViewport = undefined\n },\n }))\n .actions(self => ({\n // The frame clock. Unclamped, since clampZoom's floor is there to keep a\n // scale finite and 1 / bpPerPx already is; clamped, a whole-chromosome\n // window would stop lining up.\n hostTransform(scale: number, translateX: number) {\n const engaging = self.viewportOwner !== 'host'\n if (engaging) {\n self.viewportOwner = 'host'\n }\n self.scale = scale\n self.translateX = translateX\n if (engaging) {\n self.zoomToFit()\n }\n },\n // Faceting changes the box the drawing is fitted into, so a drawing the\n // user placed is fitted again; a host keeps its x\n refitView() {\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n self.zoomToFit()\n },\n // A drawing still on the reference stays where the host left it; one\n // whose x no longer means bp is refit.\n releaseHost() {\n if (self.viewportOwner === 'host') {\n if (self.xIsReferenceBp) {\n self.viewportOwner = 'user'\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n }\n },\n }))\n .actions(self => {\n // Pan/zoom can wait: the geometry on screen is still correct while the\n // gesture runs (the viewport bounds carry 20% overscan), so rebuilding is\n // deferred until the user settles.\n function scheduleViewportDirty() {\n clearTimeout(self.viewportDirtyTimer)\n self.viewportRebuildPending = true\n self.viewportDirtyTimer = setTimeout(() => {\n if (isAlive(self)) {\n self.setViewportDirty()\n }\n }, VIEWPORT_DEBOUNCE_MS)\n }\n\n // A node drag cannot wait \u2014 the node only moves on screen when its\n // geometry is rebuilt \u2014 but a bump costs a full geometry rebuild plus\n // invalidation of both hit-detection indexes, and mousemove fires in\n // bursts well above the frame rate. Coalescing to the next frame keeps the\n // drag live while bounding that work to once per frame instead of once\n // per event.\n function requestPositionsDirtyFrame() {\n cancelAnimationFrame(self.positionsDirtyFrame)\n self.positionsDirtyFrame = requestAnimationFrame(() => {\n if (isAlive(self)) {\n self.setPositionsDirty()\n }\n })\n }\n\n return {\n // Moves the position objects IN PLACE, which is the one thing\n // jbrowse-components' upload invariant says not to do (\"per-region\n // upload values must be freshly constructed, never mutated \u2014 backends\n // diff by reference identity\"), so it is worth saying why this is not\n // that case and what it costs instead.\n //\n // Nothing here diffs by identity: the geometry is rebuilt wholesale and\n // handed over as one batch, so `nodePositions` identity is not a\n // protocol between the model and the backend the way a per-region map\n // is. What identity DOES drive is the fit: the zoom-to-fit autorun and\n // `layoutBounds` \u2014 and so `canvasHeight` \u2014 key off `layoutResult`, and\n // they mean \"a new LAYOUT arrived\", not \"a node moved\". Publishing a\n // fresh positions record per frame of a drag would refit the drawing\n // and resize the pane under the cursor, sixty times a second.\n //\n // So the change is announced by `positionsVersion` instead, and every\n // cache that would otherwise trust identity takes it as a key. The cost\n // of that trade is that the version is a thing to remember: a caller\n // that mutates here and does not bump it gets stale curves, stale hit\n // boxes and stale labels, silently. Everything downstream of it is\n // reached from this one action.\n moveNode(nodeId: string, dx: number, dy: number) {\n const positions = self.layoutResult?.nodePositions\n if (positions?.[nodeId]) {\n for (const seg of positions[nodeId]) {\n seg.x += dx\n seg.y += dy\n }\n requestPositionsDirtyFrame()\n }\n },\n scheduleViewportDirty,\n }\n })\n", "// src/renderer/geometryInputs.ts\nfunction layoutGeometryInputs(layout, drawing, o = {}) {\n return {\n nodePositions: o.drawsRows ? {} : layout.nodePositions,\n deletions: drawing.bypassed,\n deletionRoutes: layout.deletionRoutes,\n stranded: layout.stranded,\n hiddenEdges: drawing.hidden\n };\n}\n\nexport {\n layoutGeometryInputs\n};\n", "// src/renderer/svgCanvas.ts\nvar n = (v) => +v.toFixed(1);\nfunction paint(css) {\n const m = /^rgba?\\(([^,]+),([^,]+),([^,)]+)(?:,([^)]+))?\\)$/.exec(\n css.replaceAll(\" \", \"\")\n );\n if (!m) {\n return { color: css, opacity: 1 };\n }\n const opacity = m[4] === void 0 ? 1 : Number(m[4]);\n return { color: `rgb(${m[1]},${m[2]},${m[3]})`, opacity };\n}\nfunction paintAttrs(kind, css) {\n const { color, opacity } = paint(css);\n return `${kind}=\"${color}\"${opacity < 1 ? ` ${kind}-opacity=\"${n(opacity)}\"` : \"\"}`;\n}\nvar DOT_PX = 0.5;\nvar DOT_CELL_PX = 0.25;\nfunction svgCanvas(width, height) {\n const out = [];\n let subpaths = [];\n const start = (x, y) => {\n const s = { d: `M${n(x)} ${n(y)}`, segments: 0, x0: x, x1: x, y0: y, y1: y };\n subpaths.push(s);\n return s;\n };\n const reach = (points) => {\n const s = subpaths.at(-1) ?? start(points[0], points[1]);\n for (let i = 0; i < points.length; i += 2) {\n s.x0 = Math.min(s.x0, points[i]);\n s.x1 = Math.max(s.x1, points[i]);\n s.y0 = Math.min(s.y0, points[i + 1]);\n s.y1 = Math.max(s.y1, points[i + 1]);\n }\n s.segments++;\n return s;\n };\n const pathData = (dots) => {\n const seen = /* @__PURE__ */ new Set();\n return subpaths.map((s) => {\n if (!dots || s.x1 - s.x0 >= DOT_PX || s.y1 - s.y0 >= DOT_PX) {\n return s.d;\n }\n const x = (s.x0 + s.x1) / 2;\n const y = (s.y0 + s.y1) / 2;\n const cell = `${Math.round(x / DOT_CELL_PX)} ${Math.round(y / DOT_CELL_PX)}`;\n if (s.segments === 0 || seen.has(cell)) {\n return \"\";\n }\n seen.add(cell);\n return `M${n(x)} ${n(y)}h0`;\n }).join(\"\");\n };\n const ctx = {\n canvas: void 0,\n fillStyle: \"#000\",\n strokeStyle: \"#000\",\n lineWidth: 1,\n lineCap: \"butt\",\n lineJoin: \"miter\",\n beginPath() {\n subpaths = [];\n },\n moveTo(x, y) {\n start(x, y);\n },\n lineTo(x, y) {\n reach([x, y]).d += `L${n(x)} ${n(y)}`;\n },\n bezierCurveTo(cx0, cy0, cx1, cy1, x, y) {\n reach([cx0, cy0, cx1, cy1, x, y]).d += `C${n(cx0)} ${n(cy0)} ${n(cx1)} ${n(cy1)} ${n(x)} ${n(y)}`;\n },\n closePath() {\n const s = subpaths.at(-1);\n if (s) {\n s.d += \"Z\";\n }\n },\n stroke() {\n const d = pathData(ctx.lineCap !== \"butt\");\n if (d) {\n out.push(\n `<path d=\"${d}\" fill=\"none\" ${paintAttrs(\"stroke\", ctx.strokeStyle)} stroke-width=\"${n(ctx.lineWidth)}\" stroke-linecap=\"${ctx.lineCap}\" stroke-linejoin=\"${ctx.lineJoin}\"/>`\n );\n }\n },\n fill() {\n const d = pathData(false);\n if (d) {\n out.push(`<path d=\"${d}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`);\n }\n },\n fillRect(x, y, w, h) {\n out.push(\n `<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`\n );\n }\n };\n const canvas = {\n width,\n height,\n style: {},\n getContext: () => ctx\n };\n ctx.canvas = canvas;\n return {\n canvas,\n // the drawing so far, as SVG elements in canvas pixels\n markup: () => out.join(\"\")\n };\n}\n\nexport {\n svgCanvas\n};\n", "import {\n polylineSlice\n} from \"./chunk-TAMCZHLW.js\";\nimport {\n svgPath\n} from \"./chunk-2CVHXFK7.js\";\nimport {\n firstNodeAtOrAfter,\n isAnchored\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/genes/genePins.ts\nfunction genePins(graph, genes, positions) {\n const byRefName = /* @__PURE__ */ new Map();\n for (const node of graph.nodes) {\n if (isAnchored(node)) {\n const { refName } = node.stable;\n if (positions[node.id]?.length) {\n const entry = byRefName.get(refName) ?? byRefName.set(refName, { nodes: [], reach: 0 }).get(refName);\n entry.nodes.push(node);\n entry.reach = Math.max(entry.reach, node.length);\n }\n }\n }\n for (const { nodes } of byRefName.values()) {\n nodes.sort((a, b) => a.stable.start - b.stable.start);\n }\n const pins = [];\n for (const gene of genes) {\n const onRefName = byRefName.get(gene.refName);\n if (!onRefName) {\n continue;\n }\n const parts = [];\n const exonsByNode = [];\n const nodeIds = /* @__PURE__ */ new Set();\n let at;\n let atDistance = Infinity;\n let covered = 0;\n const mid = (gene.start + gene.end) / 2;\n const { nodes, reach } = onRefName;\n for (let i = firstNodeAtOrAfter(nodes, gene.start - reach); i < nodes.length && nodes[i].stable.start < gene.end; i++) {\n const node = nodes[i];\n const nodeStart = node.stable.start;\n const nodeEnd = nodeStart + node.length;\n if (nodeEnd <= gene.start) {\n continue;\n }\n const line = positions[node.id];\n nodeIds.add(node.id);\n covered += Math.min(nodeEnd, gene.end) - Math.max(nodeStart, gene.start);\n const nodeParts = [];\n for (const exon of gene.exons) {\n const a = Math.max(exon.start, nodeStart);\n const b = Math.min(exon.end, nodeEnd);\n if (b <= a) {\n continue;\n }\n const stretch = polylineSlice(\n line,\n (a - nodeStart) / node.length,\n (b - nodeStart) / node.length\n );\n if (stretch.length === 1) {\n stretch.push({ ...stretch[0] });\n }\n nodeParts.push(svgPath(stretch));\n }\n if (nodeParts.length > 0) {\n parts.push(...nodeParts);\n exonsByNode.push({ nodeId: node.id, d: nodeParts.join(\"\") });\n }\n const pinBp = Math.min(Math.max(mid, nodeStart), nodeEnd);\n const distance = Math.abs(pinBp - mid);\n if (distance < atDistance) {\n atDistance = distance;\n const [p] = polylineSlice(\n line,\n (pinBp - nodeStart) / node.length,\n (pinBp - nodeStart) / node.length\n );\n at = p;\n }\n }\n if (at) {\n pins.push({\n gene,\n exons: parts.join(\"\"),\n exonsByNode,\n nodeIds,\n at,\n covered: covered / (gene.end - gene.start)\n });\n }\n }\n return pins;\n}\n\nexport {\n genePins\n};\n", "import {\n encodedColor,\n resolveEncoding\n} from \"./chunk-ZNMHIPUZ.js\";\nimport {\n pathOrigin\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n panSNContig\n} from \"./chunk-BPLIXMH7.js\";\n\n// src/walkHighlight.ts\nvar isReference = (graph, name) => !!graph.referencePath && pathOrigin(name).name === graph.referencePath;\nfunction piecesOf(graph, name) {\n return (graph.paths ?? []).filter((p) => p.name === name).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));\n}\nfunction walkHighlight(graph, name) {\n const pieces = piecesOf(graph, name);\n const first = pieces[0];\n if (!first) {\n return void 0;\n }\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const edgeAt = /* @__PURE__ */ new Map();\n graph.edges.forEach((e, i) => {\n edgeAt.set(`${e.from}>${e.to}`, i);\n });\n const lengthOf = (id) => byId.get(id)?.length ?? 0;\n const bpOf = (path) => path.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0);\n const bp = pieces.reduce((sum, piece) => sum + bpOf(piece), 0);\n const range = first.start === void 0 ? void 0 : {\n contig: first.contig ?? panSNContig(pathOrigin(name).name),\n start: first.start,\n end: Math.max(...pieces.map((p) => (p.start ?? 0) + bpOf(p)))\n };\n const span = range ? range.end - range.start : bp;\n const nodeIds = /* @__PURE__ */ new Set();\n const edgeIndexes = /* @__PURE__ */ new Set();\n const progress = /* @__PURE__ */ new Map();\n let before = 0;\n for (const piece of pieces) {\n if (range) {\n before = Math.max(before, (piece.start ?? 0) - range.start);\n }\n piece.nodeIds.forEach((id, i) => {\n nodeIds.add(id);\n if (i > 0) {\n const a = piece.nodeIds[i - 1];\n const index = edgeAt.get(`${a}>${id}`) ?? edgeAt.get(`${id}>${a}`);\n if (index !== void 0) {\n edgeIndexes.add(index);\n }\n }\n const length = lengthOf(id);\n if (!progress.has(id)) {\n progress.set(id, span > 0 ? (before + length / 2) / span : 0);\n }\n before += length;\n });\n }\n const reference = isReference(graph, name);\n const referencePieces = reference ? [] : (graph.paths ?? []).filter((p) => isReference(graph, p.name));\n return {\n name,\n reference,\n range,\n nodeIds,\n edgeIndexes,\n progress,\n steps: pieces.reduce((sum, piece) => sum + piece.nodeIds.length, 0),\n bp,\n referenceBp: referencePieces.length > 0 ? referencePieces.reduce((sum, piece) => sum + bpOf(piece), 0) : void 0\n };\n}\nfunction laneColors(graph, walk, encoding, ramp) {\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const colors = /* @__PURE__ */ new Map();\n for (const [id, progress] of walk.progress) {\n const node = byId.get(id);\n const mid = ramp?.midpoints.get(id);\n const t = encoding.field === \"progress\" ? progress : ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;\n colors.set(id, encodedColor(encoding, t));\n }\n return colors;\n}\nfunction reversedNodes(graph, walk) {\n const reversed = /* @__PURE__ */ new Set();\n let bp = 0;\n const referencePath = graph.referencePath;\n if (!referencePath || walk.reference) {\n return { reversed, bp };\n }\n const walkPath = pathOrigin(walk.name).name;\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n for (const id of walk.progress.keys()) {\n const node = byId.get(id);\n const visits = node ? graph.pathVisits?.get(node.name) : void 0;\n const own = visits?.find((v) => v.path === walkPath)?.strand;\n const theirs = visits?.find((v) => v.path === referencePath)?.strand;\n if (own && theirs && own !== theirs) {\n reversed.add(id);\n bp += node.length;\n }\n }\n return { reversed, bp };\n}\nfunction walkLift(graph, layers, ramp) {\n const seen = /* @__PURE__ */ new Set();\n const lifted = layers.filter((layer) => !seen.has(layer.walk) && seen.add(layer.walk)).flatMap((layer) => {\n const walk = walkHighlight(graph, layer.walk);\n return walk ? [{ walk, layer }] : [];\n }).sort((a, b) => Number(b.walk.reference) - Number(a.walk.reference));\n if (lifted.length === 0) {\n return void 0;\n }\n let picked = 0;\n const walks = lifted.map(({ walk, layer }) => {\n const encoding = resolveEncoding(\n layer,\n walk.reference,\n walk.reference ? 0 : picked++,\n lifted.length === 1\n );\n const { reversed, bp } = reversedNodes(graph, walk);\n return {\n ...walk,\n encoding,\n colors: laneColors(graph, walk, encoding, ramp),\n reversed,\n reversedBp: bp\n };\n });\n return liftOf(walks, ramp);\n}\nvar FACET_COLOR = { field: \"progress\", scheme: \"red\" };\nfunction facetLifts(graph, lift, layers, ramp) {\n return lift.walks.map((walk) => {\n const stated = layers.find((l) => l.walk === walk.name)?.color;\n const encoding = resolveEncoding(\n { walk: walk.name, color: { ...FACET_COLOR, ...stated } },\n walk.reference,\n 0\n );\n return liftOf(\n [\n {\n ...walk,\n encoding,\n colors: laneColors(graph, walk, encoding, ramp)\n }\n ],\n ramp\n );\n });\n}\nfunction liftOf(walks, ramp) {\n return {\n walks,\n referenceDomain: ramp ? { start: ramp.start, end: ramp.start + ramp.span } : void 0,\n nodeIds: new Set(walks.flatMap((w) => [...w.nodeIds])),\n edgeIndexes: new Set(walks.flatMap((w) => [...w.edgeIndexes])),\n names: new Set(walks.map((w) => w.name))\n };\n}\n\nexport {\n walkHighlight,\n walkLift,\n facetLifts\n};\n", "// src/version.ts\nvar version = \"7.5.1\";\n\nexport {\n version\n};\n", "import {\n layoutGeometryInputs\n} from \"./chunk-LOCJN3BZ.js\";\nimport {\n svgCanvas\n} from \"./chunk-47DYCZOK.js\";\nimport {\n stripGeneGaps,\n walkStripFrame,\n walkStripLabelsTree\n} from \"./chunk-ZYHSUNQO.js\";\nimport {\n walkRowsKey,\n walkRowsKeyTree,\n walkRowsTree\n} from \"./chunk-7G7TFATC.js\";\nimport {\n Canvas2DRenderer\n} from \"./chunk-CH3DLBUT.js\";\nimport {\n EXON_COLOR,\n exonOutlineTree,\n exonStretches\n} from \"./chunk-3S3YVOJ7.js\";\nimport {\n genePins\n} from \"./chunk-BUBZ32IC.js\";\nimport {\n facetLifts,\n walkLift\n} from \"./chunk-3LXG54PN.js\";\nimport {\n encodingStops\n} from \"./chunk-ZNMHIPUZ.js\";\nimport {\n rangeText,\n walkKey\n} from \"./chunk-2LQ5BWT7.js\";\nimport {\n buildGeometry,\n computeReferenceRamp\n} from \"./chunk-RCWYY6XA.js\";\nimport {\n version\n} from \"./chunk-CNGKWYUC.js\";\nimport {\n axisScaleOf\n} from \"./chunk-4UBWXZVX.js\";\nimport {\n walkRowLabels,\n walkRowsExtent\n} from \"./chunk-MP7LXLWV.js\";\nimport {\n nodeInk\n} from \"./chunk-PBENCR5L.js\";\nimport {\n pathLegend,\n walkLabelsOf\n} from \"./chunk-7GBL7SJY.js\";\nimport {\n referenceLabel\n} from \"./chunk-RAKOB6IV.js\";\nimport {\n geneLabelCandidates\n} from \"./chunk-GJMC3PGM.js\";\nimport {\n nodesUnderBox\n} from \"./chunk-FP4H7SFT.js\";\nimport {\n LABEL_CHAR_PX,\n LABEL_PAD,\n LABEL_PX,\n occupancy,\n placeLabels\n} from \"./chunk-AB35TJST.js\";\nimport {\n resolveColorScheme\n} from \"./chunk-JKJWSY4V.js\";\nimport {\n serializeEl\n} from \"./chunk-NNODIW4U.js\";\nimport {\n FACET_GAP_PX,\n FACET_PAD_PX,\n FACET_TITLE_PX,\n facetCells,\n facetGrid,\n facetSettingOf\n} from \"./chunk-XV4P5KEQ.js\";\nimport {\n FIT_PADDING,\n drawingBounds,\n fitTransform\n} from \"./chunk-WZATPZNH.js\";\nimport {\n deletionDrawing,\n deletionEdges\n} from \"./chunk-N6FECAXP.js\";\n\n// src/figure.ts\nvar FONT = 'font-family=\"Helvetica, Arial, sans-serif\" font-size=\"11\"';\nvar BAR_PX = 48;\nvar SWATCH_PX = 18;\nvar KEY_GAP_PX = 16;\nvar STRIP_KEY_PX = 22;\nvar FADED = \"rgb(160,160,160)\";\nvar GENE_INK = \"#1c1c22\";\nfunction esc(s) {\n return s.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\");\n}\nfunction keySvg(id, x, y, stops, label, after, under, opacity = 1) {\n const bar = stops.length > 1 ? BAR_PX : SWATCH_PX;\n const fill = stops.length > 1 ? `fill=\"url(#${id})\"` : `fill=\"${stops[0].color}\"${opacity < 1 ? ` fill-opacity=\"${opacity}\"` : \"\"}`;\n const defs = stops.length > 1 ? `<linearGradient id=\"${id}\">${stops.map((s) => `<stop offset=\"${s.offset}\" stop-color=\"${s.color}\"/>`).join(\"\")}</linearGradient>` : \"\";\n const width = Math.max(\n bar + 5 + (label.length + after.length) * LABEL_CHAR_PX,\n (under?.length ?? 0) * LABEL_CHAR_PX\n );\n return {\n width,\n markup: `${defs}<g transform=\"translate(${x} ${y})\" ${FONT}><rect y=\"5\" width=\"${bar}\" height=\"8\" rx=\"2\" ${fill}/><text x=\"${bar + 5}\" y=\"13\"><tspan font-weight=\"bold\">${esc(label)}</tspan>${esc(after)}</text>${under ? `<text y=\"28\">${esc(under)}</text>` : \"\"}</g>`\n };\n}\nfunction exonKeySvg(x, y) {\n return {\n width: SWATCH_PX + 5 + 4 * LABEL_CHAR_PX,\n markup: `<g transform=\"translate(${x} ${y})\" ${FONT}><rect x=\"1\" y=\"4\" width=\"${SWATCH_PX - 2}\" height=\"10\" rx=\"4\" fill=\"none\" stroke=\"${EXON_COLOR}\" stroke-width=\"2\"/><text x=\"${SWATCH_PX + 5}\" y=\"13\">exon</text></g>`\n };\n}\nfunction walkKeySvg(id, x, y, walk, label, reference) {\n const key = walkKey(walk, reference);\n return keySvg(\n id,\n x,\n y,\n encodingStops(walk.encoding),\n label,\n key.delta + key.outside + key.reversed,\n key.scale\n );\n}\nfunction screenPath(d, t) {\n return d.replaceAll(\n /([ML])(-?[\\d.e-]+),(-?[\\d.e-]+)/g,\n (_, cmd, x, y) => `${cmd}${+(Number(x) * t.scaleX + t.translateX).toFixed(1)},${+(Number(y) * t.scaleY + t.translateY).toFixed(1)}`\n );\n}\nfunction chip(x, y, w, name, note) {\n return `<rect x=\"${x - w / 2}\" y=\"${y - LABEL_PX - LABEL_PAD + 2}\" width=\"${w}\" height=\"${LABEL_PX + LABEL_PAD * 2 - 2}\" rx=\"3\" fill=\"#fff\" fill-opacity=\"0.85\" stroke=\"${EXON_COLOR}\"/><text x=\"${x}\" y=\"${y}\" font-family=\"Helvetica, Arial, sans-serif\" font-size=\"${LABEL_PX}\" fill=\"${GENE_INK}\" text-anchor=\"middle\"><tspan font-style=\"italic\" font-weight=\"600\">${esc(name)}</tspan>${note ? esc(note) : \"\"}</text>`;\n}\nfunction figureSvg(graph, layout, o = {}) {\n const width = o.width ?? 1200;\n const room = o.height ?? 800;\n const region = o.region;\n const rampDomain = o.colorDomain ?? region;\n const rows = o.walkRows;\n const bounds = drawingBounds(layout, {\n region: o.fitToDrawing ? void 0 : region,\n extent: rows && layout.extent ? walkRowsExtent(rows, o.walkRowPitch) : void 0\n });\n const pixelRows = layout.pixelRows ?? false;\n const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));\n const colorScheme = resolveColorScheme(o.colorScheme ?? \"auto\", graph);\n const referenceRamp = colorScheme === \"reference-position\" && !layout.tubeMap ? computeReferenceRamp(graph, rampDomain) : void 0;\n const rampInterval = referenceRamp && {\n start: referenceRamp.start,\n end: referenceRamp.start + referenceRamp.span\n };\n const drawnDeletions = deletionDrawing(\n graph,\n layout.tubeMap ? [] : deletionEdges(graph),\n o.showDeletionEdges\n );\n const layers = o.walks ?? [];\n const walkRamp = layers.some((l) => l.color?.field === \"reference\") ? referenceRamp ?? computeReferenceRamp(graph, rampDomain) : void 0;\n const lift = layers.length > 0 && !layout.tubeMap ? walkLift(graph, layers, walkRamp) : void 0;\n const facet = facetSettingOf(o.facet);\n const panels = facet.field && lift && lift.walks.length > 1 ? facetLifts(graph, lift, layers, walkRamp) : void 0;\n const labels = walkLabelsOf(\n graph.paths?.length ? pathLegend(graph.paths) : []\n );\n const labelOf = (name) => labels.get(name) ?? name;\n const referenceName = o.referenceName ?? referenceLabel(graph, region);\n const reference = lift?.referenceDomain && {\n ...lift.referenceDomain,\n name: referenceName\n };\n const contigThickness = o.contigThickness ?? 6;\n const nodeWidth = o.nodeWidth ?? \"depth\";\n const pins = o.genes?.length && !layout.tubeMap && !rows ? genePins(graph, o.genes, layout.nodePositions) : [];\n const ink = nodeInk(graph, nodeById, contigThickness, nodeWidth);\n let masks = 0;\n function overlays(highlight, t, w, h) {\n const out = [];\n const outlines = exonOutlineTree(\n exonStretches(pins, ink.halfWidthPx, highlight, (d) => screenPath(d, t)),\n { id: `exons${masks++}`, width: w, height: h }\n );\n if (outlines) {\n out.push(serializeEl(outlines));\n }\n const screen = (p) => ({\n x: p.x * t.scaleX + t.translateX,\n y: p.y * t.scaleY + t.translateY\n });\n const frame = { width: w, height: h };\n for (const { item: pin, x, y, w: cw, text } of placeLabels(\n geneLabelCandidates(\n pins,\n screen,\n contigThickness,\n nodesUnderBox(layout.nodePositions, t)\n ),\n frame,\n occupancy(frame)\n )) {\n const pinY = screen(pin.at).y + contigThickness / 2;\n out.push(\n `<line x1=\"${x}\" x2=\"${x}\" y1=\"${y - LABEL_PX - 2}\" y2=\"${pinY}\" stroke=\"${GENE_INK}\" stroke-width=\"0.8\" stroke-opacity=\"0.6\"/>`,\n chip(x, y, cw, pin.gene.name, text.slice(pin.gene.name.length))\n );\n }\n if (rows) {\n out.push(\n serializeEl(\n walkRowsTree(\n rows,\n { ...t, width: w, height: h, ...o.walkRowPitch },\n {\n ramp: rampInterval,\n rowGenes: o.rowGenes\n }\n )\n )\n );\n }\n const rowLabels = walkRowLabels(rows, layout, o.walkRowPitch);\n for (const { label, y } of rowLabels) {\n const sy = y * t.scaleY + t.translateY;\n if (sy >= 0 && sy <= h) {\n out.push(\n `<text x=\"6\" y=\"${sy + 4}\" ${FONT} stroke=\"#fff\" stroke-width=\"3\" paint-order=\"stroke\">${esc(label)}</text>`\n );\n }\n }\n return out.join(\"\");\n }\n function drawing(highlight, w, h) {\n const fit = fitTransform(\n bounds,\n w,\n h,\n pixelRows,\n panels ? {\n padLeft: FACET_PAD_PX,\n padTop: FACET_PAD_PX,\n padRight: FACET_PAD_PX,\n padBottom: FACET_PAD_PX\n } : {}\n );\n if (!fit) {\n return \"\";\n }\n const axis = axisScaleOf(fit.scale, pixelRows);\n const { canvas, markup } = svgCanvas(w, h);\n const renderer = new Canvas2DRenderer(canvas);\n renderer.uploadGeometry(\n buildGeometry({\n ...layoutGeometryInputs(layout, drawnDeletions, {\n drawsRows: !!rows\n }),\n graph,\n nodeById,\n colorScheme,\n contigThickness,\n connectorThickness: o.connectorThickness ?? 2,\n drawPaths: false,\n nodeWidth,\n linearLayout: o.linearLayout,\n highlight,\n axis,\n referenceRamp\n })\n );\n const t = {\n scaleX: axis.scaleX,\n scaleY: axis.scaleY,\n translateX: fit.translateX,\n translateY: fit.translateY\n };\n renderer.updateTransform({ ...t, dpr: 1 });\n renderer.render([1, 1, 1, 1]);\n return markup() + overlays(highlight, t, w, h);\n }\n const parts = [];\n let height;\n if (panels) {\n const place = facetCells(\n panels.map((p) => p.walks[0].name),\n facet.field || \"walk\",\n facet.domain\n );\n const grid = facetGrid({\n count: place.count,\n bounds,\n pixelRows,\n width,\n room,\n columns: place.columns ?? facet.columns\n });\n panels.forEach((panel, i) => {\n const cell = place.cells[i];\n const x = cell % grid.columns * (grid.width + FACET_GAP_PX);\n const y = Math.floor(cell / grid.columns) * (grid.height + FACET_TITLE_PX + FACET_GAP_PX);\n const walk = panel.walks[0];\n parts.push(\n walkKeySvg(`key${i}`, x + 6, y + 2, walk, labelOf(walk.name), reference).markup,\n `<svg x=\"${x}\" y=\"${y + FACET_TITLE_PX}\" width=\"${grid.width}\" height=\"${grid.height}\">${drawing(panel, grid.width, grid.height)}</svg>`\n );\n });\n height = grid.total;\n } else {\n let x = 6;\n const push = (key) => {\n parts.push(key.markup);\n x += key.width + KEY_GAP_PX;\n };\n if (lift) {\n lift.walks.forEach((walk, i) => {\n push(walkKeySvg(`key${i}`, x, 2, walk, labelOf(walk.name), reference));\n });\n push(\n keySvg(\n \"faded\",\n x,\n 2,\n [{ offset: 0, color: FADED }],\n \"\",\n `not on ${lift.walks.length === 1 ? labelOf(lift.walks[0].name) : \"these walks\"}`,\n void 0,\n 0.3\n )\n );\n }\n if (rows) {\n const key = walkRowsKeyTree(\n walkRowsKey(rows, {\n ramp: rampInterval,\n genes: o.rowGenes?.size ? o.rowGeneGaps : void 0\n }),\n x,\n 2,\n \"rows-key\"\n );\n push({ width: key.width, markup: serializeEl(key.tree) });\n } else if (!lift && referenceRamp) {\n push(\n keySvg(\n \"ramp\",\n x,\n 2,\n encodingStops({ field: \"reference\", scheme: \"rainbow\" }),\n referenceName ? `${referenceName} position` : \"Reference position\",\n \"\",\n rangeText(\n referenceName,\n referenceRamp.start,\n referenceRamp.start + referenceRamp.span\n )\n )\n );\n }\n if (pins.some((pin) => pin.exonsByNode.length > 0)) {\n push(exonKeySvg(x, 2));\n }\n const header = parts.length > 0 ? FACET_TITLE_PX : 0;\n const usable = width - 2 * FIT_PADDING;\n const drawn = pixelRows || !(bounds.w > 0) ? bounds.h : bounds.h * usable / bounds.w;\n const h = Math.max(\n 160,\n Math.min(room - header, Math.ceil(drawn + 2 * FIT_PADDING))\n );\n parts.push(\n `<svg y=\"${header}\" width=\"${width}\" height=\"${h}\">${drawing(lift, width, h)}</svg>`\n );\n height = header + h;\n }\n const strip = o.walkStrip;\n if (strip && !rows && !layout.tubeMap) {\n const frame = walkStripFrame(strip.rows, { width });\n const key = walkRowsKeyTree(\n walkRowsKey(strip.rows, {\n ramp: rampInterval,\n genes: stripGeneGaps(frame, strip.rowGenes, strip.rowGeneGaps)\n }),\n 6,\n height + frame.height,\n \"strip-key\"\n );\n parts.push(\n `<line x1=\"0\" x2=\"${width}\" y1=\"${height + 0.5}\" y2=\"${height + 0.5}\" stroke=\"#ddd\"/>`,\n `<svg y=\"${height}\" width=\"${width}\" height=\"${frame.height}\">${serializeEl(\n walkRowsTree(strip.rows, frame, {\n ramp: rampInterval,\n rowGenes: strip.rowGenes,\n idPrefix: \"strip\"\n })\n )}${serializeEl(\n walkStripLabelsTree(\n strip.rows,\n frame,\n new Set(layers.map((l) => l.walk))\n )\n )}</svg>`,\n serializeEl(key.tree)\n );\n height += frame.height + STRIP_KEY_PX;\n }\n const metadata = JSON.stringify({\n generator: `@jbrowse/bandage-core@${version}`,\n ...o.spec === void 0 ? {} : { spec: o.spec }\n });\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\"><metadata>${esc(metadata)}</metadata><rect width=\"${width}\" height=\"${height}\" fill=\"#fff\"/>${parts.join(\"\")}</svg>\n`;\n}\n\nexport {\n figureSvg\n};\n", "import {\n ENGINE_DEFAULTS\n} from \"./chunk-WZATPZNH.js\";\n\n// src/figureSettings.ts\nvar FIGURE_DEFAULTS = {\n ...ENGINE_DEFAULTS,\n colorScheme: \"auto\",\n nodeWidth: \"depth\",\n contigThickness: 6,\n connectorThickness: 2\n};\nfunction figureSpecSettings(s) {\n const defaults = FIGURE_DEFAULTS;\n const out = {};\n for (const [k, v] of Object.entries(s)) {\n if (v !== void 0 && v !== defaults[k]) {\n out[k] = v;\n }\n }\n return out;\n}\n\nexport {\n FIGURE_DEFAULTS,\n figureSpecSettings\n};\n", "// src/tubeMap/warp.ts\nvar MAX_GAP_PX = 24;\nvar isReal = (c) => c.bp1 > c.bp0;\nfunction referenceKnots(columns, bpToScreen) {\n const real = columns.filter(isReal);\n if (real.length === 0) {\n const first = columns[0];\n return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];\n }\n const screen = real.map((c) => ({\n c,\n s0: bpToScreen(c.bp0),\n s1: bpToScreen(c.bp1),\n trimLeft: 0,\n trimRight: 0\n }));\n for (let i = 0; i + 1 < screen.length; i++) {\n const left = screen[i];\n const right = screen[i + 1];\n const demand = Math.min(right.c.x0 - left.c.x1, MAX_GAP_PX);\n const short = demand - (right.s0 - left.s1);\n if (short > 0) {\n const capLeft = (left.s1 - left.s0) / 2;\n const capRight = (right.s1 - right.s0) / 2;\n let fromLeft = Math.min(short / 2, capLeft);\n const fromRight = Math.min(short - fromLeft, capRight);\n fromLeft = Math.min(short - fromRight, capLeft);\n left.trimRight = fromLeft;\n right.trimLeft = fromRight;\n }\n }\n const knots = [];\n for (const { c, s0, s1, trimLeft, trimRight } of screen) {\n knots.push(\n { tx: c.x0, sx: s0 + trimLeft },\n { tx: c.x1, sx: s1 - trimRight }\n );\n }\n return knots;\n}\nfunction warpX(knots, tx) {\n const n = knots.length;\n if (n === 0) {\n return tx;\n }\n const first = knots[0];\n const last = knots[n - 1];\n if (tx <= first.tx) {\n return first.sx + (tx - first.tx);\n }\n if (tx >= last.tx) {\n return last.sx + (tx - last.tx);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = lo + hi >> 1;\n if (knots[mid].tx <= tx) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n const a = knots[lo];\n const b = knots[hi];\n const span = b.tx - a.tx;\n return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;\n}\n\nexport {\n referenceKnots,\n warpX\n};\n", "import {\n referenceKnots,\n warpX\n} from \"./chunk-KQFOCDFY.js\";\n\n// src/tubeMap/frame.ts\nvar MIN_TUBE_Y_SCALE = 0.05;\nvar NODE_BOX_PAD = 9;\nfunction squeeze(drawing, usableHeight) {\n const { minY, maxY } = drawing.layout.bounds;\n const h = maxY - minY;\n return drawing.columns && h > 0 ? Math.max(MIN_TUBE_Y_SCALE, Math.min(1, usableHeight / h)) : 1;\n}\nfunction tubeMapFrame(drawing, view) {\n const { scaleX, translateX, translateY } = view;\n const yScale = view.scaleY * squeeze(drawing, view.usableHeight);\n const y = (ty) => (ty - drawing.yOffset) * yScale + translateY;\n const { columns } = drawing;\n if (columns) {\n const knots = referenceKnots(columns, (bp) => bp * scaleX + translateX);\n return { x: (tx) => warpX(knots, tx), y, yScale };\n }\n return { x: (tx) => tx * scaleX + translateX, y, yScale };\n}\nfunction tubeMapNodeAt(drawing, { x, y }, sx, sy) {\n let hit = null;\n drawing.layout.nodes.forEach((node) => {\n if (node.order >= 0 && x(node.x - NODE_BOX_PAD) <= sx && sx <= x(node.x + node.pixelWidth + NODE_BOX_PAD) && y(node.y - NODE_BOX_PAD) <= sy && sy <= y(node.y + node.contentHeight + NODE_BOX_PAD)) {\n hit = node.name;\n }\n });\n return hit;\n}\n\nexport {\n tubeMapFrame,\n tubeMapNodeAt\n};\n", "import {\n FACET_PAD_PX,\n facetCells,\n facetGrid,\n} from '@jbrowse/bandage-core/facetGrid'\nimport { figureSvg } from '@jbrowse/bandage-core/figure'\nimport { figureSpecSettings } from '@jbrowse/bandage-core/figureSettings'\nimport { rowLabelBox } from '@jbrowse/bandage-core/graphLabels'\nimport {\n LEGEND_INSET_PX,\n layoutLabels,\n} from '@jbrowse/bandage-core/labelLayout'\nimport {\n boxesGenes,\n rowPitch,\n walkRowReadout,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport {\n walkRowLabels,\n walkRowsExtent,\n} from '@jbrowse/bandage-core/layout/walkRowLayout'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n FIT_PADDING,\n drawingBounds,\n fitTransform,\n} from '@jbrowse/bandage-core/pipeline'\nimport { buildGeometry } from '@jbrowse/bandage-core/renderer/GeometryBuilder'\nimport { getDpr } from '@jbrowse/bandage-core/renderer/canvas'\nimport { layoutGeometryInputs } from '@jbrowse/bandage-core/renderer/geometryInputs'\nimport { rulerBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport {\n connectorAt,\n tubeMapConnectors,\n} from '@jbrowse/bandage-core/tubeMap/connectors'\nimport {\n mismatchOnScreen,\n mismatchesLegible,\n} from '@jbrowse/bandage-core/tubeMap/draw'\nimport {\n tubeMapFrame,\n tubeMapNodeAt,\n} from '@jbrowse/bandage-core/tubeMap/frame'\nimport {\n GENE_ROW_PX,\n tubeMapGeneRows,\n} from '@jbrowse/bandage-core/tubeMap/genes'\nimport { padded } from '@jbrowse/bandage-core/viewport'\nimport { walkPosition } from '@jbrowse/bandage-core/walkKey'\nimport {\n expandTabixShorthand,\n readConfObject,\n} from '@jbrowse/core/configuration'\nimport { getSession } from '@jbrowse/core/util'\nimport { untracked } from 'mobx'\n\nimport { hostFrame } from '../host'\nimport { SECTION_HEADER_PX, sectionPlacement } from '../walkRowGroups'\nimport { withHostViews } from './hostViews'\nimport {\n HOVER_BRIGHTEN,\n MAX_CANVAS_HEIGHT,\n MIN_CANVAS_HEIGHT,\n MIN_FIT_TUBE_PX,\n PAPER_DARK,\n PAPER_LIGHT,\n SELECT_BRIGHTEN,\n VIEWPORT_PANES_BUILT,\n dependOn,\n paneViewportOf,\n uriOf,\n} from './paneBase'\n\nimport type { FacetGrid, FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type {\n GeneGaps,\n RowPitch,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\nimport type { LiftedWalk, WalkLift } from '@jbrowse/bandage-core/walkHighlight'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport function walkRowGeneKey(\n pitch: RowPitch | undefined,\n hasGenes: boolean,\n gaps: GeneGaps | undefined,\n): GeneGaps | undefined {\n if (!pitch || !hasGenes) {\n return undefined\n }\n return boxesGenes(pitch.rowPx, pitch.barPx)\n ? gaps\n : { untracked: 0, unread: 0, ...gaps, crowded: true }\n}\n\nexport const withFitViews = withHostViews\n .views(self => ({\n // `paneHeight` replaces the built-in ceiling rather than adding a second\n // clamp under it, and the floor still wins: a pane shorter than\n // MIN_CANVAS_HEIGHT leaves no room to hover a node and read its tooltip,\n // which is the reason that floor exists.\n get paneCeiling(): number {\n return Math.max(MIN_CANVAS_HEIGHT, self.paneHeight ?? MAX_CANVAS_HEIGHT)\n },\n // Walk rows pack to fill the pane, as the strip does, so every walk of a\n // cohort is on screen; rows too thin to letter put their names and\n // readouts on hover\n get walkRowPitch(): RowPitch | undefined {\n const bars = self.walkRowBars\n if (!bars) {\n return undefined\n }\n const room = self.host ? this.canvasHeight : this.paneCeiling\n const headersPx =\n (self.walkRowGroups?.sections.length ?? 0) * SECTION_HEADER_PX\n return rowPitch(\n bars.rows.length + 1,\n room - this.fitPadTopBase - FIT_PADDING - headersPx,\n )\n },\n // Where each walk row and section header sits at the rows' pitch\n get walkRowPlacement() {\n const pitch = this.walkRowPitch\n return pitch\n ? sectionPlacement(self.walkRowGroups?.sections ?? [], pitch.rowPx)\n : undefined\n },\n // What the walk-rows key says of genes: where they went unread, or one\n // note that rows this thin box none, as the walk strip's key says\n get walkRowGeneKey() {\n return walkRowGeneKey(\n this.walkRowPitch,\n !!self.walkRowGenes?.size,\n self.walkRowGeneGaps,\n )\n },\n // Walk rows label from the bars themselves, which follow the selected\n // repeat and sample filter that the layout, run once per cut, cannot\n get drawnRowLabels() {\n const place = this.walkRowPlacement\n const labels = walkRowLabels(\n self.walkRowBars,\n self.layoutResult,\n this.walkRowPitch,\n )\n return self.walkRowBars && place\n ? labels.map((l, i) => ({ ...l, y: place.rowY(i) }))\n : labels\n },\n // The row labels are pinned to the pane's left edge, so the fit starts\n // the drawing past the widest one.\n get fitPadLeft() {\n return Math.max(\n FIT_PADDING,\n ...this.drawnRowLabels.map(r => rowLabelBox(r.label, 0).x1 + 6),\n )\n },\n // Extent of the drawing in layout units, shared by the pane height and\n // zoomToFit. On a reference-bp layout x is the cut window rather than\n // how far the drawing reaches: an allele anchored far outside it is a\n // fact about the graph, not a reason to draw the window at 6% of the\n // frame. A popped bubble fits to what it drew. Walk rows reach as far as\n // the bars on screen, which a repeat pick or a sample filter narrows\n // after the layout ran.\n get layoutBounds() {\n const layout = self.layoutResult\n const bars = self.walkRowBars\n const rowsExtent =\n bars && layout?.extent\n ? walkRowsExtent(bars, this.walkRowPitch)\n : undefined\n return layout\n ? drawingBounds(layout, {\n region: self.popStack.length === 0 ? self.graphRegion : undefined,\n extent: rowsExtent && {\n ...rowsExtent,\n maxY: rowsExtent.maxY + (this.walkRowPlacement?.headersPx ?? 0),\n },\n })\n : undefined\n },\n // What a hovered row's label and readout would say, while its rows are\n // too thin to draw them\n get hoveredWalkRowText() {\n const bars = self.walkRowBars\n const name = self.hoveredWalkRow\n if (!bars || name === null || this.walkRowPitch?.readouts !== false) {\n return undefined\n }\n const isReference = bars.reference.name === name\n const row = isReference\n ? bars.reference\n : bars.rows.find(r => r.name === name)\n return row\n ? {\n label: row.label,\n readout: walkRowReadout(\n row,\n isReference ? undefined : bars.reference,\n bars.unit,\n row.call,\n ),\n }\n : undefined\n },\n // The walk row under a pane point, as its index among the reference row\n // and the rows below it, where the point is on its bar\n walkRowAt(screenX: number, screenY: number) {\n const bars = self.walkRowBars\n const pitch = this.walkRowPitch\n const place = this.walkRowPlacement\n if (!bars || !pitch || !place) {\n return undefined\n }\n const i = place.rowAt(\n (screenY - self.translateY) / self.scaleY,\n bars.rows.length + 1,\n )\n const row = [bars.reference, ...bars.rows][i]\n const y = place.rowY(i) * self.scaleY + self.translateY\n const bp = (screenX - self.translateX) / self.scaleX - bars.origin\n return row &&\n Math.abs(screenY - y) <= pitch.barPx / 2 + 2 &&\n bp >= 0 &&\n bp <= row.bp\n ? i\n : undefined\n },\n // Room over a tube map for the rows its genes need, one inside the\n // padding and one more for each further gene that overlaps it, and\n // room for the reference strip\n get fitPadTopBase() {\n const rows = tubeMapGeneRows(self.tubeMapGenes)\n return (\n FIT_PADDING +\n Math.max(0, rows - 1) * GENE_ROW_PX +\n self.referenceStripZonePx\n )\n },\n // The fit draws nothing under the legend. It leaves the legend room on\n // the side that costs the drawing less scale: beside a tall drawing,\n // which has width to spare, or above a wide flat one, which takes the\n // height instead. A drawing whose x the host places can only move down.\n // Reads get no room: their letters, and the legend row naming them, come\n // and go with the fit's scale.\n get legendRoom(): 'right' | 'top' | undefined {\n const bounds = this.layoutBounds\n const { width, height } = self.legendSize\n if (\n !bounds ||\n bounds.w <= 0 ||\n width === 0 ||\n self.facetPanels ||\n self.tubeMapReads\n ) {\n return undefined\n }\n if (self.hostPlacesX) {\n return 'top'\n }\n const base = this.fitPadTopBase\n // a track's height is its own\n const room = self.host ? this.canvasHeight : this.paneCeiling\n const across = (padRight: number) =>\n (self.paneWidth - this.fitPadLeft - padRight) / bounds.w\n const down = (padTop: number) =>\n self.pixelRows\n ? bounds.h + padTop + FIT_PADDING <= room\n ? Infinity\n : 0\n : (room - padTop - FIT_PADDING) / bounds.h\n const beside = Math.min(across(width + 2 * LEGEND_INSET_PX), down(base))\n const above = Math.min(\n across(FIT_PADDING),\n down(base + height + LEGEND_INSET_PX),\n )\n return above >= beside ? 'top' : 'right'\n },\n get fitPadTop() {\n return (\n this.fitPadTopBase +\n (this.legendRoom === 'top'\n ? self.legendSize.height + LEGEND_INSET_PX\n : 0)\n )\n },\n get fitPadRight() {\n return this.legendRoom === 'right'\n ? Math.max(FIT_PADDING, self.legendSize.width + 2 * LEGEND_INSET_PX)\n : FIT_PADDING\n },\n // A tube map on its own axis reads by panning along it, as in\n // sequenceTubeMap. Rather than shrink a long cut to a strip, the fit\n // stops where its tubes are MIN_FIT_TUBE_PX wide, or at whatever fits\n // the tallest pane, with the cut's left end on screen.\n get minFitScale() {\n const bounds = this.layoutBounds\n const layout = self.layoutResult\n const tubePx = layout?.tubeMap?.layout.tracks[0]?.width\n return bounds && bounds.h > 0 && tubePx && !layout.referenceAxis\n ? Math.min(\n MIN_FIT_TUBE_PX / tubePx,\n (this.paneCeiling - this.fitPadTop - FIT_PADDING) / bounds.h,\n )\n : 0\n },\n // The facet as a spec writes it: the bare field while nothing else is\n // written, the whole setting otherwise, and nothing while off\n get facetSpec(): string | FacetSetting | undefined {\n const { field, domain, columns } = self.facet\n return field === ''\n ? undefined\n : domain.length === 0 && columns === undefined\n ? field\n : {\n field,\n domain: [...domain],\n ...(columns === undefined ? {} : { columns }),\n }\n },\n // Which grid cell each panel takes; see facetCells\n get facetPlacement() {\n const panels = self.facetPanels\n const { field, domain } = self.facet\n return panels\n ? facetCells(\n panels.map(p => p.walks[0]!.name),\n self.hostPlacesX || field === '' ? 'walk' : field,\n domain,\n )\n : undefined\n },\n // How the facet panels tile the pane in `room` px. A track whose x the\n // linear view places stacks full-width panels so each keeps that x.\n facetGridIn(room: number): FacetGrid | undefined {\n const place = this.facetPlacement\n const bounds = this.layoutBounds\n return place && bounds && bounds.w > 0\n ? facetGrid({\n count: place.count,\n bounds,\n pixelRows: self.pixelRows,\n width: self.paneWidth,\n room,\n columns: self.hostPlacesX\n ? 1\n : (place.columns ?? self.facet.columns),\n })\n : undefined\n },\n get facetGrid() {\n return this.facetGridIn(self.host ? this.canvasHeight : this.paneCeiling)\n },\n // The pane is as tall as the drawing, rather than a fixed box the drawing\n // floats in. A row layout's rows are px, so its height is a sum; an\n // isotropic layout has no height of its own and takes its aspect ratio\n // at the width's fit. Neither reads `scale`, so the fit reads this\n // without feeding back into it.\n get canvasHeight(): number {\n const bounds = this.layoutBounds\n const usableWidth = self.paneWidth - FIT_PADDING - this.fitPadRight\n const ceiling = this.paneCeiling\n if (!bounds) {\n return ceiling\n }\n const grid = this.facetGrid\n if (grid) {\n return Math.max(MIN_CANVAS_HEIGHT, grid.total)\n }\n // never shorter than the legend, which a flat drawing would clip\n const floor = Math.max(\n MIN_CANVAS_HEIGHT,\n self.legendSize.height +\n 2 * LEGEND_INSET_PX +\n self.referenceStripZonePx,\n )\n if (self.pixelRows) {\n return Math.min(\n ceiling,\n Math.max(floor, bounds.h + this.fitPadTop + FIT_PADDING),\n )\n }\n return bounds.w > 0 && usableWidth > 0\n ? Math.min(\n ceiling,\n Math.max(\n floor,\n bounds.h * Math.max(usableWidth / bounds.w, this.minFitScale) +\n this.fitPadTop +\n FIT_PADDING,\n ),\n )\n : ceiling\n },\n // What the transform maps the drawing into: one facet panel while the\n // pane is faceted, since every panel shares it, else the pane\n get viewBox() {\n const grid = this.facetGrid\n return grid\n ? { width: grid.width, height: grid.height }\n : { width: self.paneWidth, height: this.canvasHeight }\n },\n // Where the fit puts the drawing, or undefined until there is a layout\n // and a measured canvas to fit it into\n get fittedTransform() {\n const bounds = this.layoutBounds\n const grid = this.facetGrid\n return !bounds\n ? undefined\n : grid\n ? fitTransform(bounds, grid.width, grid.height, self.pixelRows, {\n padLeft: FACET_PAD_PX,\n padTop: FACET_PAD_PX,\n padRight: FACET_PAD_PX,\n padBottom: FACET_PAD_PX,\n })\n : fitTransform(\n bounds,\n self.paneWidth,\n this.canvasHeight,\n self.pixelRows,\n {\n minScale: this.minFitScale,\n padLeft: this.fitPadLeft,\n padTop: this.fitPadTop,\n padRight: this.fitPadRight,\n },\n )\n },\n }))\n .views(self => ({\n // The window the transform shows plus a pane of overscan all round,\n // which a pan inside needs no rebuild for\n viewportToBuild() {\n return padded(paneViewportOf(self), VIEWPORT_PANES_BUILT)\n },\n // Hover and selection as draw-time colour overrides, stated whole, so\n // there is nothing to restore and nothing to go stale when a rebuild\n // renumbers the batch\n applyHighlights(b: Renderer) {\n const { hoveredNode, hoveredEdge, selectedNode } = self\n const nodes = new Map<string, number>()\n if (selectedNode !== null) {\n nodes.set(selectedNode, SELECT_BRIGHTEN)\n }\n if (hoveredNode !== null && hoveredNode !== selectedNode) {\n nodes.set(hoveredNode, HOVER_BRIGHTEN)\n }\n b.setNodeHighlights(nodes)\n b.setEdgeHighlight(hoveredEdge, HOVER_BRIGHTEN)\n },\n // Draws the uploaded batch through the pane's transform\n paint(b: Renderer) {\n // getDpr(), never a bare `devicePixelRatio`: it is capped at\n // MAX_DPR so this canvas costs what every other canvas in the app\n // costs on a 3x display (the square of the ratio, i.e. 9x the\n // pixels of 1x against the 4x everything else pays), and it is the\n // same read `syncCanvasSize` sizes the backing store with \u2014 two\n // call sites reading the global separately can disagree, and then\n // the geometry lands at a different scale from the canvas under it.\n const dpr = getDpr()\n b.updateTransform({\n scaleX: self.scaleX * dpr,\n scaleY: self.scaleY * dpr,\n translateX: self.translateX * dpr,\n translateY: self.translateY * dpr,\n // Handed over rather than read again by the backend: the\n // thicknesses in the vertex buffer are css px and are expanded\n // after this transform, so they need the same ratio the fields\n // above were already multiplied by. See TransformUniform.dpr.\n dpr,\n })\n // Clear under a reference strip: GraphCanvas lays the paper below the\n // strip, so the linear view's gridlines show through between its blocks\n b.render(\n self.referenceStripShown\n ? [0, 0, 0, 0]\n : self.darkMode\n ? PAPER_DARK\n : PAPER_LIGHT,\n )\n },\n }))\n .views(self => ({\n // The drawing's batch with `highlight`'s walks lifted, for the window\n // the transform shows. A caller's autorun rebuilds it when the window\n // settles after a pan or zoom, when a drag moves the positions, and when\n // any display option read here changes.\n buildDrawing(highlight: WalkLift | undefined, drawPaths: boolean) {\n const { graph, nodeById, layoutResult, deletionDrawing } = self\n if (!graph || !nodeById || !layoutResult || !deletionDrawing) {\n return undefined\n }\n dependOn(self.viewportDirty, self.positionsVersion)\n const viewportBounds = untracked(() => self.viewportToBuild())\n const batch = buildGeometry({\n // walk rows' overlay draws every bar, the reference's among them;\n // its nodes stay in the hit index, so hovering the bar finds them\n ...layoutGeometryInputs(layoutResult, deletionDrawing, {\n drawsRows: !!self.walkRowBars,\n }),\n graph,\n nodeById,\n colorScheme: self.effectiveColorScheme,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n drawPaths,\n nodeWidth: self.nodeWidth,\n highlight,\n // Untracked, so a zoom does not eagerly rebuild geometry \u2014 the\n // debounced viewportDirty bump drives the scale-dependent rebuild\n // (flatness, arrow visibility, viewport culling), same as pan.\n axis: untracked(() => self.axisScale),\n linearLayout: self.linearLayout,\n viewportBounds,\n // Held against the graph rather than derived here, the same way the\n // deletion drawing is and for the same reason \u2014 see `referenceRamp`.\n referenceRamp: self.referenceRamp,\n // passed so the shared edge-curve cache can tell a drag from a pan\n version: self.positionsVersion,\n })\n return { batch, viewportBounds }\n },\n get overlayLabels() {\n return layoutLabels(self)\n },\n // where the hovered node sits on a lifted walk, while one is hovered\n hoveredOn(walk: LiftedWalk) {\n const id = self.hoveredNode\n const node = id ? self.nodeById?.get(id) : undefined\n return node\n ? (walkPosition(walk, node.id, node.length) ?? 'not on this walk')\n : undefined\n },\n // The spec bandage-figure makes this drawing from with no browser, or\n // undefined for a graph it cannot read again: one cut from a gbz-base\n // track or read from a GFA url, with the genes of a GFF3 tabix track\n figureSpec() {\n const region = self.graphRegion\n const adapter = self.sourceAdapter\n const panSN = adapter?.assemblyNameToPanSN as\n Record<string, string> | undefined\n const window = region && `${region.refName}:${region.start}-${region.end}`\n const gfa = uriOf(self.sourceGfaLocation)\n const db =\n adapter?.type === 'GbzBaseSyntenyAdapter'\n ? uriOf(adapter.gbzDbLocation as FileLocation)\n : undefined\n const source = gfa\n ? { gfa, region: window }\n : db && region && window\n ? {\n gbz: {\n db,\n index: uriOf(adapter!.haplotypeIndexLocation as FileLocation),\n region: window,\n // the adapter cuts a lane by its PanSN prefix\n haplotypes: self.cutHaplotypes?.map(\n lane => panSN?.[lane] ?? lane,\n ),\n referenceSample:\n (adapter!.referenceSample as string | undefined) ||\n panSN?.[region.assemblyName] ||\n region.assemblyName,\n context: adapter!.context as number | undefined,\n snarls: self.cutsWholeWalks\n ? 'overlapping'\n : (adapter!.subgraphSnarls as string | undefined),\n },\n }\n : undefined\n if (!source) {\n return undefined\n }\n const geneTrack = self.showGenes ? self.geneTrack : undefined\n const geneConf = geneTrack\n ? getSession(self).tracks.find(t => t.trackId === geneTrack.trackId)\n : undefined\n const geneAdapter = geneConf\n ? expandTabixShorthand(\n readConfObject(geneConf, 'adapter') as Record<string, unknown>,\n 'gffGzLocation',\n )\n : undefined\n const genes =\n geneAdapter?.type === 'Gff3TabixAdapter'\n ? {\n file: uriOf(geneAdapter.gffGzLocation as FileLocation),\n index: uriOf(\n (geneAdapter.index as { location?: FileLocation } | undefined)\n ?.location,\n ),\n format: 'gff3',\n }\n : undefined\n return JSON.parse(\n JSON.stringify({\n ...source,\n genes: genes?.file && genes.index ? genes : undefined,\n referencePath: self.referencePath || undefined,\n layout: self.chosenLayoutMode,\n ...figureSpecSettings({\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n colorScheme: self.chosenColorScheme,\n nodeWidth: self.nodeWidth,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n colorDomain: self.colorDomain,\n }),\n walks: self.walkLayers.length\n ? self.walkLayers.map(l => (l.color ? l : l.walk))\n : undefined,\n facet: self.walkLayers.length > 1 ? self.facetSpec : undefined,\n walkStrip: self.walkStripShown || undefined,\n walkRowSamples: self.walkStripShown ? self.walkRowSamples : undefined,\n width: self.paneWidth,\n height: self.paneCeiling,\n }),\n ) as Record<string, unknown>\n },\n // Why the drawing cannot be written as SVG, which draws the canvas's\n // nodes, or walk rows' bars\n get figureUnavailable() {\n return !self.layoutResult\n ? 'Nothing is drawn yet'\n : self.walkRowGroups\n ? 'The SVG export cannot group walk rows yet: set Group by\u2026 to None first'\n : self.drawsNodes || self.walkRowBars\n ? undefined\n : `${layoutModeByValue(self.chosenLayoutMode).label} draws a picture of its own, which the SVG export does not`\n },\n // Why bandage-figure can't make this drawing again: it draws only\n // layouts with nodes, from a graph it can read for itself\n get figureSpecUnavailable() {\n return !self.drawsNodes\n ? `bandage-figure draws no ${layoutModeByValue(self.chosenLayoutMode).label} layout`\n : self.popStack.length\n ? 'A spec names the whole graph, so go back out of this bubble first'\n : this.figureSpec()\n ? undefined\n : 'bandage-figure reads a graph cut from a gbz-base track or a GFA url'\n },\n // The drawing as a standalone SVG, fitted, with its genes, its lifted\n // walks' keys, facet panels and the strip of walk rows; see figureSvg\n figure() {\n const { graph, layoutResult } = self\n return graph && layoutResult && !this.figureUnavailable\n ? figureSvg(graph, layoutResult, {\n width: self.paneWidth,\n height: self.paneCeiling,\n walks: self.walkLayers,\n facet: self.facetSpec,\n colorScheme: self.effectiveColorScheme,\n nodeWidth: self.nodeWidth,\n showDeletionEdges: self.showDeletionEdges,\n linearLayout: self.linearLayout,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n region: self.graphRegion,\n colorDomain: self.colorDomain,\n fitToDrawing: self.popStack.length > 0,\n genes: self.showGenes ? self.backboneGenes : undefined,\n walkRows: self.walkRowBars,\n walkRowPitch: self.walkRowPitch,\n rowGenes: self.walkRowGenes,\n rowGeneGaps: self.walkRowGeneGaps,\n walkStrip: self.walkStripRows && {\n rows: self.walkStripRows,\n rowGenes: self.walkRowGenes,\n rowGeneGaps: self.walkRowGeneGaps,\n },\n // the SVG carries the spec only where the spec draws this same\n // picture\n spec: this.figureSpecUnavailable ? undefined : this.figureSpec(),\n })\n : undefined\n },\n get tubeMapFrame() {\n const drawing = self.layoutResult?.tubeMap\n return drawing\n ? tubeMapFrame(drawing, {\n scaleX: self.scaleX,\n translateX: self.translateX,\n scaleY: self.scaleY,\n translateY: self.translateY,\n usableHeight: self.canvasHeight - self.fitPadTop - FIT_PADDING,\n })\n : undefined\n },\n }))\n .views(self => ({\n // the reference ruler under the tubes, unless the linear view's ruler\n // is already the axis\n get tubeMapRulerBoxes() {\n const reference = self.tubeMapReference\n return reference && !self.hostPlacesX ? rulerBoxes(reference) : undefined\n },\n // The connectors run from the top of the pane down to the tubes' top\n get connectorZoneBottom() {\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n return picture && frame ? frame.y(picture.bounds.minY) - 2 : 0\n },\n // Read off the live blocks, so the bands' tops follow every frame of a\n // pan in the linear view and their bottoms every pan of the tubes\n get tubeMapConnectors() {\n const nodes = self.tubeMapReferenceNodes\n const frame = self.tubeMapFrame\n const { host, graphRegion } = self\n const bp =\n nodes && frame && host?.initialized && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n return nodes && frame && bp\n ? tubeMapConnectors(\n nodes,\n b => b * bp.scale + bp.translateX,\n frame.x,\n self.paneWidth,\n )\n : []\n },\n }))\n .views(self => ({\n // What the tube map's legend has to explain: that on the own axis a\n // box is as wide as the log of its length, the fold its walks' ticks\n // stand for, the reads' strands, and the marks on the reads in view\n get tubeMapKeys() {\n const layout = self.layoutResult\n const reads = layout?.tubeMap?.layout.reads ?? []\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n const shown =\n picture && frame && mismatchesLegible(frame.yScale)\n ? picture.mismatches.filter(m =>\n mismatchOnScreen(m, { x: frame.x, width: self.paneWidth }),\n )\n : []\n return {\n logWidths: layout?.tubeMap !== undefined && !layout.referenceAxis,\n foldBp:\n self.tubeMapDeviations.length > 0 ? self.tubeMapFold : undefined,\n forwardReads: reads.some(r => !r.is_reverse),\n reverseReads: reads.some(r => r.is_reverse),\n mismatches: new Set(shown.map(m => m.kind)),\n }\n },\n tubeMapNodeAt(sx: number, sy: number) {\n const drawing = self.layoutResult?.tubeMap\n const frame = self.tubeMapFrame\n return (\n (drawing && frame ? tubeMapNodeAt(drawing, frame, sx, sy) : null) ??\n connectorAt(self.tubeMapConnectors, self.connectorZoneBottom, sx, sy) ??\n null\n )\n },\n }))\n", "import type { SubgraphRegion } from '../GetSubgraph'\n\n// The members of a LinearGenomeView a hosted pane reads and drives.\n// Structural, because this plugin takes no runtime dependency on the LGV\n// plugin (see hoverSync/index.tsx).\nexport interface HostBlock {\n refName: string\n assemblyName: string\n start: number\n end: number\n offsetPx: number\n reversed?: boolean\n displayedRegionIndex?: number\n}\n\nexport interface LinearHost {\n id: string\n initialized: boolean\n bpPerPx: number\n offsetPx: number\n width: number\n displayedRegions: readonly { start: number; end: number }[]\n dynamicBlocks: { contentBlocks: readonly HostBlock[] }\n coarseDynamicBlocks: readonly HostBlock[]\n horizontalScroll: (distance: number) => number\n zoomTo: (bpPerPx: number, offset?: number) => number\n navTo?: (loc: {\n refName: string\n assemblyName: string\n start: number\n end: number\n }) => void\n // whether the view's body is mounted, which an off-screen view's is not\n effectiveBodyMounted?: boolean\n hasVisibleContent?: boolean\n}\n\nexport function isLinearHost(view: unknown): view is LinearHost {\n if (typeof view !== 'object' || view === null) {\n return false\n }\n const v = view as Record<string, unknown>\n return (\n typeof v.horizontalScroll === 'function' &&\n typeof v.zoomTo === 'function' &&\n 'coarseDynamicBlocks' in v &&\n 'dynamicBlocks' in v\n )\n}\n\nfunction widest(blocks: readonly HostBlock[]) {\n return blocks.reduce<HostBlock | undefined>(\n (best, b) => (best && best.end - best.start >= b.end - b.start ? best : b),\n undefined,\n )\n}\n\nexport interface HostWindow {\n refName: string\n assemblyName: string\n start: number\n end: number\n bpPerPx: number\n // the view's width in bp, which the margin is sized by: a block at a contig\n // end is clipped, the zoom is not\n span: number\n regionStart: number\n regionEnd: number\n}\n\n// x is reference bp on an anchored layout, so the graph shows what the linear\n// view shows when one bp is as many px in both and the cut's refName sits at\n// the same screen x. Undefined when the linear view shows no block of that\n// refName, which is a re-cut's job rather than the frame's. A reversed block\n// runs bp right to left, which only the tube map's connectors can draw.\nexport function hostFrame(view: LinearHost, region: SubgraphRegion) {\n const block = widest(\n view.dynamicBlocks.contentBlocks.filter(\n b =>\n b.refName === region.refName && b.assemblyName === region.assemblyName,\n ),\n )\n const { bpPerPx } = view\n if (!block || !(bpPerPx > 0)) {\n return undefined\n }\n const left = block.offsetPx - view.offsetPx\n return block.reversed\n ? { scale: -1 / bpPerPx, translateX: left + block.end / bpPerPx }\n : { scale: 1 / bpPerPx, translateX: left - block.start / bpPerPx }\n}\n\n// Read off the LIVE blocks even when the coarse ones woke the caller: those\n// name where the window was half a second ago (SyntenyFollow/CLAUDE.md).\nexport function hostWindow(view: LinearHost): HostWindow | undefined {\n const block = widest(view.dynamicBlocks.contentBlocks)\n const displayed =\n block?.displayedRegionIndex === undefined\n ? undefined\n : view.displayedRegions[block.displayedRegionIndex]\n return block && view.bpPerPx > 0\n ? {\n refName: block.refName,\n assemblyName: block.assemblyName,\n start: block.start,\n end: block.end,\n bpPerPx: view.bpPerPx,\n span: view.bpPerPx * view.width,\n regionStart: displayed?.start ?? block.start,\n regionEnd: displayed?.end ?? block.end,\n }\n : undefined\n}\n\n// The window plus one window-width each side, clamped to the displayed\n// region, with the margins narrowed until the whole cut fits under `capBp`.\nexport function hostCut(\n window: HostWindow,\n capBp: number,\n margins = true,\n): SubgraphRegion {\n const visible = window.end - window.start\n const margin = margins\n ? Math.max(0, Math.min(window.span, (capBp - visible) / 2))\n : 0\n let start = Math.max(window.regionStart, Math.floor(window.start - margin))\n let end = Math.min(window.regionEnd, Math.ceil(window.end + margin))\n // Rounding outward can put a cut a base or two past the cap, which the load\n // refuses whole; trim it back rather than lose the cut.\n const over = end - start - capBp\n if (over > 0) {\n start += Math.floor(over / 2)\n end -= Math.ceil(over / 2)\n }\n return {\n refName: window.refName,\n assemblyName: window.assemblyName,\n start,\n end,\n }\n}\n\n// With margins, a cut holds while the window is inside it; without, only the\n// window itself does, since the drawing is the window.\nexport function cutHolds(\n cut: SubgraphRegion | undefined,\n window: HostWindow,\n margins = true,\n) {\n if (\n cut?.refName !== window.refName ||\n cut.assemblyName !== window.assemblyName\n ) {\n return false\n }\n // to the base, since a cut trimmed to its cap can end a base inside the window\n if (margins) {\n return cut.start <= window.start + 1 && window.end <= cut.end + 1\n }\n const exact = hostCut(window, Infinity, false)\n return (\n Math.abs(cut.start - exact.start) < 1 && Math.abs(cut.end - exact.end) < 1\n )\n}\n", "import {\n backboneNodes,\n backboneSpan,\n} from '@jbrowse/bandage-core/anchoredNodes'\nimport { nodeReferenceSpan } from '@jbrowse/bandage-core/referenceSpan'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport { getContainingView, getSession } from '@jbrowse/core/util'\n\nimport { withGraphViews } from './graphViews'\nimport {\n contributingAssemblies,\n nodeOwnLocation,\n resolveContributors,\n resolveLocationAssembly,\n} from '../../launchFromGraph/contributors'\nimport {\n canonicalAssemblyName,\n paddedLocation,\n withReferenceRegion,\n} from '../../launchFromGraph/launchFromGraph'\nimport { linearViewTarget } from '../../launchFromGraph/linearViewTarget'\nimport { GENE_ADAPTER_TYPES, pickGeneTrack } from '../genes/geneFeatures'\nimport { isLinearHost } from '../host'\n\nimport type { LinearHost } from '../host'\n\nexport const withLaunchViews = withGraphViews\n .views(self => ({\n // Every assembly this graph names a segment from, with the locus each one\n // contributes here. rGFA's SN tag is what makes this knowable: the graph\n // states its own contributors, so the view can offer a way out to each of\n // them without consulting an alignment.\n //\n // Gaps larger than the backbone span split a contributor's segments into\n // separate loci and the widest wins, so a sample that also contributes\n // sequence from a distant duplication is launched at the locus on screen\n // rather than at the union of the two.\n get contributingAssemblies() {\n const graph = self.graph\n const backbone = graph ? backboneNodes(graph) : []\n return graph\n ? contributingAssemblies(graph, {\n maxGap: backbone.length > 0 ? backboneSpan(backbone) : Infinity,\n })\n : []\n },\n }))\n .views(self => ({\n // A node's PanSN sample as an assembly this session can open, or\n // undefined. The graph's spelling and the assembly's need not agree:\n // HPRC writes `CHM13` where the assembly is UCSC's `hs1`. The track the\n // graph was cut from states that pairing in its `assemblyNameToPanSN`,\n // so its map is read first, then `assemblyManager`'s names and aliases.\n //\n // `has` before `get`, deliberately: `get` reports an unknown name to\n // `Core-handleUnrecognizedAssembly`, which asks every installed plugin to\n // go supply it, and this is a probe run for hundreds of haplotypes per\n // graph.\n get assemblyResolver() {\n const { assemblyManager } = getSession(self)\n const panSN = self.sourceAdapter?.assemblyNameToPanSN as\n Record<string, string> | undefined\n const byPrefix = new Map(\n Object.entries(panSN ?? {}).map(([asm, prefix]) => [prefix, asm]),\n )\n const loaded = (name: string | undefined) =>\n name !== undefined && assemblyManager.has(name)\n ? (assemblyManager.get(name)?.name ?? name)\n : undefined\n return (sample: string) => loaded(byPrefix.get(sample)) ?? loaded(sample)\n },\n // Each assembly's gene track among the session's tracks, picked as the\n // backbone's is, so a walk row can read its haplotype's own annotation.\n // One pass over the tracks, not one per row.\n get geneTracksByAssembly() {\n const byAssembly = new Map<\n string,\n { trackId: string; name: string; adapterType: string }[]\n >()\n for (const t of getSession(self).tracks) {\n const adapterType = (readConfObject(t, 'adapter') as { type: string })\n .type\n if (!GENE_ADAPTER_TYPES.has(adapterType)) {\n continue\n }\n const track = {\n trackId: t.trackId as string,\n name: readConfObject(t, 'name') as string,\n adapterType,\n }\n for (const name of readConfObject(t, 'assemblyNames') as string[]) {\n const asm = canonicalAssemblyName(getSession(self), name)\n byAssembly.set(asm, [...(byAssembly.get(asm) ?? []), track])\n }\n }\n return new Map(\n [...byAssembly].flatMap(([asm, tracks]) => {\n const picked = pickGeneTrack(tracks, '')\n return picked ? [[asm, picked] as const] : []\n }),\n )\n },\n }))\n .views(self => ({\n // The contributors a view can actually be opened on: those naming an\n // assembly this session has loaded. Every strain of an E. coli pangenome\n // demo is its own assembly, so all of them resolve; an HPRC graph names\n // hundreds of haplotypes that no session loads, so only the reference\n // does.\n get launchableAssemblies() {\n return resolveContributors(\n withReferenceRegion(self.contributingAssemblies, self.graphRegion),\n self.assemblyResolver,\n )\n },\n // Whether there is a linear view this graph may draw a highlight into \u2014\n // the paired one, or the session's only one on the reference assembly.\n // Read by the node menu, which offers the item only when it would land\n // somewhere.\n get canHighlightInLinearView() {\n const region = self.graphRegion\n return (\n region !== undefined &&\n linearViewTarget({\n views: [...getSession(self).views],\n connectedViewId: self.connectedViewId,\n assemblyName: region.assemblyName,\n }) !== undefined\n )\n },\n // Where one node can be opened: on its own assembly, and on the reference\n // the graph was cut against. Both are padded to a readable window \u2014 a\n // base-level allele is a few bp, and a linear view framed on exactly that\n // shows no context at all.\n nodeLaunchTargets(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n const own = node ? nodeOwnLocation(node) : undefined\n const ownAssembly = own\n ? resolveLocationAssembly(self.assemblyResolver, own)\n : undefined\n const region = self.graphRegion\n const nodeById = self.nodeById\n const neighbors = self.nodeNeighbors\n const span =\n region && nodeById && neighbors\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n const onReference =\n region && span\n ? {\n sample: region.assemblyName,\n haplotype: undefined,\n refName: region.refName,\n ...span,\n }\n : undefined\n return {\n own:\n own && ownAssembly\n ? { location: paddedLocation(own), assembly: ownAssembly }\n : undefined,\n reference:\n region && onReference\n ? {\n location: paddedLocation(onReference),\n assembly: region.assemblyName,\n }\n : undefined,\n // Unpadded: a mark is of the node, the same span its hover band\n // draws. The padding above is room to read a view opened on it.\n highlight:\n region && onReference\n ? { location: onReference, assembly: region.assemblyName }\n : undefined,\n }\n },\n }))\n .views(self => ({\n // The linear view this pane draws inside, when a display hosts it: x is\n // that view's window and the cut is re-made when the window leaves it.\n // A pane that is a view of its own has none.\n get host(): LinearHost | undefined {\n let view: unknown\n try {\n view = getContainingView(self)\n } catch {\n return undefined\n }\n return isLinearHost(view) ? view : undefined\n },\n }))\n", "import {\n bubbleSegmentIds,\n classifyBubble,\n formatBp\n} from \"./chunk-WOO7QYKB.js\";\nimport {\n svgPath\n} from \"./chunk-2CVHXFK7.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/bubbles/bubbleHalos.ts\nvar WHOLE_FRACTION = 0.9;\nvar NAMED_WALKS = 2;\nvar MIN_CHIPPED_BP = 1e3;\nfunction bubbleHalos(graph, bubbles, positions, walkLabel = (name) => name, repeats = []) {\n const byName = new Map(graph.nodes.map((n) => [n.name, n]));\n const halos = [];\n for (const bubble of bubbles) {\n const parts = [];\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n const nodeIds = [];\n const ends = [];\n for (const name of bubbleSegmentIds(bubble)) {\n const node = byName.get(name);\n const line = node && positions[node.id];\n if (!node || !line?.length) {\n continue;\n }\n if (isBackbone(node) && (node.stable.start < bubble.start || node.stable.start >= bubble.end)) {\n ends.push(line[Math.floor(line.length / 2)]);\n continue;\n }\n nodeIds.push(node.id);\n parts.push(svgPath(line.length === 1 ? [line[0], line[0]] : line));\n for (const p of line) {\n minX = Math.min(minX, p.x);\n maxX = Math.max(maxX, p.x);\n minY = Math.min(minY, p.y);\n }\n }\n if (nodeIds.length === 0) {\n continue;\n }\n const labelAt = { x: (minX + maxX) / 2, y: minY };\n const anchor = ends.length ? {\n x: ends.reduce((s, p) => s + p.x, 0) / ends.length,\n y: ends.reduce((s, p) => s + p.y, 0) / ends.length\n } : labelAt;\n const sharing = /* @__PURE__ */ new Map();\n for (const route of bubble.routes ?? []) {\n for (const id of new Set(route.steps)) {\n sharing.set(id, (sharing.get(id) ?? 0) + 1);\n }\n }\n const routes = [];\n for (const route of bubble.routes ?? []) {\n if (bubble.longestAlleleLength < MIN_CHIPPED_BP) {\n break;\n }\n if (route.steps.length === 0) {\n continue;\n }\n const rarest = Math.min(...route.steps.map((id) => sharing.get(id)));\n let at;\n let far = -1;\n for (const id of route.steps) {\n if (sharing.get(id) !== rarest) {\n continue;\n }\n for (const p of positions[id] ?? []) {\n const d = Math.hypot(p.x - anchor.x, p.y - anchor.y);\n if (d > far) {\n far = d;\n at = p;\n }\n }\n }\n if (at) {\n routes.push({ route, at, text: routeText(route, walkLabel) });\n }\n }\n halos.push({\n bubble,\n ...classifyBubble(bubble, repeats),\n path: parts.join(\"\"),\n labelAt,\n members: nodeIds.length,\n nodeIds,\n whole: nodeIds.length >= WHOLE_FRACTION * graph.nodes.length,\n routes\n });\n }\n return halos;\n}\nfunction routeText(route, walkLabel) {\n const names = [...new Set(route.walks.map(walkLabel))].sort();\n const shown = names.slice(0, NAMED_WALKS).join(\", \");\n const more = names.length > NAMED_WALKS ? ` +${names.length - NAMED_WALKS}` : \"\";\n return `${shown}${more} \\xB7 ${formatBp(route.bp)}`;\n}\n\nexport {\n bubbleHalos\n};\n", "import {\n SATURATED_PATH_COUNT\n} from \"./chunk-MFKORG3F.js\";\nimport {\n referenceOrder\n} from \"./chunk-HNQPEMYE.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/bubbles/bubblesFromGraph.ts\nfunction bubblesFromGraph(graph) {\n if (!graph.nodes.some(isBackbone)) {\n return [];\n }\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const order = referenceOrder(graph);\n const indexOf = new Map(order.map((id, i) => [id, i]));\n const reach = new Int32Array(order.length + 1);\n const succ = /* @__PURE__ */ new Map();\n const linked = /* @__PURE__ */ new Set();\n for (const e of graph.edges) {\n const a = indexOf.get(e.from);\n const b = indexOf.get(e.to);\n if (a === void 0 || b === void 0 || a === b) {\n continue;\n }\n linked.add(`${e.from}>${e.to}`).add(`${e.to}>${e.from}`);\n const [lo, hi] = a < b ? [a, b] : [b, a];\n reach[lo + 1]++;\n reach[hi]--;\n const [from, to] = a < b ? [e.from, e.to] : [e.to, e.from];\n (succ.get(from) ?? succ.set(from, /* @__PURE__ */ new Set()).get(from)).add(to);\n }\n for (let i = 1; i < reach.length; i++) {\n reach[i] += reach[i - 1];\n }\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const ends = /* @__PURE__ */ new Set([backbone[0].id, backbone.at(-1).id]);\n const boundaries = backbone.map((node) => [node, indexOf.get(node.id)]).filter(([node, i]) => ends.has(node.id) || reach[i] === 0).sort(([a, ia], [b, ib]) => ia - ib || a.stable.start - b.stable.start);\n const walkIndex = graph.paths?.map((p) => {\n const at = /* @__PURE__ */ new Map();\n p.nodeIds.forEach((id, i) => {\n if (!at.has(id)) {\n at.set(id, i);\n }\n });\n return at;\n });\n const bubbles = [];\n for (let i = 0; i + 1 < boundaries.length; i++) {\n const [start, i0] = boundaries[i];\n const [end, i1] = boundaries[i + 1];\n const interior = order.slice(i0 + 1, i1);\n if (interior.length === 0) {\n continue;\n }\n const best = /* @__PURE__ */ new Map([[start.id, { min: 0, max: 0, n: 1 }]]);\n for (const id of [start.id, ...interior]) {\n const cur = best.get(id);\n if (!cur) {\n continue;\n }\n for (const t of succ.get(id) ?? []) {\n const ti = indexOf.get(t);\n if (ti > i1) {\n continue;\n }\n const add = t === end.id ? 0 : byId.get(t).length;\n const prev = best.get(t);\n best.set(t, {\n min: Math.min(prev?.min ?? Infinity, cur.min + add),\n max: Math.max(prev?.max ?? -Infinity, cur.max + add),\n n: Math.min(SATURATED_PATH_COUNT, cur.n + (prev?.n ?? 0))\n });\n }\n }\n const walked = walkIndex && walkRoutes(graph, byId, walkIndex, start.id, end.id);\n const crossed = walked?.n ? walked : void 0;\n const routes = crossed ?? best.get(end.id) ?? { min: 0, max: 0, n: 0 };\n const walksLeave = walked !== void 0 && walked.left > 0;\n const refStart = start.stable.start + start.length;\n const refEnd = end.stable.start;\n const chain = [\n start.id,\n ...interior.filter((id) => isBackbone(byId.get(id))),\n end.id\n ];\n const chainBroken = chain.some(\n (id, k) => k > 0 && !linked.has(`${chain[k - 1]}>${id}`)\n );\n const partial = chainBroken || walksLeave;\n const fallback = chainBroken && !crossed;\n bubbles.push({\n refName: start.stable.refName,\n start: refStart,\n end: refEnd,\n segmentCount: interior.length + 2,\n pathCount: routes.n,\n // a real inversion test needs each walk's direction relative to the\n // reference; the first visit's strand is just whichever path anchored the\n // node\n inversion: false,\n shortestAlleleLength: fallback ? refEnd - refStart : routes.min,\n longestAlleleLength: fallback ? refEnd - refStart : routes.max,\n segments: [start, ...interior.map((id) => byId.get(id)), end].map((n) => n.name).join(\",\"),\n shortestAllele: void 0,\n longestAllele: void 0,\n partial,\n routes: crossed?.routes\n });\n }\n return bubbles;\n}\nfunction walkRoutes(graph, byId, walkIndex, startId, endId) {\n const seen = /* @__PURE__ */ new Map();\n let min = Infinity;\n let max = -Infinity;\n let left = 0;\n graph.paths.forEach((p, k) => {\n const i0 = walkIndex[k].get(startId);\n const i1 = walkIndex[k].get(endId);\n if (i0 === void 0 || i1 === void 0) {\n if (i0 !== void 0 || i1 !== void 0) {\n left++;\n }\n return;\n }\n const steps = p.nodeIds.slice(Math.min(i0, i1) + 1, Math.max(i0, i1));\n if (i1 < i0) {\n steps.reverse();\n }\n let bp = 0;\n for (const id of steps) {\n bp += byId.get(id)?.length ?? 0;\n }\n const key = steps.join(\",\");\n const route = seen.get(key) ?? { steps, bp, walks: [] };\n route.walks.push(p.name);\n seen.set(key, route);\n min = Math.min(min, bp);\n max = Math.max(max, bp);\n });\n return seen.size || left ? { min, max, n: seen.size, left, routes: [...seen.values()] } : void 0;\n}\n\nexport {\n bubblesFromGraph\n};\n", "import {\n computeColorSchemeRange,\n getNodeColor\n} from \"./chunk-RCWYY6XA.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-UMNCCYBN.js\";\n\n// src/tubeMap/nodeColors.ts\nfunction tubeMapNodeColors(graph, colorScheme, referenceRamp) {\n if (colorScheme === \"uniform\" || colorScheme === \"grey\") {\n return void 0;\n }\n const range = { ...computeColorSchemeRange(graph), referenceRamp };\n return new Map(\n graph.nodes.map((node, index) => [\n node.id,\n abgrToCssRgba(getNodeColor(node, index, colorScheme, range))\n ])\n );\n}\n\nexport {\n tubeMapNodeColors\n};\n", "import { bubbleHalos } from '@jbrowse/bandage-core/bubbles/bubbleHalos'\nimport { bubblesFromGraph } from '@jbrowse/bandage-core/bubbles/bubblesFromGraph'\nimport { resolveColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport {\n deletionDrawing,\n deletionEdges,\n} from '@jbrowse/bandage-core/deletionEdges'\nimport { genePins } from '@jbrowse/bandage-core/genes/genePins'\nimport { filterSamples, walkRows } from '@jbrowse/bandage-core/layout/walkRows'\nimport {\n layoutModeByValue,\n modeUsesLayoutEngine,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { nodeInk } from '@jbrowse/bandage-core/nodeWidths'\nimport {\n pathColorsLegible,\n pathGreyCssColor,\n pathLegend,\n walkLabelsOf,\n} from '@jbrowse/bandage-core/pathColors'\nimport {\n backboneAssembly,\n featuresOnBackbone,\n graphBackbone,\n} from '@jbrowse/bandage-core/reference'\nimport {\n buildNeighbors,\n nodeReferenceSpan,\n} from '@jbrowse/bandage-core/referenceSpan'\nimport {\n LIFT_BACKDROP_CSS,\n computeReferenceRamp,\n} from '@jbrowse/bandage-core/renderer/GeometryBuilder'\nimport { tubeMapNodeColors } from '@jbrowse/bandage-core/tubeMap/nodeColors'\nimport { axisScaleOf } from '@jbrowse/bandage-core/viewport'\nimport { NO_VALUE_COLOR } from '@jbrowse/bandage-core/walkEncoding'\nimport { facetLifts, walkLift } from '@jbrowse/bandage-core/walkHighlight'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'\nimport {\n getContainingTrack,\n getContainingView,\n getEnv,\n getSession,\n} from '@jbrowse/core/util'\n\nimport { TUBE_MAP_MODES, dependOn, geometryPainted, paneBase } from './paneBase'\nimport { trackAdapterConfig } from '../../panSNAliases/trackAdapterConfig'\nimport {\n GENE_ADAPTER_TYPES,\n geneModelsFrom,\n laneFilters,\n pickGeneTrack,\n} from '../genes/geneFeatures'\nimport {\n REPEAT_ADAPTER_TYPES,\n pickRepeatTrack,\n} from '../repeats/repeatFeatures'\nimport { withCalls } from '../repeats/walkCalls'\nimport { groupWalkRows, metadataColumns } from '../walkRowGroups'\n\nimport type {\n ColorScheme,\n ResolvedColorScheme,\n} from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AssemblyNames } from '@jbrowse/bandage-core/reference'\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\nimport type { NodeInk } from '@jbrowse/bandage-core/util/hitDetection'\nimport type { WalkLayer } from '@jbrowse/bandage-core/walkEncoding'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport const withGraphViews = paneBase\n .views(self => ({\n get defaultLayoutMode(): LayoutModeValue {\n return 'force'\n },\n get defaultColorScheme(): ColorScheme {\n return 'auto'\n },\n // a source declared but not yet loaded\n get hasPendingSource() {\n return false\n },\n get canRetryLoad() {\n return false\n },\n // the track the graph is cut from: the one the pane is a display of\n get sourceTrack(): AnyConfigurationModel | undefined {\n try {\n return getContainingTrack(self).configuration\n } catch {\n return undefined\n }\n },\n }))\n .views(self => ({\n get chosenLayoutMode() {\n return self.layoutMode ?? self.defaultLayoutMode\n },\n get chosenColorScheme() {\n return self.colorScheme ?? self.defaultColorScheme\n },\n }))\n .views(self => ({\n get paneWidth() {\n return getContainingView(self).width\n },\n // The graph the drawing's node ids address: a folded tube map's coarse\n // graph, the cut otherwise. Hover, details and labels read it, so a\n // merged node reports its own span and length.\n get drawnGraph() {\n return self.layoutResult?.tubeMap?.coarse?.graph ?? self.graph\n },\n }))\n .views(self => ({\n get nodeById() {\n if (self.drawnGraph) {\n const m = new Map<string, GraphNode>()\n for (const n of self.drawnGraph.nodes) {\n m.set(n.id, n)\n }\n return m\n }\n return undefined\n },\n // bp per node id, which is all the label overlay needs of a GraphNode.\n // Held here rather than rebuilt in the component: that render runs on\n // every pan, and the map is a fact about the graph (measured 6.9 ms an\n // allocation on a 30k-node cut).\n get nodeLengths() {\n const m = new Map<string, number>()\n for (const n of self.drawnGraph?.nodes ?? []) {\n m.set(n.id, n.length)\n }\n return m\n },\n get nodeCount() {\n return self.graph?.nodes.length ?? 0\n },\n get edgeCount() {\n return self.graph?.edges.length ?? 0\n },\n get pathCount() {\n return self.graph?.paths?.length ?? 0\n },\n get hasGraph() {\n return self.graph !== undefined\n },\n get geometryPainted() {\n return geometryPainted(self)\n },\n // The app-wide readiness contract (AppReadyMarker, @jbrowse/capture)\n // reads this: a declared source still fetching, or a graph whose\n // settled geometry is not on the canvas yet.\n get showLoading() {\n return (\n self.error === undefined &&\n (self.isLoading ||\n self.hasPendingSource ||\n (self.graph !== undefined && !geometryPainted(self)))\n )\n },\n // Only before anything is drawn: past that point a reload is superseded\n // by the next setting change, and stopping one midway would leave a new\n // graph under the previous graph's layout.\n get canCancelLoad() {\n return self.isLoading && !self.layoutResult\n },\n // Whether the drawing on screen is the FMMM engine's. False before there\n // is a graph, since nothing is drawn by anything yet.\n //\n // Read by the settings that only the engine looks at: the layout quality\n // and the bubble spread do nothing at all to an anchored drawing, which\n // places a node from its coordinates, and the guide says so in prose\n // precisely because the dialog did not. A control that silently does\n // nothing is worse than one that says it cannot \u2014 the same rule the\n // `drawPaths` switch already follows.\n get usesLayoutEngine() {\n return self.graph\n ? modeUsesLayoutEngine(self.chosenLayoutMode, self.graph)\n : false\n },\n // A rank-0 backbone to draw x against, whether the segments declared it\n // (rGFA) or a path walk derived it. Only a GFA with neither tags nor\n // paths has no backbone at all, and there force is the one honest layout.\n get canAnchorLayout() {\n return self.graph?.nodes.some(n => n.stable?.rank === 0) ?? false\n },\n // The paths this graph could be anchored on, for the picker. Empty for an\n // rGFA, which has no P/W records and needs none.\n get anchorPaths() {\n return self.graph?.anchorPaths ?? []\n },\n // Every walk the graph carries, named for a picker, whatever the count.\n get walkChoices() {\n const paths = self.graph?.paths\n return paths?.length ? pathLegend(paths) : []\n },\n // Whether the drawing is actually painted per path, which is not the same\n // question as whether the user asked for it: past MAX_PATH_COLORS the\n // colours say nothing and cost a stroke per path per edge. A bare getter\n // returning a resolved value, the same shape and for the same reason as\n // `effectiveColorScheme` \u2014 every consumer of a path colour reads this\n // one, so the geometry, the hit index and the key cannot disagree about\n // whether there are any. The switch in the settings dialog reads the raw\n // `drawPaths`, so the user's choice stays visible as the choice it is.\n get effectiveDrawPaths() {\n return self.drawPaths && pathColorsLegible(self.graph?.paths?.length ?? 0)\n },\n // The path x is currently drawn on, which is not necessarily the one\n // `referencePath` asked for: an unmatched name falls back rather than\n // leaving the graph unanchored, and the picker has to show what happened.\n get activeReferencePath() {\n return self.graph?.referencePath\n },\n // Undefined for a graph with neither, where the ramp spans the drawn\n // extent (computeReferenceRamp)\n get rampDomain() {\n return self.colorDomain ?? self.graphRegion\n },\n // The ramp a lane coloured by reference position reads, computed only\n // when a layer asks for one: it is a neighbour walk per node\n get walkRamp() {\n const { graph } = self\n return graph &&\n self.walkLayers.some(layer => layer.color?.field === 'reference')\n ? computeReferenceRamp(graph, this.rampDomain)\n : undefined\n },\n // Whether the chosen layout draws the graph's nodes, which a facet\n // splits and a hovered lane row's walk is lifted over\n get modeDrawsNodes() {\n return layoutModeByValue(self.chosenLayoutMode).drawsNodes\n },\n // The walks picked, or while none is, those of the lane row hovered\n get liftedWalkLayers(): WalkLayer[] {\n return self.walkLayers.length > 0 || !this.modeDrawsNodes\n ? self.walkLayers\n : self.hoveredRowWalks.map(walk => ({ walk }))\n },\n // The lifted walks the graph on screen carries, or undefined when none\n // is named or it carries none of those that were\n get walkLift() {\n const { graph } = self\n const layers = this.liftedWalkLayers\n return graph && layers.length > 0 && !self.layoutResult?.tubeMap\n ? walkLift(graph, layers, this.walkRamp)\n : undefined\n },\n // One panel per lifted walk while the pane is faceted by walk, each a\n // lift of that walk alone, on a layout whose nodes the panels can split.\n // See facetLifts.\n get facetPanels() {\n const { graph } = self\n const lift = this.walkLift\n return self.facet.field !== '' &&\n this.modeDrawsNodes &&\n graph &&\n lift &&\n self.walkLayers.length > 1 &&\n lift.walks.length > 1\n ? facetLifts(graph, lift, self.walkLayers, this.walkRamp)\n : undefined\n },\n // The lifted walks as drawn, each panel's own while faceted\n get drawnWalks() {\n return (\n this.facetPanels?.map(panel => panel.walks[0]!) ??\n this.walkLift?.walks ??\n []\n )\n },\n // A tube map draws every walk as a tube of its own\n get liftsWalks() {\n return !TUBE_MAP_MODES.has(self.chosenLayoutMode)\n },\n // The window a lane coloured by reference position spans, by name\n get walkReference() {\n const domain = this.walkLift?.referenceDomain\n return domain && { ...domain, name: self.graphRegion?.refName }\n },\n // A label per walk, which the pickers, the keys and a bubble's label all\n // read, so a walk name repeated across records reads the same everywhere\n get walkLabels() {\n return walkLabelsOf(this.walkChoices)\n },\n walkLabel(name: string) {\n return this.walkLabels.get(name) ?? name\n },\n // Whether a lifted lane paints a node charcoal, the colour a lane coloured\n // by reference position gives what is off the reference\n get liftPaintsOffReference() {\n for (const w of this.walkLift?.walks ?? []) {\n if (w.encoding.field !== 'walk') {\n for (const color of w.colors.values()) {\n if (color === NO_VALUE_COLOR) {\n return true\n }\n }\n }\n }\n return false\n },\n // what the faded rest of the drawing is not on\n get liftedWalksLabel() {\n const walks = this.walkLift?.walks ?? []\n return walks.length === 1 ? this.walkLabel(walks[0]!.name) : 'these walks'\n },\n // The scheme the renderer actually paints with, which is the raw prop\n // unless it is 'auto'. A bare getter returns a resolved value (root\n // CLAUDE.md): every consumer of a colour reads this one, and the two\n // dropdowns read `colorScheme` so \"Auto\" stays visible as the choice it\n // is.\n //\n // 'auto' asks the GRAPH, not the layout. A hue along the reference is\n // meaningful whenever the segments have reference coordinates \u2014\n // `anchoredBy` is exactly that question \u2014 and a force-directed drawing of\n // an rGFA is the case that proves it: the layout has no reference axis and\n // the ramp still says where on the reference each node came from, which is\n // the only quantity a linear track beside it can be painted with too.\n //\n // A tube map tells its paths apart by their tubes' hues, so there 'auto'\n // leaves the boxes clear and a node scheme is the user's pick. Beside\n // reads, which take the reds and the blues, the boxes stay clear\n // whatever was picked.\n get effectiveColorScheme(): ResolvedColorScheme {\n return self.layoutResult?.tubeMap &&\n (this.tubeMapReads || self.chosenColorScheme === 'auto')\n ? 'uniform'\n : resolveColorScheme(self.chosenColorScheme, self.graph)\n },\n get tubeMapReads() {\n return (self.layoutResult?.tubeMap?.layout.reads.length ?? 0) > 0\n },\n // Why no node scheme is on screen to pick, for every control that\n // offers one: lifted walks colour their own lanes and grey the rest,\n // and reads take a tube map's reds and blues\n get colorSchemeLock() {\n return this.walkLift\n ? {\n value: 'By walk',\n why: 'Each lifted walk colours its own lane: set it under the menu, Walk, Colour',\n }\n : this.tubeMapReads\n ? {\n value: 'By strand',\n why: 'Reads take the reds and blues, so the tube map leaves its nodes clear',\n }\n : undefined\n },\n get nodePositions() {\n return self.layoutResult?.nodePositions\n },\n // a length label would sit on the lanes of lifted walks\n get labelsNodeSizes() {\n return !self.layoutResult?.tubeMap && !this.walkLift\n },\n // Empty rather than undefined: every consumer maps over it, and a layout\n // with no row structure (FMMM) is a normal state, not a missing one.\n get rowLabels() {\n return self.layoutResult?.rowLabels ?? []\n },\n // Deletions the layout found inside an allele, empty for the same reason\n // rowLabels is: a layout drawn at sequence scale states none, because\n // there a node's drawn extent already IS its length. `deletions` beside\n // this one is the bare-edge kind, which every layout has.\n get alleleDeletions() {\n return self.layoutResult?.alleleDeletions ?? []\n },\n get deletionRoutes() {\n return self.layoutResult?.deletionRoutes\n },\n get stranded() {\n return self.layoutResult?.stranded\n },\n // Whether the current layout states y in screen px rather than in the same\n // units as x (LayoutResult.pixelRows). Everything that has to put the two\n // axes in one expression reads this through scaleX/scaleY.\n get pixelRows() {\n return self.layoutResult?.pixelRows ?? false\n },\n get zoomPercent() {\n return `${(self.scale * 100).toFixed(1)}%`\n },\n // True while the persisted transform is still the schema default, i.e.\n // neither a restored session nor the user has positioned this view yet,\n // so an incoming layout is free to zoom-to-fit.\n get isDefaultViewport() {\n return self.scale === 1 && self.translateX === 0 && self.translateY === 0\n },\n }))\n .views(self => ({\n get poppedFrom() {\n return self.popStack.at(-1)\n },\n // The bubbles the graph itself states, for a graph with no index: a GBZ\n // cut, a pggb file, the inside of a popped bubble.\n get derivedBubbles() {\n return self.graph ? bubblesFromGraph(self.graph) : []\n },\n }))\n .views(self => ({\n // The bubbles halos draw and pops open. Index rows win where both exist:\n // gfatools measured every allele, the layered order only bounds them.\n get bubbles() {\n return self.indexBubbles?.length ? self.indexBubbles : self.derivedBubbles\n },\n }))\n .views(self => ({\n // the haplotypes the graph on screen was cut for, where a host says\n get cutHaplotypes(): string[] | undefined {\n return undefined\n },\n // the GFA the graph on screen was read from, where a host says\n get sourceGfaLocation(): FileLocation | undefined {\n return undefined\n },\n get sourceAdapter() {\n const track = self.sourceTrack\n return track ? trackAdapterConfig(self, track) : undefined\n },\n get sourceTrackId() {\n const track = self.sourceTrack\n return track ? (readConfObject(track, 'trackId') as string) : undefined\n },\n get assemblyTrackChoices() {\n const region = self.graphRegion\n if (!region) {\n return []\n }\n return getSession(self)\n .tracks.filter(t =>\n (readConfObject(t, 'assemblyNames') as string[]).includes(\n region.assemblyName,\n ),\n )\n .map(t => ({\n trackId: t.trackId as string,\n name: readConfObject(t, 'name') as string,\n adapterType: (readConfObject(t, 'adapter') as { type: string }).type,\n }))\n },\n }))\n .views(self => ({\n get geneTrackChoices() {\n return self.assemblyTrackChoices.filter(t =>\n GENE_ADAPTER_TYPES.has(t.adapterType),\n )\n },\n // The session's feature tracks a repeat annotation could be, for the\n // picker; which one is read is pickRepeatTrack's choice.\n get repeatTrackChoices() {\n return self.assemblyTrackChoices.filter(t =>\n REPEAT_ADAPTER_TYPES.has(t.adapterType),\n )\n },\n // The arrays over the window that state a unit, for the Repeat picker.\n get repeatChoices() {\n return self.repeatArrays ?? []\n },\n }))\n .views(self => ({\n get repeatTrack() {\n return pickRepeatTrack(self.repeatTrackChoices, self.repeatTrackId)\n },\n get geneTrack() {\n return pickGeneTrack(self.geneTrackChoices, self.geneTrackId)\n },\n get selectedRepeat() {\n return self.repeatChoices.find(r => r.key === self.repeatKey)\n },\n get backbone() {\n return self.graph ? graphBackbone(self.graph) : undefined\n },\n // Each walk sliced to the window, for walk rows and the strip; a repeat\n // pick slices again by its own array\n get cutWalkRows() {\n return self.graph ? walkRows(self.graph, self.graphRegion) : undefined\n },\n // An assembly by each name a backbone may spell it with: the session's\n // name and aliases, and the PanSN prefix the source track maps each of\n // those to.\n assemblySpellings(assemblyName: string): AssemblyNames {\n const { assemblyManager } = getSession(self)\n const assembly = assemblyManager.has(assemblyName)\n ? assemblyManager.get(assemblyName)\n : undefined\n const panSN = (self.sourceAdapter?.assemblyNameToPanSN ?? {}) as Record<\n string,\n string\n >\n const names = [\n assemblyName,\n ...(assembly ? [assembly.name, ...assembly.aliases] : []),\n ]\n return {\n name: assemblyName,\n aliases: [...names, ...names.flatMap(n => panSN[n] ?? [])],\n }\n },\n // Whether x lies along the reference the track's graph came with, not a\n // walk \"Draw x along\" picked. An rGFA's backbone is fixed.\n get drawsLoadedReference() {\n const graph = self.graph\n return (\n graph?.anchoredBy === 'tags' ||\n (graph?.referencePath !== undefined &&\n graph.referencePath === self.loadedReferencePath)\n )\n },\n }))\n .views(self => ({\n // the assembly the genes were read for\n get geneAssembly() {\n const region = self.graphRegion\n return region ? self.assemblySpellings(region.assemblyName) : undefined\n },\n // the filter of the gene track's lane in the view the pane draws in\n get geneLaneFilter() {\n let view: object\n try {\n view = getContainingView(self)\n } catch {\n return undefined\n }\n const filters = laneFilters(view, self.geneTrack?.trackId)\n return filters.length\n ? new SerializableFilterChain({\n filters,\n jexl: getEnv(self).pluginManager.jexl,\n })\n : undefined\n },\n // the genes over the cut that the lane admits\n get geneFeatures() {\n const features = self.geneTrackFeatures\n const lane = this.geneLaneFilter\n return features\n ? geneModelsFrom(lane ? features.filter(f => lane.passes(f)) : features)\n : undefined\n },\n }))\n .views(self => ({\n // The genes on the drawn backbone under its own refNames. The track's\n // config puts its reference on the cut's assembly, whatever the walk's\n // name. After \"Draw x along\" another walk, the backbone takes the genes\n // only where its PanSN prefix names their assembly.\n get backboneGenes() {\n const { backbone, geneAssembly, geneFeatures } = self\n const binds =\n self.drawsLoadedReference ||\n (geneAssembly !== undefined &&\n backboneAssembly(backbone, [geneAssembly]) !== undefined)\n return backbone && geneFeatures && binds\n ? featuresOnBackbone(geneFeatures, backbone)\n : undefined\n },\n }))\n .views(self => ({\n get nodeNeighbors() {\n return self.drawnGraph ? buildNeighbors(self.drawnGraph) : undefined\n },\n get nodeInk(): NodeInk {\n return nodeInk(\n self.drawnGraph,\n self.nodeById,\n self.contigThickness,\n self.nodeWidth,\n )\n },\n // Links that skip reference sequence, i.e. the deletions this graph\n // holds. Computed once per graph rather than per geometry rebuild: it is\n // a pass over the edges and the drawing rebuilds on every pan.\n // Walk rows state what each walk skips as its own bar length, so the arcs\n // over the backbone would only say it again, across the bars.\n get allDeletions() {\n return self.graph && this.drawsNodes ? deletionEdges(self.graph) : []\n },\n // One bar per haplotype walk on its own bp axis, each with the allele\n // the picked repeat called for it, before the sample filter. Empty under\n // every other layout.\n get cohortWalkRows() {\n if (self.chosenLayoutMode !== 'walkrows' || !self.graph) {\n return undefined\n }\n const repeat = self.selectedRepeat\n const bars = repeat\n ? walkRows(self.graph, repeat, repeat.unit)\n : self.cutWalkRows\n if (!bars) {\n return undefined\n }\n const [reference, ...rows] = withCalls(\n [bars.reference, ...bars.rows],\n repeat?.calls,\n )\n return { ...bars, reference: reference!, rows }\n },\n // The samples walk rows can show, by name, and those with a walk its\n // call disagrees with, longest walk first\n get walkRowSampleChoices() {\n const rows = this.cohortWalkRows?.rows ?? []\n return {\n samples: [...new Set(rows.map(r => r.sample))].sort(),\n disagreeing: [\n ...new Set(\n rows.filter(r => r.call?.agrees === false).map(r => r.sample),\n ),\n ],\n }\n },\n // The source track's samples TSV, where its adapter names one\n get walkRowSamplesTsv(): FileLocation | undefined {\n const location = self.sourceAdapter?.samplesTsvLocation as\n FileLocation | undefined\n return location && (!('uri' in location) || location.uri)\n ? location\n : undefined\n },\n // The sample table's columns walk rows can group by\n get walkRowGroupFields() {\n return metadataColumns(self.walkRowSampleTable)\n },\n // The filtered rows in a section per value of the grouped column, or\n // undefined while ungrouped or the table lacks that column\n get walkRowGroups() {\n const bars = this.cohortWalkRows\n const table = self.walkRowSampleTable\n const groupBy = self.walkRowGroupBy\n return bars &&\n table &&\n groupBy &&\n this.walkRowGroupFields.includes(groupBy.field)\n ? groupWalkRows(\n filterSamples(bars.rows, self.walkRowSamples),\n table,\n groupBy,\n )\n : undefined\n },\n // The bars the overlay draws: the cohort's, narrowed by the sample\n // filter, and stacked section by section while grouped\n get walkRowBars() {\n const bars = this.cohortWalkRows\n return bars\n ? {\n ...bars,\n rows:\n this.walkRowGroups?.rows ??\n filterSamples(bars.rows, self.walkRowSamples),\n }\n : undefined\n },\n // Whether the canvas draws the graph's nodes. A tube map and walk rows\n // draw a picture of their own over it, so what sits on nodes (genes,\n // bubble halos, deletion arcs, the reference strip) has nowhere to go.\n // Read off what was drawn rather than the mode asked for, which falls\n // back to the force layout on a graph it cannot draw.\n get drawsNodes() {\n return !self.layoutResult?.tubeMap && !this.walkRowBars\n },\n // Exons and names on the nodes that carry them, in layout units. Reads\n // positionsVersion so a dragged node takes its exons with it.\n get genePins() {\n dependOn(self.positionsVersion)\n const positions = self.layoutResult?.nodePositions\n return self.showGenes &&\n this.drawsNodes &&\n self.graph &&\n self.backboneGenes &&\n positions\n ? genePins(self.graph, self.backboneGenes, positions)\n : []\n },\n // The bubbles as halos along their nodes.\n // Reads positionsVersion so a dragged node takes its halo with it.\n get bubbleHalos() {\n dependOn(self.positionsVersion)\n const positions = self.layoutResult?.nodePositions\n if (!self.showBubbles || !this.drawsNodes || !self.graph || !positions) {\n return []\n }\n return bubbleHalos(\n self.graph,\n self.bubbles,\n positions,\n name => self.walkLabel(name),\n self.repeatArrays,\n )\n },\n // Every node's midpoint on the reference plus the interval the hue ramps\n // over \u2014 what `reference-position` paints from, and undefined under every\n // other scheme so the walk is never run for a colouring that ignores it.\n //\n // Here for the same reason `deletions` is, only more so: deriving it is a\n // bounded neighbour walk PER NODE (referenceMidpoints), it depends on\n // nothing the transform touches, and it was being redone inside every\n // geometry rebuild \u2014 1.6 ms at 1.5k nodes, 45 ms at 30k, on a pass that\n // reruns on each debounced pan and each drag frame. `reference-position`\n // is also what `auto` resolves to on any anchored graph, so this was the\n // default path rather than an opt-in one.\n //\n // On the drawn graph, whose ids a folded tube map's boxes carry\n get referenceRamp() {\n return self.effectiveColorScheme === 'reference-position' &&\n self.drawnGraph\n ? computeReferenceRamp(self.drawnGraph, self.rampDomain)\n : undefined\n },\n // The assemblies this view is showing, which is the interface every\n // assembly-aware piece of the app looks for \u2014 `viewTitle` first among\n // them, which falls back through it and otherwise names the view\n // \"Untitled view\". Every published HPRC figure showed that.\n // `launchSubgraphView` only avoids it by writing `displayName`, so a\n // declaratively-instantiated view (a session snapshot, a figure spec) got\n // the fallback.\n //\n // A whole-file import has none: its stable names are a GFA's business and\n // need not name anything the session has loaded. Empty rather than\n // undefined, matching what an LGV with no displayed regions reports.\n get assemblyNames() {\n const region = self.graphRegion\n return region ? [region.assemblyName] : []\n },\n // Screen px per layout unit, per axis. `scale` is the x zoom and the whole\n // of what a user's wheel moves; y is a second question the layout answers\n // for itself.\n //\n // On a row layout the pitch is already in screen px (rowSpacing.ts), so\n // scaleY is 1 and stays 1: rows are a track's row height, unchanged by\n // zoom, and the backbone under them zooms the way the ruler above it does.\n // On an isotropic layout (FMMM) x and y are one simulation space and one\n // number scales both, exactly as before.\n //\n // Everything that mixes the two axes takes their ratio as `yToX`\n // (scaleY / scaleX) \u2014 see computeEdgeCurves.\n get scaleX() {\n return axisScaleOf(self.scale, self.pixelRows).scaleX\n },\n get scaleY() {\n return axisScaleOf(self.scale, self.pixelRows).scaleY\n },\n // The pair, for everything that draws or hit-tests. Handed over as one\n // value on purpose: every consumer needs both, and passing them separately\n // let a caller supply the x scale and default y, which compiles and draws\n // a wrong picture. See AxisScale.\n get axisScale() {\n return axisScaleOf(self.scale, self.pixelRows)\n },\n }))\n .views(self => ({\n get deletionDrawing() {\n return self.graph\n ? deletionDrawing(self.graph, self.allDeletions, self.showDeletionEdges)\n : undefined\n },\n // the deletions drawn, which their labels and hover name\n get deletions() {\n return this.deletionDrawing?.shown ?? []\n },\n get deletionEdgeIndexes() {\n return this.deletionDrawing?.bypassed\n },\n get hiddenEdgeIndexes() {\n return this.deletionDrawing?.hidden\n },\n // The interval the reference-position ramp runs over, for the key beside\n // the drawing, and undefined when no key should be drawn. Two tutorials\n // carry \"red to magenta is left to right of the cut window\" as a sentence\n // in prose because nothing on screen said it.\n //\n // Read off the ramp the drawing is actually painted with rather than\n // re-derived from the domain, so the key cannot come to describe a\n // different interval from the hues beside it \u2014 and so a graph that states\n // no domain, whose interval has to be measured, does not pay for a second\n // neighbour walk to say what the first one already worked out.\n get referenceRampDomain() {\n const ramp = self.referenceRamp\n return ramp\n ? { start: ramp.start, end: ramp.start + ramp.span }\n : undefined\n },\n // The ramp's two colours for nodes off it, as getNodeColor paints them:\n // charcoal where an rGFA rank puts a node off the reference, grey where\n // a node has no reference position at all. A tube map draws the window\n // alone (trimToWindow), so there only the boxes it drew count.\n get referenceRampOffKeys() {\n const ramp = self.referenceRamp\n const layout = self.layoutResult\n const drawn = layout?.tubeMap ? layout.nodePositions : undefined\n let offReference = false\n let unplaced = false\n if (ramp && self.drawnGraph) {\n for (const node of self.drawnGraph.nodes) {\n if (drawn && !drawn[node.id]) {\n continue\n }\n if (!ramp.midpoints.has(node.id)) {\n unplaced = true\n } else if (node.stable && node.stable.rank > 0) {\n offReference = true\n }\n }\n }\n return { offReference, unplaced }\n },\n // Each tube map box in its node's colour, where the scheme paints one\n get tubeMapNodeColors() {\n const graph = self.drawnGraph\n return self.layoutResult?.tubeMap && graph\n ? tubeMapNodeColors(\n graph,\n self.effectiveColorScheme,\n self.referenceRamp,\n )\n : undefined\n },\n // Beside tinted boxes the tubes step through greys, as they do beside\n // reads, so no tube shares a box's hue\n get tubeMapTubeColors() {\n const colors = self.layoutResult?.tubeMap?.pathColors\n const tubes =\n colors && this.tubeMapNodeColors\n ? colors.map((_, i) => pathGreyCssColor(i, colors.length))\n : colors\n const hovered = new Set(self.hoveredRowWalks)\n const paths = self.drawnGraph?.paths\n return tubes && paths && hovered.size > 0\n ? tubes.map((color, i) =>\n hovered.has(paths[i]?.name ?? '') ? color : LIFT_BACKDROP_CSS,\n )\n : tubes\n },\n // A node's reference interval, an allele's between its flanks\n nodeSpan(nodeId: string) {\n const { nodeById, nodeNeighbors: neighbors } = self\n return nodeById && neighbors\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n },\n }))\n .views(self => ({\n // Which haplotype each ribbon colour belongs to, in the order the file\n // states the paths \u2014 the same list and the same order the geometry keys\n // its colours off, so the key cannot name a colour that is not drawn.\n // Empty unless the ribbons are actually on: a colour key beside a drawing\n // with no colours in it is a legend for nothing.\n // The tube map colours its tubes whether or not paths are drawn on the\n // nodes, so under it the key follows the tubes, and names the colours\n // the tubes were drawn in.\n get pathLegend() {\n const paths = self.graph?.paths\n const tubeMap = self.layoutResult?.tubeMap\n const colouring = self.drawPaths || tubeMap\n return colouring && paths && pathColorsLegible(paths.length)\n ? pathLegend(paths, self.tubeMapTubeColors)\n : []\n },\n // The reference interval under the pointer: the hovered node's, or the\n // hovered bubble's\n get hoveredSpan() {\n const nodeId = self.hoveredNode\n const bubble = self.hoveredBubble\n return nodeId !== null\n ? self.nodeSpan(nodeId)\n : bubble\n ? { start: bubble.start, end: bubble.end }\n : undefined\n },\n }))\n .views(self => ({\n // The hovered span, for a connected linear view to highlight. Only a\n // graph cut from a track has one: a whole-file import has no region, and\n // its stable names need not name anything in a loaded assembly.\n get hoverHighlight() {\n const region = self.graphRegion\n const span = self.hoveredSpan\n return region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n ...span,\n }\n : undefined\n },\n }))\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getSession } from '@jbrowse/core/util'\n\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nexport interface AssemblyAliases {\n name: string\n aliases: string[]\n}\n\n// Only `sample#haplotype`, the spelling gbz-base gives a walk's prefix. A bare\n// alias is indistinguishable from an ordinary one (hg38's `GRCh38`) and would\n// replace the identity mapping that already resolves an assembly named as its\n// sample; at sample depth it would also claim both of a diploid's walks, since\n// `panSNMatchesPrefix` matches `HG002` against `HG002#1` and `HG002#2`. Three\n// parts name a contig, not a haplotype.\nconst PANSN_HAPLOTYPE = /^[^#]+#\\d+$/\n\n// The config's `assemblyNameToPanSN` with each assembly's PanSN alias added\n// beneath it: an entry wins for its assembly and for its prefix. Unchanged when\n// no alias qualifies, so such a track keeps its adapter cache key.\nexport function withPanSNAliases(\n adapterConfig: Record<string, unknown>,\n assemblies: AssemblyAliases[],\n) {\n const explicit = (adapterConfig.assemblyNameToPanSN ?? {}) as Record<\n string,\n string\n >\n const claimed = new Set(Object.values(explicit))\n const fromAliases: Record<string, string> = {}\n for (const { name, aliases } of assemblies) {\n const prefix = aliases.find(alias => PANSN_HAPLOTYPE.test(alias))\n if (prefix !== undefined && !claimed.has(prefix)) {\n fromAliases[name] = prefix\n }\n }\n return Object.keys(fromAliases).length === 0\n ? adapterConfig\n : {\n ...adapterConfig,\n assemblyNameToPanSN: { ...fromAliases, ...explicit },\n }\n}\n\n/**\n * A track's adapter config as its requests carry it. A worker has no assembly\n * manager, so a gbz-base track's lanes learn the session's PanSN aliases here.\n */\nexport function trackAdapterConfig(\n node: IAnyStateTreeNode,\n track: AnyConfigurationModel,\n) {\n const adapterConfig = readConfObject(track, 'adapter') as Record<\n string,\n unknown\n >\n return adapterConfig.type === 'GbzBaseSyntenyAdapter'\n ? withPanSNAliases(\n adapterConfig,\n getSession(node).assemblyManager.assemblyList.map(conf => ({\n name: readConfObject(conf, 'name') as string,\n aliases: (readConfObject(conf, 'aliases') ?? []) as string[],\n })),\n )\n : adapterConfig\n}\n", "// src/genes/geneFiles.ts\nvar GENE_TYPE = /(gene|gene_segment|RNA|transcript)$/i;\nvar isGene = (type) => GENE_TYPE.test(type) || type === \"CDS\" || type === \"exon\";\nfunction mergedIntervals(intervals) {\n const out = [];\n for (const iv of [...intervals].sort((a, b) => a.start - b.start)) {\n const last = out.at(-1);\n if (last && iv.start <= last.end) {\n last.end = Math.max(last.end, iv.end);\n } else {\n out.push({ ...iv });\n }\n }\n return out;\n}\nfunction strandOf(s) {\n return s === \"+\" ? 1 : s === \"-\" ? -1 : 0;\n}\nfunction unescape(value) {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\nfunction attributes(column) {\n const out = /* @__PURE__ */ new Map();\n for (const pair of column.split(\";\")) {\n const eq = pair.indexOf(\"=\");\n if (eq > 0) {\n out.set(pair.slice(0, eq).trim(), unescape(pair.slice(eq + 1).trim()));\n }\n }\n return out;\n}\nfunction gff3Row(line) {\n const cols = line.split(\"\t\");\n const start = Number(cols[3]);\n const end = Number(cols[4]);\n if (cols.length < 9 || !Number.isInteger(start) || !Number.isInteger(end)) {\n return void 0;\n }\n return {\n refName: cols[0],\n type: cols[2],\n start: start - 1,\n end,\n strand: strandOf(cols[6]),\n attrs: attributes(cols[8])\n };\n}\nfunction genesFromGff3Lines(lines) {\n const rows = [];\n for (const line of lines) {\n if (line.startsWith(\"##FASTA\")) {\n break;\n }\n const row = line.startsWith(\"#\") ? void 0 : gff3Row(line);\n if (row) {\n rows.push(row);\n }\n }\n const parentOf = /* @__PURE__ */ new Map();\n for (const { attrs } of rows) {\n const id = attrs.get(\"ID\");\n const parent = attrs.get(\"Parent\")?.split(\",\")[0];\n if (id && parent) {\n parentOf.set(id, parent);\n }\n }\n const rootOf = (row) => {\n let id = row.attrs.get(\"Parent\")?.split(\",\")[0] ?? row.attrs.get(\"ID\");\n if (!id) {\n return row.attrs.get(\"gene_id\");\n }\n const seen = /* @__PURE__ */ new Set();\n while (id && parentOf.has(id) && !seen.has(id)) {\n seen.add(id);\n id = parentOf.get(id);\n }\n return id;\n };\n const groups = /* @__PURE__ */ new Map();\n rows.forEach((row, i) => {\n const root = rootOf(row) ?? `#${i}`;\n const key = `${row.refName}\t${root}`;\n const group = groups.get(key) ?? groups.set(key, { rows: [] }).get(key);\n group.rows.push(row);\n if (!row.attrs.has(\"Parent\") && !group.top) {\n group.top = row;\n }\n });\n const genes = [];\n for (const [key, { top, rows: rows2 }] of groups) {\n if (top && !isGene(top.type)) {\n continue;\n }\n const first = top ?? rows2[0];\n const start = top?.start ?? Math.min(...rows2.map((r) => r.start));\n const end = top?.end ?? Math.max(...rows2.map((r) => r.end));\n const a = first.attrs;\n const spans = (type) => rows2.filter((r) => r.type === type).map((r) => ({ start: r.start, end: r.end }));\n const exons = spans(\"exon\");\n const coding = spans(\"CDS\");\n const transcribed = rows2.some(\n (r) => r !== top && r.type !== \"exon\" && r.type !== \"CDS\"\n );\n genes.push({\n name: a.get(\"Name\") ?? a.get(\"gene_name\") ?? a.get(\"gene\") ?? a.get(\"gene_id\") ?? key.split(\"\t\")[1],\n refName: first.refName,\n start,\n end,\n strand: first.strand,\n // A range read holds only the rows over its window, so a gene with\n // transcripts but no exon or CDS there is intronic in it. Only a gene\n // with no transcripts, as a bacterium's gene and CDS, is one exon.\n exons: exons.length ? mergedIntervals(exons) : transcribed ? mergedIntervals(coding) : [{ start, end }]\n });\n }\n return genes;\n}\nfunction mergeOverlappingByName(genes) {\n const out = [];\n const open = /* @__PURE__ */ new Map();\n for (const g of [...genes].sort((a, b) => a.start - b.start)) {\n const key = `${g.refName}\t${g.strand}\t${g.name}`;\n const last = open.get(key);\n if (last && g.start < last.end) {\n last.end = Math.max(last.end, g.end);\n last.exons = mergedIntervals([...last.exons, ...g.exons]);\n } else {\n const gene = { ...g, exons: mergedIntervals(g.exons) };\n out.push(gene);\n open.set(key, gene);\n }\n }\n return out;\n}\nfunction genesFromBed(text) {\n const rows = [];\n for (const line of text.split(\"\\n\")) {\n const cols = line.replace(/\\r$/, \"\").split(\"\t\");\n const start = Number(cols[1]);\n const end = Number(cols[2]);\n if (/^(#|track|browser)/.test(line) || cols.length < 3 || !Number.isInteger(start) || !(end > start)) {\n continue;\n }\n const refName = cols[0];\n const name = cols[3] && cols[3] !== \".\" ? cols[3] : `${refName}:${start + 1}-${end}`;\n const sizes = cols[10]?.split(\",\").filter((s) => s !== \"\").map(Number);\n const starts = cols[11]?.split(\",\").filter((s) => s !== \"\").map(Number);\n const blocks = sizes?.length && sizes.length === starts?.length ? sizes.map((size, i) => ({\n start: start + starts[i],\n end: start + starts[i] + size\n })) : [{ start, end }];\n rows.push({\n name,\n refName,\n start,\n end,\n strand: strandOf(cols[5]),\n exons: blocks\n });\n }\n return mergeOverlappingByName(rows);\n}\nfunction genesFromText(text) {\n const first = text.split(\"\\n\", 1e3).find((l) => l.trim() !== \"\" && !/^(#|track|browser)/.test(l));\n const cols = first?.split(\"\t\") ?? [];\n return /^\\d+$/.test(cols[1] ?? \"\") && /^\\d+$/.test(cols[2] ?? \"\") ? genesFromBed(text) : genesFromGff3Lines(text.split(/\\r?\\n/));\n}\n\nexport {\n mergedIntervals,\n genesFromGff3Lines,\n mergeOverlappingByName,\n genesFromBed,\n genesFromText\n};\n", "import { mergeOverlappingByName } from '@jbrowse/bandage-core/genes/geneFiles'\nimport { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { Feature } from '@jbrowse/core/util'\n\n// The adapters whose tracks hold gene models, in the order the session's\n// tracks are searched when no track is named.\nexport const GENE_ADAPTER_TYPES = new Set([\n 'Gff3TabixAdapter',\n 'Gff3Adapter',\n 'BedTabixAdapter',\n 'BedAdapter',\n 'GtfTabixAdapter',\n 'GtfAdapter',\n 'BigBedAdapter',\n 'NCListAdapter',\n])\n\nconst GENE_TRACK_HINT = /gene|refseq|gencode|ensembl|annotation/i\n\n// A BED track is as often peaks or repeats as genes, so one counts only where\n// its name says it is annotation\nconst BED_ADAPTER_TYPES = new Set(['BedTabixAdapter', 'BedAdapter'])\n\n// Which of the session's tracks to read genes from: the named one, else the\n// first gene-bearing track on the assembly whose name says it is annotation,\n// else the first non-BED gene-bearing track.\nexport function pickGeneTrack<\n T extends { trackId: string; name?: string; adapterType: string },\n>(tracks: T[], named: string) {\n if (named) {\n return tracks.find(t => t.trackId === named)\n }\n const candidates = tracks.filter(t => GENE_ADAPTER_TYPES.has(t.adapterType))\n return (\n candidates.find(t =>\n GENE_TRACK_HINT.test(`${t.trackId} ${t.name ?? ''}`),\n ) ?? candidates.find(t => !BED_ADAPTER_TYPES.has(t.adapterType))\n )\n}\n\ninterface LaneView {\n tracks?: readonly {\n configuration: AnyConfigurationModel\n displays: readonly { configuration: AnyConfigurationModel }[]\n }[]\n}\n\n// The `filter` of the gene track's lane in the view the graph is drawn in, so\n// the chips name what the lane draws. None where the view shows no such lane,\n// or has no tracks, as a graph genome view of its own.\nexport function laneFilters(view: object, trackId: string | undefined) {\n const lane = (view as LaneView).tracks?.find(\n t => readConfObject(t.configuration, 'trackId') === trackId,\n )?.displays[0]\n return lane\n ? ((readConfObject(lane.configuration, 'filter') as string[] | undefined) ??\n [])\n : []\n}\n\n// Records spanning a whole sequence, the types the GFF3 adapter declines to\n// widen a fetch for. RefSeq opens every molecule with a `region` named\n// ANONYMOUS.\nconst WHOLE_SEQUENCE_TYPES = new Set([\n 'chromosome',\n 'region',\n 'contig',\n 'supercontig',\n 'scaffold',\n])\n\ntype FeatureLike = Feature | Record<string, unknown>\n\nfunction field(f: FeatureLike, name: string): unknown {\n return typeof (f as Feature).get === 'function'\n ? (f as Feature).get(name)\n : (f as Record<string, unknown>)[name]\n}\n\n// JBrowse's BED parser splits a coding BED12 block into CDS and UTR parts and\n// keeps `exon` for non-coding ones, so all of them are exon\nconst EXON_PARTS = new Set([\n 'exon',\n 'CDS',\n 'five_prime_UTR',\n 'three_prime_UTR',\n 'UTR',\n])\n\nfunction exonsOf(f: FeatureLike, into: { start: number; end: number }[]) {\n const type = field(f, 'type')\n if (typeof type === 'string' && EXON_PARTS.has(type)) {\n into.push({\n start: field(f, 'start') as number,\n end: field(f, 'end') as number,\n })\n }\n const children = field(f, 'subfeatures') as FeatureLike[] | undefined\n for (const child of children ?? []) {\n exonsOf(child, into)\n }\n}\n\nfunction merged(intervals: { start: number; end: number }[]) {\n const sorted = [...intervals].sort((a, b) => a.start - b.start)\n const out: { start: number; end: number }[] = []\n for (const iv of sorted) {\n const last = out.at(-1)\n if (last && iv.start <= last.end) {\n last.end = Math.max(last.end, iv.end)\n } else {\n out.push({ ...iv })\n }\n }\n return out\n}\n\n// Genes from a track's features: every top-level feature but a whole-sequence\n// record, named by the first of gene_name, name, gene and gene_id it carries,\n// with the exons found anywhere under it merged. A feature with no exons is one exon,\n// its whole span. A BED track gives one feature per transcript, so a name's\n// overlapping features merge, while its copies down the contig stay apart.\n// UCSC's ncbiRefSeq.gff gene records carry their symbol only as gene_id. A\n// feature with none of those names is left out: its raw ID, RefSeq's\n// `id-NC_000913.3:1978503..1979270`, only restates where it is.\nexport function geneModelsFrom(features: FeatureLike[]): GeneModel[] {\n const genes: GeneModel[] = []\n for (const f of features) {\n const name =\n (field(f, 'gene_name') as string | undefined) ??\n (field(f, 'name') as string | undefined) ??\n (field(f, 'gene') as string | undefined) ??\n (field(f, 'gene_id') as string | undefined)\n const start = field(f, 'start') as number\n const end = field(f, 'end') as number\n if (\n !name ||\n !(end > start) ||\n WHOLE_SEQUENCE_TYPES.has(field(f, 'type') as string)\n ) {\n continue\n }\n const exons: { start: number; end: number }[] = []\n exonsOf(f, exons)\n genes.push({\n name,\n refName: field(f, 'refName') as string,\n start,\n end,\n strand: (field(f, 'strand') as number | undefined) ?? 0,\n exons: exons.length ? merged(exons) : [{ start, end }],\n })\n }\n return mergeOverlappingByName(genes)\n}\n", "import type { Feature } from '@jbrowse/core/util'\n\nexport interface RepeatCall {\n bp: number\n // TRGT's `SD`. Zero means the allele is a copy of the one the reads did\n // support, so its length states nothing about a second haplotype; absent\n // where the genotyper writes no such field.\n spanningReads?: number\n // the PanSN haplotype a phased genotype puts this allele on\n haplotype?: number\n}\n\n// A tandem repeat array as the walk rows need it: its span on the reference,\n// which is what the bars measure between, and its unit length, which is what\n// they tile by. Read off whatever repeat annotation the session has, since the\n// tools all state the same two facts under different names: VCF 4.5's\n// `<CNV:TR>` allele gives `RUL` and `RUS` (one entry per repeat sequence,\n// grouped by `RN`), UCSC simpleRepeat and TRF give `period` and the consensus\n// `sequence`, TRGT gives `MOTIFS` and `TRID`, ExpansionHunter `RU` and `REPID`,\n// HipSTR and GangSTR `PERIOD`, vamos its `motifs`. A VCF record's INFO is\n// searched as well as its top level, and a list's first entry is the unit the\n// bars tile by: for a compound array that is the first repeat sequence, which\n// is the expanding one at every such locus in the common catalogues.\nexport interface RepeatArray {\n key: string\n name: string\n refName: string\n start: number\n end: number\n unit: number\n motif?: string\n // Each sample's genotyped alleles, from a genotyper's per-sample `AL`\n // (TRGT) or a genotype over VCF 4.5 <CNV:TR> alleles; absent from a\n // catalogue.\n calls?: Record<string, RepeatCall[]>\n}\n\nexport const REPEAT_ADAPTER_TYPES = new Set([\n 'BedAdapter',\n 'BedTabixAdapter',\n 'BigBedAdapter',\n 'VcfAdapter',\n 'VcfTabixAdapter',\n])\n\nconst REPEAT_TRACK_HINT =\n /repeat|tandem|\\bstr\\b|vntr|trf|trgt|vamos|expansion|microsat/i\n\nexport function pickRepeatTrack<\n T extends { trackId: string; name?: string; adapterType: string },\n>(tracks: T[], named: string) {\n if (named) {\n return tracks.find(t => t.trackId === named)\n }\n const candidates = tracks.filter(t => REPEAT_ADAPTER_TYPES.has(t.adapterType))\n return candidates.find(t =>\n REPEAT_TRACK_HINT.test(`${t.trackId} ${t.name ?? ''}`),\n )\n}\n\ntype FeatureLike = Feature | Record<string, unknown>\n\nfunction own(f: FeatureLike, name: string): unknown {\n return typeof (f as Feature).get === 'function'\n ? (f as Feature).get(name)\n : (f as Record<string, unknown>)[name]\n}\n\n// A TRGT repeat catalogue is a BED whose name column packs the record:\n// `ID=HTT;MOTIFS=CAG,CCG;STRUC=(CAG)nCAACAG(CCG)n`. Read as fields when it\n// has that shape.\nconst PACKED_NAME = /^\\w+=[^;]*(;\\w+=[^;]*)*$/\n\nfunction packedName(f: FeatureLike) {\n const name = own(f, 'name')\n if (typeof name !== 'string' || !PACKED_NAME.test(name)) {\n return undefined\n }\n return Object.fromEntries(\n name.split(';').map(pair => {\n const i = pair.indexOf('=')\n return [pair.slice(0, i), pair.slice(i + 1)]\n }),\n )\n}\n\n// A field at the feature's top level, in a VCF record's INFO, or in a packed\n// name column, in that order.\nfunction field(f: FeatureLike, name: string): unknown {\n const top = own(f, name)\n if (top !== undefined) {\n return top\n }\n const info = own(f, 'INFO') as Record<string, unknown> | undefined\n return info?.[name] ?? packedName(f)?.[name]\n}\n\nconst MOTIF_FIELDS = [\n 'RUS',\n 'MOTIFS',\n 'RU',\n 'motifs',\n 'motif',\n 'sequence',\n 'consensus',\n]\nconst PERIOD_FIELDS = [\n 'RUL',\n 'period',\n 'PERIOD',\n 'consensusSize',\n 'unit',\n 'unitLength',\n]\nconst NAME_FIELDS = ['TRID', 'REPID', 'VARID', 'ID', 'name', 'id']\n\n// The first entry of a list-valued field, whether it arrived parsed or as\n// the comma-joined text a VCF INFO or a BED column holds; VCF's missing \".\"\n// counts as absent.\nfunction first(f: FeatureLike, names: string[]) {\n for (const name of names) {\n const value = field(f, name)\n const one = String((Array.isArray(value) ? value[0] : value) ?? '')\n .split(',')[0]!\n .trim()\n if (one !== '' && one !== '.') {\n return one\n }\n }\n return undefined\n}\n\nconst IUPAC = /^[ACGTURYSWKMBDHVN]+$/i\n\n// The unit in bp: a stated period, else the length of the first motif.\nexport function repeatUnitOf(f: FeatureLike) {\n const period = Number(first(f, PERIOD_FIELDS))\n if (Number.isFinite(period) && period > 0) {\n return Math.round(period)\n }\n const motif = first(f, MOTIF_FIELDS)\n return motif && IUPAC.test(motif) ? motif.length : undefined\n}\n\n// A per-sample list field, parsed or as the comma-joined text a VCF column\n// holds. A missing entry stays missing: read as 0, an absent `SD` would make\n// every allele of every genotyper that writes no such field unspanned.\nfunction numbers(value: unknown) {\n const raw: unknown[] = Array.isArray(value)\n ? value\n : String(value ?? '').split(',')\n return raw.map(one => {\n const n =\n one === '' || one === null || one === undefined ? NaN : Number(one)\n return Number.isFinite(n) ? n : undefined\n })\n}\n\nfunction strings(value: unknown) {\n const raw: unknown[] = Array.isArray(value)\n ? value\n : String(value ?? '').split(',')\n return raw.map(one => {\n const text = String(one ?? '').trim()\n return text === '' || text === '.' ? undefined : text\n })\n}\n\nconst TANDEM_REPEAT = '<CNV:TR>'\n\n// Each ALT allele's length, off VCF 4.5's flattened list-of-lists: RN says how\n// many RUS/RUL/RUC/RB entries each allele takes, and the allele's bases are\n// its runs' RB, or unit length times count where RB is missing. An allele that\n// is not <CNV:TR>, or has a run stating neither, has none.\nfunction tandemAlleleBp(f: FeatureLike) {\n const alts = strings(own(f, 'ALT'))\n if (!alts.includes(TANDEM_REPEAT)) {\n return undefined\n }\n const rn = numbers(field(f, 'RN'))\n const rus = strings(field(f, 'RUS'))\n const rul = numbers(field(f, 'RUL'))\n const ruc = numbers(field(f, 'RUC'))\n const rb = numbers(field(f, 'RB'))\n let k = 0\n return alts.map((alt, i) => {\n const n = rn[i] ?? (alt === TANDEM_REPEAT ? 1 : 0)\n let bp = 0\n let known = 0\n for (let j = 0; j < n; j++, k++) {\n const motif = rus[k]\n const unitLength =\n rul[k] ?? (motif && IUPAC.test(motif) ? motif.length : undefined)\n const count = ruc[k]\n const runBp =\n rb[k] ??\n (unitLength && count !== undefined\n ? Math.round(unitLength * count)\n : undefined)\n if (runBp !== undefined) {\n bp += runBp\n known++\n }\n }\n return alt === TANDEM_REPEAT && n > 0 && known === n ? bp : undefined\n })\n}\n\n// A sample's alleles through its genotype: 0 is the reference's, an index\n// past it the ALT allele's. A phased genotype's k-th allele is PanSN\n// haplotype k, the order vg deconstruct writes an assembly's haplotypes in.\nfunction genotyped(\n gt: string | undefined,\n alleleBp: (number | undefined)[],\n referenceBp: number,\n) {\n const phased = gt?.includes('|')\n return (gt ?? '').split(/[/|]/).flatMap((index, k): RepeatCall[] => {\n const i = Number(index)\n const bp = i > 0 ? alleleBp[i - 1] : referenceBp\n if (!Number.isInteger(i) || bp === undefined) {\n return []\n }\n return [{ bp, ...(phased ? { haplotype: k + 1 } : {}) }]\n })\n}\n\nfunction callsOf(\n f: FeatureLike,\n alleleBp: (number | undefined)[] | undefined,\n referenceBp: number,\n) {\n const samples = own(f, 'samples') as\n Record<string, Record<string, unknown>> | undefined\n const called: Record<string, RepeatCall[]> = {}\n for (const [sample, fields] of Object.entries(samples ?? {})) {\n const reads = numbers(fields.SD)\n const lengths = numbers(fields.AL).flatMap((bp, i) =>\n bp !== undefined && bp > 0\n ? [reads[i] === undefined ? { bp } : { bp, spanningReads: reads[i] }]\n : [],\n )\n const calls =\n lengths.length > 0 || !alleleBp\n ? lengths\n : genotyped(strings(fields.GT)[0], alleleBp, referenceBp)\n if (calls.length > 0) {\n called[sample] = calls\n }\n }\n return Object.keys(called).length > 0 ? called : undefined\n}\n\n// A <CNV:TR> record's POS is the base before the array and SVLEN the\n// reference allele's length, while a VCF feature starts at that padding base.\nfunction spanOf(f: FeatureLike, tandem: boolean) {\n const start = field(f, 'start') as number\n const end = field(f, 'end') as number\n const svlen = numbers(field(f, 'SVLEN'))[0]\n return tandem && svlen !== undefined\n ? { start: start + 1, end: start + 1 + svlen }\n : { start, end }\n}\n\nexport function repeatArraysFrom(features: FeatureLike[]): RepeatArray[] {\n const arrays: RepeatArray[] = []\n for (const f of features) {\n const alleleBp = tandemAlleleBp(f)\n const { start, end } = spanOf(f, alleleBp !== undefined)\n const unit = repeatUnitOf(f)\n if (!(end > start) || unit === undefined) {\n continue\n }\n const refName = field(f, 'refName') as string\n const motif = first(f, MOTIF_FIELDS)\n const stated = first(f, NAME_FIELDS)\n arrays.push({\n key: `${refName}:${start}-${end}`,\n name:\n (stated && !PACKED_NAME.test(stated) ? stated : undefined) ??\n (motif && motif.length <= 12\n ? `(${motif})n`\n : `${refName}:${(start + 1).toLocaleString()}-${end.toLocaleString()}`),\n refName,\n start,\n end,\n unit,\n motif,\n calls: callsOf(f, alleleBp, end - start),\n })\n }\n return arrays.sort((a, b) => a.start - b.start)\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport { locLabel, locString } from './contributors'\nimport { linearViewTarget } from './linearViewTarget'\n\nimport type { Contributor, GraphLocation } from './contributors'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface TrackScanSession {\n tracks: AnyConfigurationModel[]\n assemblies: AnyConfigurationModel[]\n // optional, as a hand-built session in a test has none\n assemblyManager?: {\n has: (name: string) => boolean\n get: (name: string) => { name: string } | undefined\n }\n}\n\n// A track may name an assembly by an alias, and contributors are resolved to\n// canonical names. `has` before `get`, as assemblyResolver does: `get` asks\n// every plugin to go supply a name it does not know.\nexport function canonicalAssemblyName(session: TrackScanSession, name: string) {\n const manager = session.assemblyManager\n return manager?.has(name) ? (manager.get(name)?.name ?? name) : name\n}\n\nexport interface GraphLaunchSession extends TrackScanSession {\n addView: (type: string, snapshot?: Record<string, unknown>) => { id: string }\n // The session's own loader for a view whose state model is registered\n // lazily (JBrowse 4's LinearSyntenyView); absent on an older core, where\n // addView is enough\n launchView?: (\n type: string,\n snapshot?: Record<string, unknown>,\n ) => Promise<{ id: string }>\n assemblyNames: string[]\n views: unknown[]\n // optional, as a hand-built session in a test has none\n notifyError?: (message: string, error?: unknown) => void\n // a highlight every linear view on its assembly draws\n addHighlight?: (highlight: {\n refName: string\n start: number\n end: number\n assemblyName: string\n }) => void\n}\n\n// A launch is a promise nothing waits on. Let go, a refusal moved nothing and\n// said nothing; this is where it is told to the user instead.\nfunction reportFailure(\n session: GraphLaunchSession,\n what: string,\n launch: Promise<unknown>,\n) {\n launch.catch((error: unknown) => {\n console.error(`[GraphGenomeView] ${what}`, error)\n session.notifyError?.(`${what}: ${error}`, error)\n })\n}\n\n// A node is often shorter than a line of text \u2014 a base-level allele can be a\n// handful of bp \u2014 and a linear view opened on exactly that span shows the span\n// and no context at all. Padding to a minimum window puts the node in the middle\n// of something readable.\nconst MIN_LAUNCH_SPAN_BP = 1000\n\nexport function paddedLocation(\n loc: GraphLocation,\n minSpan = MIN_LAUNCH_SPAN_BP,\n): GraphLocation {\n const pad = Math.max(0, Math.ceil((minSpan - (loc.end - loc.start)) / 2))\n return { ...loc, start: Math.max(0, loc.start - pad), end: loc.end + pad }\n}\n\n// Restate the rank-0 contributor in the terms of the region the graph was cut\n// from. Two separate corrections, both required:\n//\n// - the *assembly*. A backbone segment's SN is the graph's own spelling of the\n// reference, which need not be the name of any loaded assembly: the HPRC\n// graph says `GRCh38#0#chr6` in a session whose assembly is `hg38`. Taking\n// the PanSN sample there resolves to nothing and the graph offers no way out\n// at all. The cut region is authoritative \u2014 the adapter resolved that\n// assembly to that stable sequence to cut the subgraph in the first place.\n// The backbone's `haplotype` (`GRCh38#0`) goes with it, since\n// resolveLocationAssembly tries that before the sample.\n// - the *locus*. The cut region is what the user framed in the linear view, and\n// it is the span every other panel of a synteny launch is compared against;\n// the union of backbone segments differs from it whenever the window ends\n// inside a bubble.\n//\n// A subgraph is cut on one reference, so there is at most one rank-0\n// contributor. Must run before contributors are resolved against the session's\n// assemblies, or the reference is filtered out by the name this replaces.\nexport function withReferenceRegion(\n contributors: Contributor[],\n region:\n | { refName: string; assemblyName: string; start: number; end: number }\n | undefined,\n): Contributor[] {\n return region\n ? contributors.map(c =>\n c.rank === 0\n ? {\n ...c,\n sample: region.assemblyName,\n haplotype: undefined,\n refName: region.refName,\n start: region.start,\n end: region.end,\n }\n : c,\n )\n : contributors\n}\n\n// Show a location in a linear view: move the one already on screen if there is\n// one to move, open a pane only if there isn't.\n//\n// This is the difference between \"flip to the linear view\" and \"accumulate\n// panes\". The pangenome sessions this ships in are a linear view above a graph,\n// and there the answer to \"where is this node?\" should be that the linear view\n// scrolls to it \u2014 see linearViewTarget for which view counts as the one to move.\n//\n// `tracks` is only applied to a view being created; a view already open keeps\n// whatever the user has turned on. Returns the id of the view that ended up\n// showing the location, so the graph can pair with it for the hover sync.\nexport function showInLinearView({\n session,\n location,\n assembly,\n connectedViewId,\n tracks = [],\n}: {\n session: GraphLaunchSession\n location: GraphLocation\n assembly: string\n connectedViewId?: string\n tracks?: string[]\n}) {\n const existing = linearViewTarget({\n views: session.views,\n connectedViewId,\n assemblyName: assembly,\n })\n let viewId: string\n if (existing) {\n reportFailure(\n session,\n `Could not show ${assembly} ${locLabel(location)}`,\n Promise.resolve(existing.navToLocString(locString(location), assembly)),\n )\n viewId = existing.id\n } else {\n viewId = session.addView('LinearGenomeView', {\n displayName: `${assembly} \u2014 ${locLabel(location)}`,\n init: { assembly, loc: locString(location), tracks },\n }).id\n }\n return viewId\n}\n\n// Mark where a node sits on the reference, in the linear view already on\n// screen, instead of scrolling that view to it. Review: \"need to be able to\n// just highlight lineargenomeview coords\".\n//\n// The other half of the pair above, and the half that survives being let go of:\n// hover sync draws a band for as long as the pointer is over the node, where a\n// highlight is written into the session's list and stays until it is removed.\n// It also keeps the reader's frame \u2014 the interesting comparison at a pangenome\n// locus is usually the whole window, not the 200 bp the node occupies.\n//\n// Nothing to mark when no linear view on that assembly is ours to move (see\n// linearViewTarget); the caller offers the item only when there is.\nexport function highlightInLinearView({\n session,\n location,\n assembly,\n connectedViewId,\n}: {\n session: GraphLaunchSession\n location: GraphLocation\n assembly: string\n connectedViewId?: string\n}) {\n const target = linearViewTarget({\n views: session.views,\n connectedViewId,\n assemblyName: assembly,\n })\n if (target) {\n session.addHighlight?.({\n refName: location.refName,\n start: location.start,\n end: location.end,\n assemblyName: assembly,\n })\n }\n return target !== undefined\n}\n\n// Which assemblies a track config says it covers, for deciding whether a panel\n// can draw it at all. A trackId naming nothing in the session reads as covering\n// nothing, so a stale id drops the lane rather than adding one the panel would\n// fail to load.\nfunction assemblyNamesOfTrack(\n session: GraphLaunchSession,\n trackId: string | undefined,\n) {\n if (trackId === undefined) {\n return []\n }\n const track = session.tracks.find(\n t => readConfObject(t, 'trackId') === trackId,\n )\n const names: unknown = track ? readConfObject(track, 'assemblyNames') : []\n return Array.isArray(names)\n ? names\n .filter(n => typeof n === 'string')\n .map(n => canonicalAssemblyName(session, n))\n : []\n}\n\n// One panel per contributing assembly, each framed on the locus that assembly\n// contributes here, with the graph's own reference panel on top.\n//\n// The panel loci come from the graph rather than from the synteny track: rGFA\n// states where each contributor's sequence sits on its own coordinates, so the\n// launch needs no mate discovery, no PAF lookup and no dialog. That is the whole\n// point of launching from the graph instead of from a linear view.\n//\n// Panels carry THE GRAPH'S OWN TRACK and nothing else, which is a narrower rule\n// than the single-view launch's (see launchTracks, which scans the session for\n// the assembly's annotation). Tried that here: a gene track per panel takes\n// about 160px of a row that is otherwise a ruler, so on five strains the\n// annotation is most of the viewport and the ribbons \u2014 the thing the launch\n// exists to draw \u2014 are squeezed into the gaps, and `collapseEmptyRows` is here\n// to prevent exactly that.\n//\n// The graph's own track does not have that shape. It goes only in the panels\n// whose assembly its config declares, which is where the graph HAS coordinates:\n// the HPRC segments track names two, so both its panels get one lane, while the\n// E. coli one names K12 alone and a five-strain launch adds a single lane rather\n// than five. And it is the lane that makes the band readable, since the ribbons\n// otherwise connect two bare rulers and the reader has nothing to match across\n// them.\nexport function launchSyntenyView({\n session,\n contributors,\n trackId,\n graphTrackId,\n}: {\n session: GraphLaunchSession\n contributors: Contributor[]\n trackId?: string\n graphTrackId?: string\n}) {\n const graphTrackAssemblies = assemblyNamesOfTrack(session, graphTrackId)\n // The panels the chosen track aligns, in the order given. A pairwise track is\n // offered beside an all-vs-all, two assemblies being a synteny view, and over\n // every contributor it sat on each level and could draw on one at most. A\n // track that states no assemblies keeps them all.\n const aligned = assemblyNamesOfTrack(session, trackId)\n const covered = contributors.filter(c => aligned.includes(c.sample))\n const panels = covered.length >= 2 ? covered : contributors\n const snapshot = {\n init: {\n views: panels.map(c => ({\n assembly: c.sample,\n loc: locString(c),\n ...(graphTrackId !== undefined &&\n graphTrackAssemblies.includes(c.sample)\n ? { tracks: [graphTrackId] }\n : {}),\n })),\n // One entry per LEVEL, not one for the track. `init.tracks` is 2D \u2014 the\n // gap between views[i] and views[i+1] \u2014 and a flat `[trackId]` is read as\n // the level-0 shorthand, so on a five-strain launch only the top band got\n // the alignment and the four below it opened as bare rulers. The same\n // all-vs-all track fills every level: it carries all the pairs.\n tracks: trackId ? panels.slice(1).map(() => [trackId]) : [],\n collapseEmptyRows: true,\n },\n }\n // launchView where the session has it: a synteny view's state model is\n // loaded on demand and addView throws until it is\n if (session.launchView) {\n reportFailure(\n session,\n 'Could not open the synteny view',\n session.launchView('LinearSyntenyView', snapshot),\n )\n } else {\n session.addView('LinearSyntenyView', snapshot)\n }\n}\n", "// `session.views`, `session.hovered` and a display's members are read\n// structurally, their types being the host's rather than this plugin's\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n", "import { isRecord } from '../isRecord'\n\nexport interface NavigableLinearView {\n id: string\n assemblyNames: string[]\n navToLocString: (locString: string, assemblyName?: string) => unknown\n}\n\n// Reads `session.views` structurally, the same way graphViewHighlights does: the\n// members needed here are declared by LinearGenomeView, not by the\n// AbstractViewModel the session array is typed as.\nfunction isLinearView(view: unknown): view is NavigableLinearView {\n return (\n isRecord(view) &&\n view.type === 'LinearGenomeView' &&\n typeof view.id === 'string' &&\n typeof view.navToLocString === 'function' &&\n Array.isArray(view.assemblyNames)\n )\n}\n\n// The view a graph was launched from is not always in `session.views`: a row of\n// a LinearSyntenyView, LinearComparativeView or BreakpointSplitView sits in\n// that view's own `views[]`, so the candidates are the session's views plus one\n// level of rows.\nexport function withRows(views: unknown[]) {\n return views.flatMap(view =>\n isRecord(view) && Array.isArray(view.views)\n ? [view, ...view.views]\n : [view],\n )\n}\n\n// The linear view a \"show me this\" from the graph should move, rather than\n// opening a pane beside it. Three cases, in order:\n//\n// - the view this graph is paired with (`connectedViewId`), which is either\n// the view the graph was launched from or the one it later opened itself.\n// Explicit, so it wins.\n// - failing that, the only linear view in the session showing this assembly.\n// The pangenome sessions this view ships in are a linear view above a graph\n// with no pairing recorded, and there \"the linear view\" is unambiguous \u2014 the\n// same reasoning hoverSync's isConnected already applies to highlights.\n// - two or more candidates and no pairing: nothing. Guessing which of the\n// user's views to scroll is worse than opening one that is ours to move.\n//\n// Assembly-gated throughout: a linear view on a different assembly cannot show\n// this location at all.\nexport function linearViewTarget({\n views,\n connectedViewId,\n assemblyName,\n}: {\n views: unknown[]\n connectedViewId: string | undefined\n assemblyName: string\n}) {\n const candidates = withRows(views)\n .filter(view => isLinearView(view))\n .filter(view => view.assemblyNames.includes(assemblyName))\n const connected = candidates.find(view => view.id === connectedViewId)\n return connected ?? (candidates.length === 1 ? candidates[0] : undefined)\n}\n", "import {\n placeRowGenes,\n rowSpan,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport { filterSamples } from '@jbrowse/bandage-core/layout/walkRows'\nimport {\n cutsWholeWalks as wholeWalksRule,\n stripMarks,\n walkStripApplies,\n walkStripFrame,\n} from '@jbrowse/bandage-core/layout/walkStrip'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { nodeAnchor } from '@jbrowse/bandage-core/referenceStrip'\n\nimport { withLaunchViews } from './launchViews'\nimport { WALK_GENE_ROWS } from './paneBase'\nimport { resolveLocationAssembly } from '../../launchFromGraph/contributors'\n\nimport type { SubgraphRegion } from '../../GetSubgraph'\n\nexport const withWalkRowViews = withLaunchViews\n .views(self => ({\n // Whether the strip of walk rows sits under the drawing: asked for, on a\n // standalone view whose layout draws nodes, for a graph with walks, and\n // not while a bubble is popped\n get walkStripShown() {\n return walkStripApplies({\n walkStrip: self.walkStrip,\n mode: { drawsNodes: self.modeDrawsNodes },\n drawsPicture: !!self.layoutResult?.tubeMap || !!self.walkRowBars,\n popped: self.popStack.length > 0,\n walks: self.graph?.paths?.length ?? 0,\n host: !!self.host,\n })\n },\n // The strip's rows: the cut's, with the sample filter and no repeat\n // pick, which the Repeat menu only offers in walk rows\n get walkStripRows() {\n const bars = this.walkStripShown ? self.cutWalkRows : undefined\n return bars\n ? { ...bars, rows: filterSamples(bars.rows, self.walkRowSamples) }\n : undefined\n },\n get walkStripFrame() {\n const bars = this.walkStripRows\n if (!bars) {\n return undefined\n }\n return walkStripFrame(bars, { width: self.paneWidth })\n },\n // Whether a cut must follow every snarl a walk leaves the window by, so\n // walks come back whole: walk rows measure them, and so does the strip\n get cutsWholeWalks() {\n return wholeWalksRule(layoutModeByValue(self.chosenLayoutMode), {\n walkStrip: self.walkStrip,\n host: !!self.host,\n })\n },\n // Where each walk passes the hovered node, or the selected one\n get walkStripMarks() {\n const bars = this.walkStripRows\n const id = self.hoveredNode ?? self.selectedNode\n const node = id === null ? undefined : self.nodeById?.get(id)\n return bars && node && self.graph\n ? stripMarks(self.graph, [bars.reference, ...bars.rows], node)\n : []\n },\n // Where the drawing has the node a strip point lights, for the ring\n // that finds it in a hairball\n get walkStripLocator() {\n const id = self.stripHover ? self.hoveredNode : null\n return id === null\n ? undefined\n : nodeAnchor(self.nodePositions?.[id], p => ({\n x: p.x * self.scaleX + self.translateX,\n y: p.y * self.scaleY + self.translateY,\n }))\n },\n }))\n .views(self => ({\n // The gene reads walk rows need, as the layout or the strip: for each row whose haplotype\n // (`HG00097#1`) names an assembly with a gene track, that track over the\n // span of its own contig the row's bar covers. The first WALK_GENE_ROWS\n // such rows are read, and the rest counted for the key.\n get walkGeneReads() {\n const bars = self.walkRowBars ?? self.walkStripRows\n if (!bars || !self.showGenes) {\n return undefined\n }\n const reads: {\n row: string\n trackId: string\n region: SubgraphRegion\n }[] = []\n let untrackedRows = 0\n let unplaced = 0\n for (const row of bars.rows) {\n if (!row.axis) {\n unplaced++\n continue\n }\n const assemblyName = resolveLocationAssembly(self.assemblyResolver, {\n sample: row.sample,\n haplotype:\n row.haplotype === undefined\n ? undefined\n : `${row.sample}#${row.haplotype}`,\n })\n const track = assemblyName\n ? self.geneTracksByAssembly.get(assemblyName)\n : undefined\n if (!assemblyName || !track) {\n untrackedRows++\n continue\n }\n reads.push({\n row: row.name,\n trackId: track.trackId,\n region: {\n assemblyName,\n refName: row.axis.contig,\n ...rowSpan(row.axis, row.bp),\n },\n })\n }\n return {\n reads: reads.slice(0, WALK_GENE_ROWS),\n gaps: {\n untracked: untrackedRows,\n unplaced,\n unread: Math.max(0, reads.length - WALK_GENE_ROWS),\n },\n }\n },\n get walkRowGeneGaps() {\n return this.walkGeneReads?.gaps\n },\n // Where a walk row's bar lies in its own assembly, for a linear view to\n // open: the span of its contig the bar covers, on the session assembly\n // its haplotype names (the cut's own assembly for the reference row).\n // The label names the haplotype when no assembly is loaded for it.\n walkRowLaunchTarget(index: number, bars = self.walkRowBars) {\n const row = bars ? [bars.reference, ...bars.rows][index] : undefined\n if (!row?.axis) {\n return undefined\n }\n const haplotype =\n row.haplotype === undefined\n ? undefined\n : `${row.sample}#${row.haplotype}`\n const assembly =\n index === 0\n ? self.graphRegion?.assemblyName\n : resolveLocationAssembly(self.assemblyResolver, {\n sample: row.sample,\n haplotype,\n })\n return {\n label: row.label,\n assembly,\n location: {\n sample: row.sample,\n haplotype,\n refName: row.axis.contig,\n ...rowSpan(row.axis, row.bp),\n },\n }\n },\n // Each row's genes as offsets along its bar: the reference row's from\n // the backbone's gene track, every other row's from its own assembly\n get walkRowGenes() {\n const bars = self.walkRowBars ?? self.walkStripRows\n if (!bars || !self.showGenes) {\n return undefined\n }\n const byRow = new Map(self.walkGeneFeatures ?? [])\n if (self.geneFeatures) {\n byRow.set(bars.reference.name, self.geneFeatures)\n }\n return byRow.size\n ? placeRowGenes([bars.reference, ...bars.rows], byRow)\n : undefined\n },\n }))\n", "import { sameBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n REFERENCE_STRIP_ZONE_PX,\n nodeAnchor,\n referenceStripBlocks,\n stripBlockAt,\n stripOverhang,\n} from '@jbrowse/bandage-core/referenceStrip'\nimport { referenceBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport { referenceNodes } from '@jbrowse/bandage-core/tubeMap/connectors'\nimport { deviationMarks } from '@jbrowse/bandage-core/tubeMap/deviations'\nimport { tubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport { tubeMapGenes } from '@jbrowse/bandage-core/tubeMap/genes'\n\nimport { hostFrame } from '../host'\nimport { PAPER_DARK, PAPER_LIGHT, paperCss } from './paneBase'\nimport { withWalkRowViews } from './walkRowViews'\n\nexport const withHostViews = withWalkRowViews\n .views(self => ({\n // Whether the drawing's x is reference bp a host can place. Walk rows\n // put the backbone at its bp too, but their bars are lengths, so the\n // mode's `cutMargins` is what says the drawing is a picture.\n get xIsReferenceBp() {\n return (\n self.layoutResult?.referenceAxis === true &&\n layoutModeByValue(self.chosenLayoutMode).cutMargins\n )\n },\n }))\n .views(self => ({\n // Whether the host places x. Only a layout whose x is reference bp can\n // take the window's transform; force, ordered and walk rows draw in\n // their own coordinates inside the track, and a popped bubble is a\n // picture of its own.\n get hostPlacesX() {\n const { host, graphRegion: region } = self\n return (\n host !== undefined &&\n host.initialized &&\n region !== undefined &&\n self.xIsReferenceBp &&\n self.popStack.length === 0 &&\n !host.dynamicBlocks.contentBlocks.some(\n b => b.refName === region.refName && b.reversed,\n )\n )\n },\n }))\n .views(self => ({\n get hostFrame() {\n const { host, graphRegion } = self\n return self.hostPlacesX && host && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n },\n get tubeMapPicture() {\n const drawing = self.layoutResult?.tubeMap\n return drawing ? tubeMapPicture(drawing.layout) : undefined\n },\n get tubeMapReference() {\n const drawing = self.layoutResult?.tubeMap\n return drawing && self.drawnGraph\n ? referenceBoxes(self.drawnGraph, drawing.layout)\n : undefined\n },\n // the folded variants, as ticks on the tubes of the walks carrying them\n get tubeMapDeviations() {\n const coarse = self.layoutResult?.tubeMap?.coarse\n const layout = self.layoutResult?.tubeMap?.layout\n return coarse && layout\n ? deviationMarks(coarse.graph, layout, coarse.deviations)\n : []\n },\n // the reference boxes a linear view's connectors tie to its bp, which\n // the reference axis already puts under that bp\n get tubeMapReferenceNodes() {\n const layout = self.layoutResult\n return layout?.tubeMap && !layout.referenceAxis && self.drawnGraph\n ? referenceNodes(self.drawnGraph, layout.tubeMap.layout)\n : undefined\n },\n }))\n .views(self => ({\n // A linear view has the genes in a track of their own, at their bp\n get tubeMapGenes() {\n const reference = self.tubeMapReference\n return self.showGenes && !self.host && reference && self.backboneGenes\n ? tubeMapGenes(reference, self.backboneGenes)\n : []\n },\n // A drawing of nodes in its own coordinates inside a linear view, whose\n // reference segments the strip can put back at their bp\n get referenceStripApplies() {\n return (\n !!self.host?.initialized &&\n !!self.layoutResult &&\n self.drawsNodes &&\n !self.hostPlacesX &&\n !self.facetPanels\n )\n },\n }))\n .views(self => ({\n get referenceStripBlocks() {\n const { graph } = self\n return self.showReferenceStrip && self.referenceStripApplies && graph\n ? referenceStripBlocks(graph, {\n colorScheme: self.effectiveColorScheme,\n referenceRamp: self.referenceRamp,\n walks: self.walkLift?.walks,\n })\n : []\n },\n // Read off the live blocks, so the strip follows every frame of a pan\n // in the linear view\n get referenceStripFrame() {\n const { host, graphRegion } = self\n return host?.initialized && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n },\n }))\n .views(self => ({\n get referenceStripShown() {\n return (\n self.referenceStripBlocks.length > 0 &&\n self.referenceStripFrame !== undefined\n )\n },\n // Whether the graph draws reference past the window's edges. A boolean\n // rather than the bp, which moves on every frame of a pan and would\n // resize the legend with it.\n get referenceStripOverhangs() {\n const frame = self.referenceStripFrame\n if (!frame || self.referenceStripBlocks.length === 0) {\n return false\n }\n const { left, right } = stripOverhang(\n self.referenceStripBlocks,\n frame,\n self.paneWidth,\n )\n return left > 0 || right > 0\n },\n get referenceStripFaded() {\n return self.referenceStripBlocks.some(b => b.faded)\n },\n }))\n .views(self => ({\n // The lit span on the strip, and where the graph drew what it is of:\n // the hovered node, the hovered bubble's name, or the selected node\n get referenceStripLit() {\n if (!self.referenceStripShown) {\n return undefined\n }\n const toScreen = (p: { x: number; y: number }) => ({\n x: p.x * self.scaleX + self.translateX,\n y: p.y * self.scaleY + self.translateY,\n })\n const bubble = self.hoveredNode === null ? self.hoveredBubble : null\n if (bubble) {\n const halo = self.bubbleHalos.find(h => sameBubble(h.bubble, bubble))\n return {\n start: bubble.start,\n end: bubble.end,\n anchor: halo ? toScreen(halo.labelAt) : undefined,\n }\n }\n const nodeId = self.hoveredNode ?? self.selectedNode\n const span = nodeId === null ? undefined : self.nodeSpan(nodeId)\n return span && nodeId !== null\n ? {\n ...span,\n anchor: nodeAnchor(self.nodePositions?.[nodeId], toScreen),\n }\n : undefined\n },\n referenceStripNodeAt(sx: number, sy: number) {\n const frame = self.referenceStripFrame\n return self.referenceStripShown && frame\n ? stripBlockAt(self.referenceStripBlocks, frame, sx, sy)\n : undefined\n },\n get paperCss() {\n return paperCss(self.darkMode ? PAPER_DARK : PAPER_LIGHT)\n },\n // the strip, and the gap the fit leaves under it\n get referenceStripZonePx() {\n return self.referenceStripShown ? REFERENCE_STRIP_ZONE_PX : 0\n },\n }))\n", "import { isBackbone } from '@jbrowse/bandage-core/anchoredNodes'\n\nimport { isRecord } from '../isRecord'\n\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\n\n// What a LinearGenomeView writes to `session.hovered` on every mousemove (see\n// LinearGenomeViewContainer): the bp under the cursor, plus the feature under it\n// if the topmost track had one. Nothing names the source VIEW, so a graph view\n// filters by whether the position falls in the region it was cut from \u2014 but the\n// position does name the source ASSEMBLY, and that turns out to be the half\n// that matters.\nexport interface LgvHover {\n refName: string\n // The 0-based base under the pointer, the convention `stable.start` and the\n // cut region are in. Not the LGV's own `coord`, which is 1-based for display.\n coord: number\n // The assembly the hovered view is showing. `hoverPosition` is a\n // `PxToBpResult`, i.e. the displayed region the pointer landed in spread flat,\n // so this is that region's own `assemblyName`.\n //\n // Read because refName alone does not identify a locus in a session holding\n // several assemblies, which is every session these graphs are launched in. A\n // PanSN name reduces to a bare contig \u2014 the E. coli pangenome loads five\n // strains each with one refName `chr`, and HPRC's hg38 and a GenArk haplotype\n // both call it `chr6` \u2014 so a synteny stack's rows all answer to the same\n // name at unrelated coordinates. Without this the hover on ANY row lit up a\n // node in the graph, and the node then published its own reference interval\n // back into every linear view.\n //\n // Optional because the channel is typed `unknown` and read structurally: a\n // hover that states no assembly is taken at its word rather than dropped.\n assemblyName?: string\n featureName?: string\n}\n\ninterface FeatureLike {\n get: (key: string) => unknown\n}\n\nfunction isFeatureLike(value: unknown): value is FeatureLike {\n return isRecord(value) && typeof value.get === 'function'\n}\n\n// A display hovers either a Feature, read with `get`, or a plain hit item with\n// a `name` of its own, which is what the canvas feature display hands over.\n// Reading only the first left the exact segment match dead on that display.\nfunction hoveredName(feature: unknown) {\n const name = isFeatureLike(feature)\n ? feature.get('name')\n : isRecord(feature)\n ? feature.name\n : undefined\n return typeof name === 'string' ? name : undefined\n}\n\n// `hovered` is typed `unknown` on the session by design \u2014 it is a shared channel\n// every view writes its own shape to \u2014 so this reads the LGV's shape out of it\n// structurally rather than asserting a type onto it.\nexport function readLgvHover(hovered: unknown): LgvHover | undefined {\n let result: LgvHover | undefined\n if (isRecord(hovered) && isRecord(hovered.hoverPosition)) {\n const { refName, coord, coord0, assemblyName } = hovered.hoverPosition\n if (typeof refName === 'string' && typeof coord === 'number') {\n result = {\n refName,\n // `coord` is 1-based; a host that states the 0-based `coord0` is\n // taken at its word. Read as 0-based, the last base of every node lit\n // the next one, and a 1 bp node could not be reached at all.\n coord: typeof coord0 === 'number' ? coord0 : coord - 1,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n featureName: hoveredName(hovered.hoverFeature),\n }\n }\n }\n return result\n}\n\n// Whether a hover is one this graph can answer: the same assembly, the same\n// stable sequence, and inside the window the cut was made for.\n//\n// The assembly is checked FIRST and is the whole reason this is not just a\n// coordinate test. See LgvHover.assemblyName: a graph cut from K12 and a\n// synteny row on Sakai both call their sequence `chr`, so on refName and\n// coordinate alone every row of the stack matched and the graph highlighted a\n// K12 node at Sakai's offset. A hover that names no assembly still passes,\n// which is what a hand-written channel writer and the older LGVs get.\nexport function hoverInRegion(\n hover: LgvHover,\n region: { refName: string; assemblyName: string; start: number; end: number },\n) {\n return (\n (hover.assemblyName === undefined ||\n hover.assemblyName === region.assemblyName) &&\n hover.refName === region.refName &&\n hover.coord >= region.start &&\n hover.coord < region.end\n )\n}\n\n// The graph node a linear-view hover points at.\n//\n// The feature under the cursor is the exact answer when the graph's own segments\n// track is what's hovered: an RgfaTabixAdapter feature's name is the segment id,\n// which is `GraphNode.name` (`GraphNode.id` carries a strand suffix, so the\n// match has to be on name). Any other track \u2014 genes, bubbles \u2014 supplies only a\n// coordinate, which still identifies the backbone segment covering it: the\n// backbone tiles the reference exactly once, whether rGFA's rank 0 declared it\n// or a reference path's own steps did.\nexport function nodeForLgvHover({\n hover,\n nodes,\n}: {\n hover: LgvHover\n nodes: GraphNode[]\n}) {\n let byName: string | undefined\n let byCoord: string | undefined\n for (const node of nodes) {\n if (node.name === hover.featureName) {\n byName = node.id\n } else if (\n byCoord === undefined &&\n isBackbone(node) &&\n hover.coord >= node.stable.start &&\n hover.coord < node.stable.start + node.length\n ) {\n byCoord = node.id\n }\n }\n // An exact segment match wins over the coordinate it happens to sit at.\n return byName ?? byCoord ?? null\n}\n", "import { panSNSample } from '@jbrowse/bandage-core/pansn'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\n\n// A per-sample lane names its rows its own way: a phased callset `HG00097 HP0`,\n// counting haplotypes from 0, a MAF `HG00097.1`, counting from 1 as PanSN does,\n// and anything else by the bare sample\nconst PHASED_ROW = /^(.+) HP(\\d+)$/\nconst DOTTED_ROW = /^(.+)\\.(\\d+)$/\n\n// A bare sample can end in `.2` too, an accession for one, so each reading is\n// tried in turn\nfunction readings(row: string) {\n const phased = PHASED_ROW.exec(row)\n const dotted = DOTTED_ROW.exec(row)\n return [\n ...(phased\n ? [{ sample: phased[1]!, haplotype: String(Number(phased[2]) + 1) }]\n : []),\n ...(dotted ? [{ sample: dotted[1]!, haplotype: dotted[2] }] : []),\n { sample: row, haplotype: undefined },\n ]\n}\n\nfunction haplotypeOf(pathName: string) {\n return pathOrigin(pathName).name.split('#')[1]\n}\n\n// The walks a hovered lane row stands for: the one of its haplotype, or every\n// walk of a bare sample. A cut often holds one haplotype of a sample, so a row\n// naming the other matches nothing rather than the one it holds.\nexport function walksForRow(row: string, paths: readonly { name: string }[]) {\n const names = paths.map(p => p.name)\n for (const { sample, haplotype } of readings(row)) {\n const walks = names.filter(\n name =>\n panSNSample(pathOrigin(name).name) === sample &&\n (haplotype === undefined || haplotypeOf(name) === haplotype),\n )\n if (walks.length > 0) {\n return walks\n }\n }\n return []\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { TrackScanSession } from './launchFromGraph'\n\nconst ANNOTATION_TRACK_TYPE = 'FeatureTrack'\n\n// What to turn on in a linear view the graph opens on `assemblyName`.\n//\n// A launch used to carry the graph's own track and nothing else, and that track\n// is configured for the reference alone \u2014 so `Launch view` \u2192 `CFT073 chr:\u2026`\n// landed on `No tracks active`, which answers \"where is this strain's sequence?\"\n// with an empty pane. What the session does hold for a contributing assembly is\n// that assembly's own annotation, and on a pangenome config that is one track\n// per strain (`CFT073_genes`), which is exactly what makes the landing readable.\n//\n// Annotation tracks only, not everything configured for the assembly. A launch\n// is a jump to a locus, and an alignments or coverage track turned on behind the\n// user's back fetches data nobody asked for; a FeatureTrack at a 50 kb window is\n// a tabix range query.\n//\n// `first` is the graph's own track when the launch is on the reference, so the\n// segments the graph drew sit at the top of the view rather than wherever config\n// order puts them.\nexport function launchTracks({\n session,\n assemblyName,\n first,\n}: {\n session: TrackScanSession\n assemblyName: string\n first?: string\n}) {\n const found: string[] = []\n for (const track of session.tracks) {\n const type: unknown = readConfObject(track, 'type')\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n type === ANNOTATION_TRACK_TYPE &&\n Array.isArray(assemblyNames) &&\n assemblyNames.includes(assemblyName) &&\n typeof trackId === 'string' &&\n trackId !== first\n ) {\n found.push(trackId)\n }\n }\n return first ? [first, ...found] : found\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getTrackName } from '@jbrowse/core/util/tracks'\nimport { getEnv, isStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nimport { canonicalAssemblyName } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface LaunchableSyntenyTrack {\n trackId: string\n name: string\n // how many of the requested assemblies this track covers, so a whole-set\n // all-vs-all sorts above a pairwise alignment covering two of them\n coverage: number\n}\n\nconst SYNTENY_TRACK_TYPE = 'SyntenyTrack'\nconst SYNTENY_ADAPTER_CATEGORY = 'Synteny adapters'\n\n// A SyntenyTrack, or any track reading a synteny adapter (a GraphTrack over a\n// gbz-base database). Core's isSyntenyTrack makes the same test on newer hosts.\nfunction isSyntenyTrack(track: AnyConfigurationModel) {\n if (readConfObject(track, 'type') === SYNTENY_TRACK_TYPE) {\n return true\n }\n const adapterType: unknown = track.adapter?.type\n if (typeof adapterType !== 'string' || !isStateTreeNode(track)) {\n return false\n }\n const { pluginManager } = getEnv<{ pluginManager?: PluginManager }>(track)\n return (\n !!pluginManager?.hasAdapterType(adapterType) &&\n pluginManager.getAdapterType(adapterType).adapterMetadata?.category ===\n SYNTENY_ADAPTER_CATEGORY\n )\n}\n\n// Synteny datasets in the session that align at least two of `assemblyNames`.\n//\n// Two is the floor because that is the floor for a synteny view; more is better,\n// and an all-vs-all covering every contributing assembly is what makes the\n// multi-panel launch worth offering at all.\nexport function launchableSyntenyTracks(\n session: TrackScanSession,\n assemblyNames: string[],\n) {\n const wanted = new Set(assemblyNames)\n const found: LaunchableSyntenyTrack[] = []\n for (const track of session.tracks) {\n const trackAssemblies: unknown = readConfObject(track, 'assemblyNames')\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n isSyntenyTrack(track) &&\n typeof trackId === 'string' &&\n Array.isArray(trackAssemblies)\n ) {\n const coverage = trackAssemblies.filter(\n name =>\n typeof name === 'string' &&\n wanted.has(canonicalAssemblyName(session, name)),\n ).length\n if (coverage >= 2) {\n found.push({ trackId, name: getTrackName(track, session), coverage })\n }\n }\n }\n return found.sort((a, b) => b.coverage - a.coverage)\n}\n", "// Hands `text` to the browser as a file to save\nexport function downloadText(\n text: string,\n name: string,\n type = 'image/svg+xml',\n) {\n const url = URL.createObjectURL(new Blob([text], { type }))\n const a = document.createElement('a')\n a.href = url\n a.download = name\n a.click()\n setTimeout(() => {\n URL.revokeObjectURL(url)\n }, 0)\n}\n", "import { withLaunchActions } from './pane/launchActions'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport {\n DEFAULT_MAX_GRAPH_NODES,\n MAX_GRAPH_REGION_BP,\n formatSpanBp,\n} from './pane/paneBase'\n\n// The pane every graph drawing is: a view of its own, or a display inside a\n// linear view. Built in stages under pane/, each extending the one before.\nexport function GraphPaneMixin() {\n return withLaunchActions\n}\n\nexport type GraphPaneModel = Instance<typeof withLaunchActions>\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(item => typeof item === 'string')\n}\n\n// The assemblies the track names after its reference, which is what core's\n// MultiWaySyntenyDisplay opens a lane-declaring source on.\nexport function trackLanes(track: AnyConfigurationModel) {\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n const lanes = isStringArray(assemblyNames) ? assemblyNames.slice(1) : []\n return lanes.length > 0 ? lanes : undefined\n}\n\n// A graph is cut on the first assembly its track names, the rule\n// GbzBaseSyntenyAdapter states for its anchor. Every other assembly the track\n// names holds its sequence as rank>0 alleles off that reference's backbone, so\n// a window on one has no reference coordinates to frame the cut by.\nexport function graphReferenceAssembly(track: AnyConfigurationModel) {\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n return isStringArray(assemblyNames) ? assemblyNames[0] : undefined\n}\n\nexport function offReferenceProblem(\n referenceAssembly: string | undefined,\n assemblyName: string,\n) {\n return referenceAssembly === undefined || referenceAssembly === assemblyName\n ? undefined\n : `The graph is cut on its reference, ${referenceAssembly}: open it from a view of ${referenceAssembly}`\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport {\n TrackType,\n createBaseTrackConfig,\n createBaseTrackModel,\n} from '@jbrowse/core/pluggableElementTypes'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\n// core's synteny displays, copied to ask for headerLanes so only gbz-base\n// offers lanes or opens in a synteny, dotplot or circular view\nexport const SYNTENY_DISPLAYS = [\n 'MultiWaySyntenyDisplay',\n 'LinearSyntenyDisplay',\n 'DotplotDisplay',\n 'ChordSyntenyDisplay',\n]\n\nfunction displaysInOrder(pluginManager: PluginManager): DisplayType[] {\n const displays = pluginManager.getElementTypesInGroup(\n 'display',\n ) as DisplayType[]\n const named = (name: string) => displays.find(d => d.name === name)\n const needsLanes = (display: DisplayType | undefined) =>\n display &&\n Object.assign(Object.create(display) as DisplayType, {\n adapterCapabilities: ['headerLanes'],\n })\n return [\n named('LinearGraphDisplay'),\n named('LinearBasicDisplay'),\n ...SYNTENY_DISPLAYS.map(name => needsLanes(named(name))),\n ].filter((d): d is DisplayType => d !== undefined)\n}\n\nexport default function GraphTrackF(pluginManager: PluginManager) {\n pluginManager.addTrackType(() => {\n const configSchema = ConfigurationSchema(\n 'GraphTrack',\n {},\n {\n baseConfiguration: createBaseTrackConfig(pluginManager),\n explicitIdentifier: 'trackId',\n },\n )\n const track = new TrackType({\n name: 'GraphTrack',\n displayName: 'Pangenome graph track',\n configSchema,\n stateModel: createBaseTrackModel(\n pluginManager,\n 'GraphTrack',\n configSchema,\n ),\n })\n for (const display of displaysInOrder(pluginManager)) {\n track.addDisplayType(display)\n }\n return track\n })\n}\n", "import type modelFactory from './GraphGenomeView/viewModel'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type { SnapshotIn } from '@jbrowse/mobx-state-tree'\n\n// GraphGenomeView has no assembly/track resolution \u2014 every field is a plain\n// persisted view prop, so the launch spec forwards straight onto the view\n// snapshot. `afterAttach` loads `gfaLocation`, or cuts the\n// `loadedTrackId`/`loadedRegion` pair once, when the view is created.\n//\n// **Taken off the model rather than listed by hand**, which is the whole point.\n// This named four props (`gfaLocation`, `colorScheme`, `linearLayout`,\n// `drawPaths`) while the extension point spreads whatever it is handed \u2014 so the\n// runtime accepted every prop and the DECLARED contract accepted a third of\n// them. The docs' own figure specs launch with thirteen: `loadedTrackId`,\n// `loadedRegion`, `layoutMode`, `colorDomain`, `paneHeight`, `referencePath`,\n// `layoutQuality`, `maxRegionBp` and `bubbleSpread` among them, none of which\n// this said were allowed. It carries a `#extensionPoint` tag, so the published\n// API docs said so too.\n//\n// Derived, so adding a view prop widens the launch with it. `type` is the\n// dispatch key rather than a setting \u2014 loadSessionSpec strips it before calling\n// this \u2014 and is the one field a caller may not supply.\nexport type LaunchGraphGenomeViewArgs = Partial<\n Omit<SnapshotIn<ReturnType<typeof modelFactory>>, 'type'>\n> & {\n session: AbstractSessionModel\n}\n\ndeclare module '@jbrowse/core/PluginManager' {\n interface ExtensionPointRegistry {\n 'LaunchView-GraphGenomeView': {\n args: LaunchGraphGenomeViewArgs\n result: LaunchGraphGenomeViewArgs\n }\n }\n}\n\nexport default function LaunchGraphGenomeViewF(pluginManager: PluginManager) {\n /** #extensionPoint LaunchView-GraphGenomeView | async | Programmatically launch a graph genome view */\n pluginManager.addToExtensionPoint('LaunchView-GraphGenomeView', args => {\n const { session, ...spec } = args\n session.addView('GraphGenomeView', spec)\n return args\n })\n}\n", "import { lazy } from 'react'\n\nimport DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\nimport { configSchemaFactory } from './configSchema'\nimport { stateModelFactory } from './model'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function LinearGraphDisplayF(pluginManager: PluginManager) {\n pluginManager.addDisplayType(() => {\n const configSchema = configSchemaFactory()\n return Object.assign(\n new DisplayType({\n name: 'LinearGraphDisplay',\n displayName: 'Graph',\n configSchema,\n stateModel: stateModelFactory(configSchema),\n // FeatureTrack and SyntenyTrack for the configs and share links that\n // name the graph display on one, which 4.0.7 and before required\n trackType: ['GraphTrack', 'FeatureTrack', 'SyntenyTrack'],\n viewType: 'LinearGenomeView',\n ReactComponent: lazy(() => import('./components/LinearGraphDisplay')),\n }),\n { adapterCapabilities: ['getSubgraph'] },\n )\n })\n}\n", "import { COLOR_SCHEME_VALUES } from '@jbrowse/bandage-core/colorSchemes'\nimport { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { trackHeightConfigSchemaFields } from '@jbrowse/display-kit/trackHeightConfigSchemaFields'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config LinearGraphDisplay\n * The graph drawn as a track of the linear genome view. A layout whose x is\n * reference bp draws under the view's coordinates and re-cuts as the view\n * moves; force, ordered and walk rows draw in their own coordinates, fitted to\n * the track.\n */\nexport function configSchemaFactory() {\n return ConfigurationSchema(\n 'LinearGraphDisplay',\n {\n /**\n * #slot\n * the layout the track opens in\n */\n layoutMode: {\n type: 'stringEnum',\n model: types.enumeration('LayoutMode', LAYOUT_MODE_VALUES),\n defaultValue: 'auto',\n },\n /**\n * #slot\n */\n colorScheme: {\n type: 'stringEnum',\n model: types.enumeration('ColorScheme', COLOR_SCHEME_VALUES),\n defaultValue: 'auto',\n },\n ...trackHeightConfigSchemaFields({\n defaultHeight: 300,\n height: 'the height of the track the graph is drawn in',\n }),\n },\n { explicitlyTyped: true, explicitIdentifier: 'displayId' },\n )\n}\n\nexport type LinearGraphDisplayConfigModel = ReturnType<\n typeof configSchemaFactory\n>\nexport type LinearGraphDisplayConfig = Instance<LinearGraphDisplayConfigModel>\n", "import { lazy } from 'react'\n\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationReference, getConf } from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\nimport TrackHeightMixin from '@jbrowse/display-kit/TrackHeightMixin'\nimport {\n addDisposer,\n getSnapshot,\n isAlive,\n types,\n} from '@jbrowse/mobx-state-tree'\nimport {\n computeActivityPhase,\n computeDisplayStatusPhase,\n} from '@jbrowse/render-core/displayPhase'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport { reaction } from 'mobx'\n\nimport { cutHolds, hostCut, hostWindow } from '../GraphGenomeView/host'\nimport {\n GraphPaneMixin,\n MAX_GRAPH_REGION_BP,\n formatSpanBp,\n} from '../GraphGenomeView/model'\nimport {\n graphReferenceAssembly,\n offReferenceProblem,\n trackLanes,\n} from '../graphTrackConfig'\nimport { denseCovers, isNodeLimitError } from './denseWindow'\nimport { trackAdapterConfig } from '../panSNAliases/trackAdapterConfig'\n\nimport type { LinearGraphDisplayConfigModel } from './configSchema'\nimport type { DenseWindow } from './denseWindow'\nimport type { SubgraphRegion, SubgraphTier } from '../GetSubgraph'\nimport type { HostWindow } from '../GraphGenomeView/host'\nimport type { LaunchGraphGenomeViewArgs } from '../LaunchGraphGenomeView'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\nimport type { DisplayStatusPhase } from '@jbrowse/render-core/displayPhase'\n\ntype GraphViewSpec = Omit<LaunchGraphGenomeViewArgs, 'session'>\n\nconst GraphTrackSettingsDialog = lazy(\n () => import('./components/GraphTrackSettingsDialog'),\n)\n\nexport function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {\n return (\n types\n .compose(\n 'LinearGraphDisplay',\n BaseDisplay,\n TrackHeightMixin(),\n GraphPaneMixin(),\n types.model({\n type: types.literal('LinearGraphDisplay'),\n configuration: ConfigurationReference(configSchema),\n // A 4.0 entry's nested state, which preProcessSnapshot folds flat and\n // so never holds. Declared so a session spec stating it is not\n // reported as an unknown key.\n pane: types.maybe(types.frozen()),\n // The retired haplotype overview's row choice and order, which a 5.x\n // session may carry and preProcessSnapshot drops, declared for the\n // same reason\n overviewRowsChoice: types.maybe(types.frozen()),\n overviewRowOrder: types.maybe(types.frozen()),\n // the window the graph on screen was asked for, so a restored\n // session cuts it again\n cutRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // whether that cut came from the track's coarse pair\n // (RgfaTabixAdapter), on which no bp cap applies\n coarseCut: types.optional(types.boolean, false),\n // The bp ceiling on a fine cut, a proxy for node count that only\n // holds at fine granularity; `maxGraphNodes` counts what came back.\n maxRegionBp: types.optional(types.number, MAX_GRAPH_REGION_BP),\n // How far the cut follows links past the region's own segments. At\n // 0 a detour that leaves the backbone before the window and rejoins\n // after it arrives as a fragment, since its interior is indexed only\n // under its own sequence, so one bubble draws as two unrelated\n // insertions. A hop follows alleles only, so it never walks the\n // backbone out of the window.\n subgraphContext: types.optional(types.number, 1),\n // the haplotypes a GBZ cut is for; unset is the lanes the track names\n subgraphHaplotypes: types.maybe(types.frozen<string[]>()),\n }),\n )\n // A 4.0 session nests the graph's state under `pane`; a 5.x one may\n // carry the retired overview's row choice\n .preProcessSnapshot(snapshot => {\n const {\n pane,\n overviewRowsChoice: _rows,\n overviewRowOrder: _order,\n ...rest\n } = snapshot as {\n pane?: { type?: string }\n overviewRowsChoice?: unknown\n overviewRowOrder?: unknown\n }\n if (!pane) {\n return rest as typeof snapshot\n }\n const { type: _type, ...props } = pane\n return { ...props, ...rest } as typeof snapshot\n })\n .volatile(() => ({\n recuts: 0,\n // the host window the settle clock last woke on\n settledWindow: undefined as HostWindow | undefined,\n dense: undefined as DenseWindow | undefined,\n }))\n .views(self => ({\n get adapterConfig() {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n get defaultLayoutMode(): LayoutModeValue {\n return getConf(self, 'layoutMode')\n },\n get defaultColorScheme(): ColorScheme {\n return getConf(self, 'colorScheme')\n },\n // The linear view leaves its highlight bands off this track while false\n get drawsGenomicCoordinates() {\n return self.layoutResult === undefined || self.hostPlacesX\n },\n get canvasHeight() {\n return self.height\n },\n get canRetryLoad() {\n return self.cutRegion !== undefined\n },\n get cutHaplotypes() {\n return this.chosenHaplotypes\n },\n get chosenHaplotypes() {\n return (\n self.subgraphHaplotypes ??\n trackLanes(self.parentTrack.configuration)\n )\n },\n // the linear view's zoom past which the track's coarse pair is cut, or\n // undefined for a track with none\n get coarseAboveBpPerPx() {\n const coarse = self.adapterConfig.coarse as\n { aboveBpPerPx?: unknown } | undefined\n const above = coarse?.aboveBpPerPx\n return typeof above === 'number' ? above : undefined\n },\n }))\n .views(self => ({\n tierAt(bpPerPx: number): SubgraphTier {\n const above = self.coarseAboveBpPerPx\n return above !== undefined && bpPerPx > above ? 'coarse' : 'fine'\n },\n capFor(tier: SubgraphTier) {\n return tier === 'coarse' ? Infinity : self.maxRegionBp\n },\n get cutTier(): SubgraphTier {\n return self.coarseCut && self.coarseAboveBpPerPx !== undefined\n ? 'coarse'\n : 'fine'\n },\n }))\n .views(self => ({\n get settledCapBp() {\n const seen = self.settledWindow\n return seen ? self.capFor(self.tierAt(seen.bpPerPx)) : Infinity\n },\n }))\n .views(self => ({\n get regionTooLarge() {\n const seen = self.settledWindow\n return seen !== undefined && seen.end - seen.start > self.settledCapBp\n },\n get regionTooLargeReason() {\n const seen = self.settledWindow\n return seen\n ? `Region too large for a graph cut (${formatSpanBp(seen.end - seen.start)}, max ${formatSpanBp(self.settledCapBp)})`\n : ''\n },\n get zoomCanReleaseGate() {\n return true\n },\n get fetchCanceled() {\n return self.loadCanceled\n },\n }))\n .views(self => ({\n // A backend that failed is an error the canvas reports with its retry;\n // the status chrome has no renderError phase of its own. A cut refused\n // over its node limit is an error marked regionTooLarge, which core's\n // error bar shows as a zoom-in notice instead.\n get displayPhase(): DisplayStatusPhase {\n return computeDisplayStatusPhase(\n {\n regionTooLarge: self.regionTooLarge,\n error: self.error ?? self.renderError,\n },\n () =>\n computeActivityPhase(\n {\n isMinimized: self.isMinimized,\n fetchInert: false,\n viewportEmpty:\n self.host?.initialized === true &&\n self.host.hasVisibleContent === false,\n isLoading: self.isLoading || !self.hasGraph,\n fetchCanceled: self.loadCanceled,\n awaitingDependentData: false,\n rendersCanvas: true,\n canvasDrawn: self.painted && self.geometryPainted,\n },\n () => true,\n () => self.host?.effectiveBodyMounted ?? true,\n ),\n )\n },\n }))\n .actions(self => ({\n // The setters describe the next cut; the caller re-cuts.\n setSubgraphContext(hops: number) {\n self.subgraphContext = hops\n },\n setSubgraphHaplotypes(haplotypes: string[] | undefined) {\n self.subgraphHaplotypes = haplotypes\n self.dense = undefined\n },\n setDense(window: DenseWindow | undefined) {\n self.dense = window\n },\n setMaxRegionBp(bp: number) {\n self.maxRegionBp = bp\n },\n // Cut `cutRegion` again with the current options. A hop past a coarse\n // cut reaches nothing new: every bubble node's two links are indexed\n // under the backbone either side of it.\n cut() {\n const region = self.cutRegion\n if (!region) {\n return\n }\n const problem = offReferenceProblem(\n graphReferenceAssembly(self.parentTrack.configuration),\n region.assemblyName,\n )\n if (problem) {\n self.clearGraph()\n self.setError(new Error(problem))\n return\n }\n const coarse = self.cutTier === 'coarse'\n return self.cutSubgraph(self.adapterConfig, region, {\n hops: coarse ? 0 : self.subgraphContext,\n haplotypes: self.chosenHaplotypes,\n tier: coarse ? 'coarse' : undefined,\n ...(layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ? { snarls: 'overlapping' as const }\n : {}),\n })\n },\n }))\n .actions(self => ({\n recutAt(seen: HostWindow) {\n const tier = self.tierAt(seen.bpPerPx)\n self.coarseCut = tier === 'coarse'\n self.cutRegion = hostCut(\n seen,\n self.capFor(tier),\n layoutModeByValue(self.chosenLayoutMode).cutMargins,\n )\n self.recuts++\n return self.cut()\n },\n }))\n .actions(self => ({\n // The settle clock. A window the cut still holds fetches nothing; one\n // past its edge re-cuts, on the tier the zoom asks for, with margins\n // when the host places x and the window alone when the layout draws\n // its own picture of it. A canceled cut is re-made by the next move,\n // and a window a refused cut covers keeps its notice without asking\n // again. Returns whether it re-cut.\n settleOn(seen: HostWindow): boolean {\n self.settledWindow = seen\n const margins = layoutModeByValue(self.chosenLayoutMode).cutMargins\n if (\n self.regionTooLarge ||\n denseCovers(self.dense, seen) ||\n (!self.loadCanceled &&\n self.tierAt(seen.bpPerPx) === self.cutTier &&\n cutHolds(self.cutRegion, seen, margins))\n ) {\n return false\n }\n // The error is the latest cut's, since a cut clears it as it\n // starts and an outrun cut sets nothing\n void Promise.resolve(self.recutAt(seen)).then(() => {\n if (isAlive(self) && isNodeLimitError(self.error)) {\n this.refuseDenseCut(seen)\n }\n })\n return true\n },\n // A cut refused for its node count holds nothing, so a window\n // narrower than this one cuts again\n refuseDenseCut(seen: HostWindow) {\n self.setDense(seen)\n self.cutRegion = undefined\n this.settleOn(self.settledWindow ?? seen)\n },\n switchLayout(mode: LayoutModeValue) {\n const from = layoutModeByValue(self.chosenLayoutMode)\n self.setLayoutMode(mode)\n const to = layoutModeByValue(mode)\n const seen = self.host ? hostWindow(self.host) : undefined\n if (\n seen &&\n !self.regionTooLarge &&\n (to.cutMargins !== from.cutMargins ||\n to.wholeWalks !== from.wholeWalks)\n ) {\n return self.recutAt(seen)\n }\n return self.recomputeLayout()\n },\n retryLoad() {\n void self.cut()\n },\n reload() {\n void self.cut()\n },\n cancelFetchByUser() {\n self.stopLoad()\n },\n }))\n .actions(self => ({\n forceLoad() {\n const seen = self.settledWindow\n if (seen) {\n self.setMaxRegionBp(Math.ceil(seen.end - seen.start))\n self.settleOn(seen)\n }\n },\n // The host's two clocks. The frame clock moves x with every frame of\n // the linear view and fetches nothing; the settle clock wakes on its\n // debounced blocks.\n afterAttach() {\n if (self.cutRegion && !self.graph) {\n void self.cut()\n }\n addDisposer(\n self,\n reaction(\n () => self.hostPlacesX,\n places => {\n if (!places) {\n self.releaseHost()\n }\n },\n { name: 'GraphHostPlacesX' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostFrame,\n frame => {\n if (frame) {\n self.hostTransform(frame.scale, frame.translateX)\n }\n },\n {\n equals: (a, b) =>\n a?.scale === b?.scale && a?.translateX === b?.translateX,\n fireImmediately: true,\n name: 'GraphHostFrame',\n },\n ),\n )\n // A track clips what runs past its height, so side-by-side panels\n // grow it to what they need as a pane of their own. Only a change in\n // the panels does this, so a track shrunk afterwards stays shrunk.\n addDisposer(\n self,\n reaction(\n () => `${self.facet.field} ${self.facetPlacement?.count}`,\n () => {\n const needs = self.facetGridIn(self.paneCeiling)?.total ?? 0\n if ((self.facetGrid?.total ?? 0) > self.height) {\n self.setHeight(Math.max(self.height, Math.ceil(needs)))\n }\n },\n { name: 'GraphFacetHeight' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.host?.coarseDynamicBlocks,\n blocks => {\n const { host } = self\n const seen = blocks && host ? hostWindow(host) : undefined\n if (seen) {\n self.settleOn(seen)\n }\n },\n { fireImmediately: true, name: 'GraphHostSettle' },\n ),\n )\n },\n }))\n .views(self => ({\n // The window on screen as a view of its own, drawn as the track draws\n // it: the cut less the margins it holds for panning. A window forced\n // past the cap carries its own span as the cap.\n get graphViewSpec() {\n const seen = self.host ? hostWindow(self.host) : undefined\n const trackId = self.sourceTrackId\n if (\n !seen ||\n !trackId ||\n !self.hasGraph ||\n self.coarseCut ||\n self.regionTooLarge\n ) {\n return undefined\n }\n const start = Math.floor(seen.start)\n const end = Math.ceil(seen.end)\n return {\n loadedTrackId: trackId,\n loadedRegion: {\n refName: seen.refName,\n assemblyName: seen.assemblyName,\n start,\n end,\n },\n subgraphContext: self.subgraphContext,\n subgraphHaplotypes: self.chosenHaplotypes,\n maxRegionBp: Math.max(self.maxRegionBp, end - start),\n layoutMode: self.chosenLayoutMode,\n colorScheme: self.chosenColorScheme,\n referencePath: self.referencePath,\n geneTrackId: self.geneTrackId,\n showGenes: self.showGenes,\n showBubbles: self.showBubbles,\n showDeletionEdges: self.showDeletionEdges,\n walkLayers: self.walkLayers,\n facet: getSnapshot(self.facet),\n } satisfies GraphViewSpec\n },\n }))\n .actions(self => ({\n openGraphView() {\n const spec = self.graphViewSpec\n if (spec) {\n getSession(self).addView('GraphGenomeView', spec)\n }\n },\n }))\n .views(self => ({\n // Which haplotypes a GBZ cut is for: every one in the graph, the\n // assemblies the track names, or a list typed in Settings\n haplotypeMenuItems(): MenuItem[] {\n if (self.adapterConfig.type !== 'GbzBaseSyntenyAdapter') {\n return []\n }\n const lanes = trackLanes(self.parentTrack.configuration)\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n void self.cut()\n }\n return [\n {\n label: 'Haplotypes',\n subMenu: [\n {\n type: 'radio',\n label: 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(lanes\n ? [\n {\n type: 'radio' as const,\n label: `The track's ${lanes.length} assemblies`,\n checked: chosen === undefined,\n onClick: () => {\n recut(undefined)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Chosen in Settings...',\n checked: (chosen?.length ?? 0) > 0,\n onClick: () => {\n this.openSettings()\n },\n },\n ],\n },\n ]\n },\n openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, open: true, onClose },\n ])\n },\n trackMenuItems(): MenuItem[] {\n const launches = self.launchMenuItems()\n pushLaunchViewMenuItem(launches, {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n disabled: !self.graphViewSpec,\n disabledHelpText: 'Zoom in until the track cuts a graph',\n onClick: () => {\n self.openGraphView()\n },\n })\n return [\n ...this.haplotypeMenuItems(),\n ...self.graphMenuItems(),\n {\n label: 'Settings',\n icon: SettingsIcon,\n onClick: () => {\n this.openSettings()\n },\n },\n ...launches,\n ]\n },\n }))\n )\n}\n\nexport type LinearGraphDisplayStateModel = ReturnType<typeof stateModelFactory>\nexport type LinearGraphDisplayModel = Instance<LinearGraphDisplayStateModel>\n// what the track's own settings read, which the menus that open them cannot\n// name without naming themselves\nexport type LinearGraphCutModel = Omit<\n LinearGraphDisplayModel,\n 'trackMenuItems' | 'haplotypeMenuItems' | 'openSettings'\n>\n", "import type { HostWindow } from '../GraphGenomeView/host'\n\n// A cut refused for its node count: the GBZ adapter's own error, marked\n// regionTooLarge so core shows it as a zoom-in notice, or gbz-base's when it\n// reaches the display unwrapped\nexport function isNodeLimitError(error: unknown) {\n return (\n error instanceof Error &&\n (error.name === 'NodeLimitError' ||\n (error as { regionTooLarge?: unknown }).regionTooLarge === true ||\n /reads more than nodeLimit|^Subgraph size limit of \\d+ nodes exceeded/.test(\n error.message,\n ))\n )\n}\n\n// Where a cut came back over its node limit. The graph is as dense as that\n// only near it, so it stands for windows as wide or wider on the same contig\n// within one window-width of it.\nexport interface DenseWindow {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport function denseCovers(dense: DenseWindow | undefined, seen: HostWindow) {\n if (\n dense?.refName !== seen.refName ||\n dense.assemblyName !== seen.assemblyName\n ) {\n return false\n }\n const span = dense.end - dense.start\n return (\n seen.end - seen.start >= span &&\n seen.end > dense.start - span &&\n seen.start < dense.end + span\n )\n}\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema, { normalizeSnapshot } from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function MinigraphBubbleAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'MinigraphBubbleAdapter',\n displayName: 'Minigraph bubble BED adapter',\n normalizeSnapshot,\n configSchema,\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./MinigraphBubbleAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config MinigraphBubbleAdapter\n * #trackType FeatureTrack\n * #fileFormat graph | Minigraph bubble BED | `gfatools bubble` output; HPRC publishes one ready-made, so no preprocessing at all\n * the tabix-indexed BED `gfatools bubble` writes for a minigraph graph: one row\n * per bubble, on the reference's own coordinates. Unlike\n * [RgfaTabixAdapter](/docs/config/rgfatabixadapter) this needs no index build of\n * your own, because HPRC publishes this file beside its minigraph graph.\n *\n * It shows *where* the graph varies and by how much, not the graph itself.\n *\n * #example\n * ```js\n * {\n * type: 'MinigraphBubbleAdapter',\n * uri: 'https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.bubbles.bed.gz',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n bubblesLocation: { uri, baseUri },\n index: {\n indexType: csi ? 'CSI' : 'TBI',\n location: { uri: `${uri}.${csi ? 'csi' : 'tbi'}`, baseUri },\n },\n }\n : snap\n}\n\nconst MinigraphBubbleAdapter = ConfigurationSchema(\n 'MinigraphBubbleAdapter',\n {\n /**\n * #slot\n */\n bubblesLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.bb.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n index: ConfigurationSchema('MinigraphBubbleIndex', {\n /**\n * #slot index.indexType\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot index.location\n */\n location: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.bb.bed.gz.tbi',\n locationType: 'UriLocation',\n },\n },\n }),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix, for when they\n * differ. `gfatools bubble` names each row after the graph's stable\n * sequence, so a Minigraph-Cactus graph yields `GRCh38#0#chr6` and an\n * `hg38` assembly needs `{ hg38: 'GRCh38' }`; HPRC's published v1.0\n * minigraph bubbles are bare (`chr6`) and need nothing.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"MinigraphBubbleAdapter\", \"uri\": \"graph.bb.bed.gz\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type MinigraphBubbleAdapterConfig = Instance<\n typeof MinigraphBubbleAdapter\n>\n\nexport default MinigraphBubbleAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema, { normalizeSnapshot } from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function RgfaTabixAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'RgfaTabixAdapter',\n displayName: 'Indexed rGFA adapter',\n normalizeSnapshot,\n configSchema,\n // what a graph display needs of its track's adapter\n adapterCapabilities: ['getSubgraph'],\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./RgfaTabixAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config RgfaTabixAdapter\n * #trackType GraphTrack\n * #fileFormat graph | Indexed rGFA | Built by `scripts/build_rgfa_tabix.sh`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED projections of an rGFA (minigraph). rGFA tags every\n * segment with `SN`/`SO`/`SR`, so both files record coordinates the graph\n * already states rather than inventing any. Plain GFA (pggb, odgi,\n * Minigraph-Cactus) has no such tags and is not supported.\n *\n * The `uri` shorthand takes the prefix the build script was given and resolves\n * `<uri>.segs.bed.gz`, `<uri>.links.bed.gz` and their `.tbi` indexes. `coarse`\n * takes the same shorthand for a second pair at one node per bubble, built by\n * `build_bubble_tier.sh` in jbrowse-components, plus the zoom past which a\n * graph view following a linear view cuts it.\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * uri: 'https://example.com/hprc.rgfa',\n * coarse: { uri: 'https://example.com/hprc.tier10000', aboveBpPerPx: 1000 },\n * }\n * ```\n */\n\nfunction tbi(uri: string, baseUri: unknown, csi: unknown) {\n return {\n indexType: csi ? 'CSI' : 'TBI',\n location: { uri: `${uri}.${csi ? 'csi' : 'tbi'}`, baseUri },\n }\n}\n\nfunction prefixLocations(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n segmentsLocation: { uri: `${uri}.segs.bed.gz`, baseUri },\n segmentsIndex: tbi(`${uri}.segs.bed.gz`, baseUri, csi),\n linksLocation: { uri: `${uri}.links.bed.gz`, baseUri },\n linksIndex: tbi(`${uri}.links.bed.gz`, baseUri, csi),\n }\n : snap\n}\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri } = snap\n return prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, ...coarse }) }\n : snap,\n )\n}\n\nconst indexSchema = (name: string, defaultUri: string) =>\n ConfigurationSchema(name, {\n /**\n * #slot\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot\n */\n location: {\n type: 'fileLocation',\n defaultValue: { uri: defaultUri, locationType: 'UriLocation' },\n },\n })\n\nconst RgfaTabixCoarseTier = ConfigurationSchema('RgfaTabixCoarseTier', {\n /**\n * #slot\n * The linear view's bp per px past which a graph following it cuts this\n * pair. Unset means the track has no coarse tier. There is no default,\n * because the zoom a fine cut stays drawable to depends on the graph's\n * density: a minigraph graph averages ~7 kb per segment, a base-level pggb\n * graph ~17 bp.\n */\n aboveBpPerPx: { type: 'maybeNumber' },\n /**\n * #slot\n */\n segmentsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.tier.segs.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n segmentsIndex: indexSchema(\n 'RgfaCoarseSegmentsIndex',\n '/path/to/graph.tier.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n */\n linksLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.tier.links.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n linksIndex: indexSchema(\n 'RgfaCoarseLinksIndex',\n '/path/to/graph.tier.links.bed.gz.tbi',\n ),\n})\n\nconst RgfaTabixAdapter = ConfigurationSchema(\n 'RgfaTabixAdapter',\n {\n /**\n * #slot\n * one row per segment: `stableName start end segmentId rank`, as emitted by\n * `gfatools gfa2bed -m`\n */\n segmentsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.segs.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n segmentsIndex: indexSchema(\n 'RgfaSegmentsIndex',\n '/path/to/graph.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n * one row per link per endpoint, each carrying both endpoints in full so a\n * neighbour on another stable sequence needs no segment-id lookup\n */\n linksLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.links.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n linksIndex: indexSchema(\n 'RgfaLinksIndex',\n '/path/to/graph.links.bed.gz.tbi',\n ),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix in the graph, for\n * when they differ. Defaults to identity: the assembly name is assumed to be\n * the PanSN sample name, and a graph whose stable names are bare (minigraph\n * writes `chr1`) needs nothing here at all.\n *\n * Minigraph-Cactus writes PanSN stable names, so HPRC's release-2 graph\n * calls the reference `GRCh38#0#chr1` and an `hg38` assembly needs\n * `{ hg38: 'GRCh38' }`. The prefix is what disambiguates: that same graph\n * also contains `CHM13#0#chr1`, so matching on the contig alone would\n * silently resolve to the wrong sample.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * The same graph at one node per bubble, which a graph view following a\n * linear view cuts once that view is zoomed out past `aboveBpPerPx`, and\n * which no bp cap applies to. `{ uri, aboveBpPerPx }`, where `uri` is a\n * prefix as the adapter's own is.\n */\n coarse: RgfaTabixCoarseTier,\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"uri\": \"graph.rgfa\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type RgfaTabixAdapterConfig = Instance<typeof RgfaTabixAdapter>\n\nexport default RgfaTabixAdapter\n", "import {\n buildAdapterConfig,\n isSegmentsLocation,\n locationName,\n} from '../GraphAddTrackWorkflow/buildTrackConfig'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { FileLocation } from '@jbrowse/core/util'\nimport type {\n AdapterGuesser,\n TrackTypeGuesser,\n} from '@jbrowse/core/util/tracks'\n\ninterface TrackConfigSnapshot {\n displays?: { type?: string; [key: string]: unknown }[]\n [key: string]: unknown\n}\n\nconst GRAPH_ADAPTERS = new Set(['RgfaTabixAdapter', 'GbzBaseSyntenyAdapter'])\n\nexport function isGbzLocation(loc: FileLocation) {\n return locationName(loc).toLowerCase().endsWith('.gbz.db')\n}\n\n// A gbz-base adapter cuts on the first assembly it names. A track added\n// through Add track names that assembly on the track alone.\nexport function withGbzAnchor(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n { type?: string; assemblyNames?: unknown[] } | undefined\n return adapter?.type === 'GbzBaseSyntenyAdapter' &&\n !adapter.assemblyNames?.length &&\n Array.isArray(snap.assemblyNames) &&\n snap.assemblyNames.length > 0\n ? { ...snap, adapter: { ...adapter, assemblyNames: snap.assemblyNames } }\n : snap\n}\n\nexport function guessGraphAdapter(\n file: FileLocation,\n index?: FileLocation,\n adapterHint?: string,\n) {\n if (\n (!adapterHint || adapterHint === 'GbzBaseSyntenyAdapter') &&\n isGbzLocation(file)\n ) {\n return {\n type: 'GbzBaseSyntenyAdapter',\n gbzDbLocation: file,\n ...(index ? { haplotypeIndexLocation: index } : {}),\n }\n }\n if (\n (!adapterHint || adapterHint === 'RgfaTabixAdapter') &&\n isSegmentsLocation(file)\n ) {\n return buildAdapterConfig({\n choice: 'RgfaTabixAdapter',\n loc: file,\n indexLoc: index,\n assembly: '',\n sample: '',\n })\n }\n return undefined\n}\n\nexport default function GraphTrackDefaultsF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-preProcessTrackConfig', withGbzAnchor)\n pluginManager.addToExtensionPoint(\n 'Core-guessAdapterForLocation',\n (next: AdapterGuesser): AdapterGuesser =>\n (file, index, adapterHint) =>\n guessGraphAdapter(file, index, adapterHint) ??\n next(file, index, adapterHint),\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessTrackTypeForLocation',\n (next: TrackTypeGuesser): TrackTypeGuesser =>\n (adapterName, file) =>\n GRAPH_ADAPTERS.has(adapterName)\n ? 'GraphTrack'\n : next(adapterName, file),\n )\n}\n", "import { getSession } from '@jbrowse/core/util'\nimport { alpha } from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\nimport { graphViewHighlights } from './graphViewHighlights'\n\nimport type { HighlightRegion } from './graphViewHighlights'\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst useStyles = makeStyles()(theme => ({\n highlight: {\n height: '100%',\n position: 'absolute',\n background: alpha(theme.palette.primary.main, 0.25),\n borderLeft: `2px solid ${theme.palette.primary.main}`,\n borderRight: `2px solid ${theme.palette.primary.main}`,\n pointerEvents: 'none',\n zIndex: 10,\n },\n}))\n\n// One band over the linear view for a hovered graph node. `getHighlightCoords`\n// is the LGV's own projection \u2014 it canonicalizes the refName and floors the\n// width to 3 px, so a pure insertion (a zero-length reference span) still shows\n// as a mark rather than vanishing.\nconst Highlight = observer(function Highlight({\n model,\n region,\n}: {\n model: LinearGenomeViewModel\n region: HighlightRegion\n}) {\n const { classes } = useStyles()\n const coords = model.getHighlightCoords(region)\n return coords ? (\n <div\n data-testid=\"graph-node-highlight\"\n className={classes.highlight}\n style={{ left: coords.left, width: coords.width }}\n />\n ) : null\n})\n\nconst GraphNodeHighlight = observer(function GraphNodeHighlight({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { views } = getSession(model)\n return (\n <>\n {graphViewHighlights([...views], model.id, model.assemblyNames).map(\n ({ key, region }) => (\n <Highlight key={`graph-hover-${key}`} model={model} region={region} />\n ),\n )}\n </>\n )\n})\n\nexport default GraphNodeHighlight\n", "import { isRecord } from '../isRecord'\nimport { withRows } from '../launchFromGraph/linearViewTarget'\n\nexport interface HighlightRegion {\n refName: string\n start: number\n end: number\n assemblyName?: string\n}\n\nexport interface GraphViewHighlight {\n key: string\n region: HighlightRegion\n}\n\nfunction readRegion(value: unknown): HighlightRegion | undefined {\n let region: HighlightRegion | undefined\n if (isRecord(value)) {\n const { refName, start, end, assemblyName } = value\n if (\n typeof refName === 'string' &&\n typeof start === 'number' &&\n typeof end === 'number'\n ) {\n region = {\n refName,\n start,\n end,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n }\n }\n }\n return region\n}\n\n// Whether a graph view's highlights belong on a given linear view.\n// `connectedViewId` is written by the launch menu, so a launched pair is\n// explicit. A graph view without one \u2014 a hand-written session snapshot, or\n// `Add > Graph genome view` followed by a subgraph load \u2014 matches any linear\n// view, because the alternative is silently drawing nothing.\n//\n// So does one whose linear view has been closed. Held to an id nothing answers\n// to, it matched no view and its hover drew nowhere for the rest of the\n// session, the view it next opened included.\nfunction isConnected(\n view: Record<string, unknown>,\n linearViewId: string,\n liveViewIds: ReadonlySet<unknown>,\n) {\n const connectedViewId = view.connectedViewId\n return (\n connectedViewId === undefined ||\n connectedViewId === linearViewId ||\n !liveViewIds.has(connectedViewId)\n )\n}\n\n// ...and whether the view can mean anything by it. `getHighlightCoords`\n// canonicalizes a refName against the region's OWN assembly and then lays it\n// out against this view's displayed regions, without ever asking whether the\n// two are the same assembly \u2014 so a band handed to the wrong view is drawn, at\n// coordinates that belong to somebody else's genome.\n//\n// That is not hypothetical for an unpaired graph, which by the rule above\n// matches every linear view in the session. A synteny stack's rows are LGVs on\n// different assemblies, and a PanSN name reduces to a bare contig: the five\n// E. coli strains each have one refName `chr`, so a graph cut from K12 painted\n// its K12 interval across Sakai's row and CFT073's at their own offsets. With\n// the assembly checked the reference row keeps the band and the rest correctly\n// draw nothing.\n//\n// A region stating no assembly still passes \u2014 `readRegion` leaves it optional,\n// and the fallback is the behaviour every existing snapshot has.\nfunction isOnAssembly(\n region: HighlightRegion,\n assemblyNames: string[] | undefined,\n) {\n return (\n region.assemblyName === undefined ||\n assemblyNames === undefined ||\n assemblyNames.includes(region.assemblyName)\n )\n}\n\n// The graph displays in a linear view's own tracks, connected to it by where\n// they sit.\nfunction trackGraphs(view: Record<string, unknown>) {\n const tracks = Array.isArray(view.tracks) ? view.tracks : []\n return tracks.flatMap((track: unknown) =>\n isRecord(track) && Array.isArray(track.displays)\n ? track.displays.filter(\n (display: unknown) =>\n isRecord(display) && display.type === 'LinearGraphDisplay',\n )\n : [],\n ) as Record<string, unknown>[]\n}\n\n// The highlights a linear view should draw for the graph views connected to it.\n// Reads `session.views` structurally: the members it needs are declared by\n// GraphGenomeView, not by the AbstractViewModel the session array is typed as.\nexport function graphViewHighlights(\n views: unknown[],\n linearViewId: string,\n // the drawing view's own assemblies, so a band is only drawn where its\n // coordinates mean something \u2014 see isOnAssembly\n linearAssemblyNames?: string[],\n): GraphViewHighlight[] {\n const highlights: GraphViewHighlight[] = []\n const candidates = withRows(views)\n const liveViewIds = new Set(\n candidates.map(view => (isRecord(view) ? view.id : undefined)),\n )\n for (const view of candidates) {\n if (isRecord(view) && view.id === linearViewId) {\n for (const display of trackGraphs(view)) {\n const region = readRegion(display.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof display.id === 'string' ? display.id : 'graph-track',\n region,\n })\n }\n }\n }\n if (\n isRecord(view) &&\n view.type === 'GraphGenomeView' &&\n isConnected(view, linearViewId, liveViewIds)\n ) {\n const region = readRegion(view.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof view.id === 'string' ? view.id : 'graph',\n region,\n })\n }\n }\n }\n return highlights\n}\n", "import GraphNodeHighlight from './GraphNodeHighlight'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The graph-to-linear half of the hover sync. The reverse half needs no mount\n// point: an LGV already publishes its hover to `session.hovered`, and the graph\n// view's own autorun reads it (see GraphGenomeView/model.ts).\n//\n// Mounted through the extension point rather than imported by the LGV, so this\n// plugin never imports @jbrowse/plugin-linear-genome-view at runtime: it is not\n// one of JBrowse's shared globals, so a value import would bundle a second copy\n// of that whole plugin.\nconst POINT = 'LinearGenomeView-TracksContainerComponent'\n\nexport default function GraphHoverSyncF(pluginManager: PluginManager) {\n pluginManager.contributeToExtensionPoint(POINT, ({ model }) => (\n <GraphNodeHighlight key=\"graphgenomeview-hover-highlight\" model={model} />\n ))\n}\n", "import { DisplayType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { trackAdapterConfig } from './trackAdapterConfig'\nimport { SYNTENY_DISPLAYS } from '../GraphTrack/index'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\n// Core's synteny displays send `adapterConfig` with every request, the lane\n// listing's included, so overriding the getter reaches them all\nfunction withTrackAdapterConfig(model: IAnyModelType) {\n return model.views(self => ({\n get adapterConfig(): Record<string, unknown> {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n }))\n}\n\nexport default function PanSNAliasesF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-extendPluggableElement', element => {\n if (\n element instanceof DisplayType &&\n SYNTENY_DISPLAYS.includes(element.name)\n ) {\n element.extendStateModel(withTrackAdapterConfig)\n }\n return element\n })\n}\n", "// The name JBrowse knows this plugin by, which a config's `plugins` entry\n// states beside its `esmUrl`.\nexport const PLUGIN_NAME = 'GraphGenomeView'\n", "export const version = '6.2.0'\n"],
5
- "mappings": "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",
3
+ "sources": ["global-externals:@jbrowse/core/Plugin", "global-externals:@jbrowse/core/pluggableElementTypes/AdapterType", "global-externals:@jbrowse/core/configuration", "global-externals:@jbrowse/core/data_adapters/dataAdapterCache", "global-externals:@jbrowse/core/pluggableElementTypes", "global-externals:@jbrowse/core/pluggableElementTypes/ViewType", "global-externals:@jbrowse/core/util/withLaunchInput", "global-externals:@jbrowse/core/pluggableElementTypes/models", "global-externals:@jbrowse/render-core/RenderLifecycleMixin", "global-externals:@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain", "global-externals:@jbrowse/core/pluggableElementTypes/DisplayType", "global-externals:@jbrowse/display-kit/trackHeightConfigSchemaFields", "global-externals:@jbrowse/display-kit/TrackHeightMixin", "global-externals:@jbrowse/render-core/displayPhase", "../src/index.ts", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/BubbleChart.mjs", "../src/GbzBaseSyntenyAdapter/index.ts", "../src/GbzBaseSyntenyAdapter/configSchema.ts", "../src/GetGraphReads.ts", "../src/GetSubgraph.ts", "../src/GraphAddTrackWorkflow/index.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-7XHHVYG7.js", "../src/GraphComputeLayout.ts", "../src/GraphGenomeView/index.ts", "../src/GraphGenomeView/viewModel.ts", "../src/GraphGenomeView/pane/launchActions.ts", "../src/GraphGenomeView/pane/paneBase.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-IGVV37VI.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-PUG7LXDF.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-CDLPYR5O.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-72N5DJHZ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-JVLURPFW.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-WZATPZNH.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XVSBZ4ZW.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4UBWXZVX.js", "../src/GraphGenomeView/lenientEnum.ts", "../src/GraphGenomeView/pane/renderingActions.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-VHW7FDHU.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/layout/trimToWindow.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/tubeMap/coarsen.js", "../src/GraphGenomeView/pane/loadActions.ts", "../src/GraphGenomeView/pane/settingActions.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-LOCJN3BZ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-47DYCZOK.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BUBZ32IC.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-3LXG54PN.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XMNHWMGM.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-5ARDFGLJ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-H5S2ONCJ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KQFOCDFY.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-VZQ4FKLR.js", "../src/GraphGenomeView/pane/fitViews.ts", "../src/GraphGenomeView/host.ts", "../src/GraphGenomeView/pane/launchViews.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-ISEI2FH3.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4S47XRYA.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KEVQ46GG.js", "../src/GraphGenomeView/pane/graphViews.ts", "../src/panSNAliases/trackAdapterConfig.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BXEPA4KS.js", "../src/GraphGenomeView/genes/geneFeatures.ts", "../src/GraphGenomeView/repeats/repeatFeatures.ts", "../src/launchFromGraph/launchFromGraph.ts", "../src/isRecord.ts", "../src/launchFromGraph/linearViewTarget.ts", "../src/GraphGenomeView/pane/walkRowViews.ts", "../src/GraphGenomeView/pane/hostViews.ts", "../src/hoverSync/lgvHover.ts", "../src/hoverSync/rowWalks.ts", "../src/launchFromGraph/launchTracks.ts", "../src/launchFromGraph/syntenyTracks.ts", "../src/GraphGenomeView/download.ts", "../src/GraphGenomeView/model.ts", "../src/graphTrackConfig.ts", "../src/GraphTrack/index.ts", "../src/LaunchGraphGenomeView.ts", "../src/LinearGraphDisplay/index.ts", "../src/LinearGraphDisplay/configSchema.ts", "../src/LinearGraphDisplay/model.ts", "../src/LinearGraphDisplay/denseWindow.ts", "../src/MinigraphBubbleAdapter/index.ts", "../src/MinigraphBubbleAdapter/configSchema.ts", "../src/RgfaTabixAdapter/index.ts", "../src/RgfaTabixAdapter/configSchema.ts", "../src/graphTrackDefaults/index.ts", "../src/hoverSync/GraphNodeHighlight.tsx", "../src/hoverSync/graphViewHighlights.ts", "../src/hoverSync/index.tsx", "../src/panSNAliases/index.ts", "../src/pluginName.ts", "../src/version.ts"],
4
+ "sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/Plugin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/AdapterType\"];", "module.exports = JBrowseExports[\"@jbrowse/core/configuration\"];", "module.exports = JBrowseExports[\"@jbrowse/core/data_adapters/dataAdapterCache\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"];", "module.exports = JBrowseExports[\"@jbrowse/core/util/withLaunchInput\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/models\"];", "module.exports = JBrowseExports[\"@jbrowse/render-core/RenderLifecycleMixin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/TrackHeightMixin\"];", "module.exports = JBrowseExports[\"@jbrowse/render-core/displayPhase\"];", "import Plugin from '@jbrowse/core/Plugin'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\n\nimport GbzBaseSyntenyAdapterF from './GbzBaseSyntenyAdapter/index'\nimport GetGraphReads from './GetGraphReads'\nimport GetSubgraph from './GetSubgraph'\nimport GraphAddTrackWorkflowF from './GraphAddTrackWorkflow/index'\nimport GraphComputeLayout from './GraphComputeLayout'\nimport GraphGenomeViewF from './GraphGenomeView/index'\nimport GraphTrackF from './GraphTrack/index'\nimport LaunchGraphGenomeViewF from './LaunchGraphGenomeView'\nimport LinearGraphDisplayF from './LinearGraphDisplay/index'\nimport MinigraphBubbleAdapterF from './MinigraphBubbleAdapter/index'\nimport RgfaTabixAdapterF from './RgfaTabixAdapter/index'\nimport GraphTrackDefaultsF from './graphTrackDefaults/index'\nimport GraphHoverSyncF from './hoverSync/index'\nimport PanSNAliasesF from './panSNAliases/index'\nimport { PLUGIN_NAME } from './pluginName'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class GraphGenomeViewPlugin extends Plugin {\n name = PLUGIN_NAME\n version = version\n\n install(pluginManager: PluginManager) {\n GraphGenomeViewF(pluginManager)\n LinearGraphDisplayF(pluginManager)\n GraphTrackF(pluginManager)\n LaunchGraphGenomeViewF(pluginManager)\n GraphHoverSyncF(pluginManager)\n RgfaTabixAdapterF(pluginManager)\n MinigraphBubbleAdapterF(pluginManager)\n GbzBaseSyntenyAdapterF(pluginManager)\n GraphAddTrackWorkflowF(pluginManager)\n GraphTrackDefaultsF(pluginManager)\n PanSNAliasesF(pluginManager)\n pluginManager.addRpcMethod(() => new GraphComputeLayout(pluginManager))\n pluginManager.addRpcMethod(() => new GetSubgraph(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphReads(pluginManager))\n }\n\n // A throw from configure() takes the whole session to its error page, and a\n // menu entry is not worth that: hubs 1.0.9 did exactly this to every\n // jbrowse.org/ucsc launch by appending to a menu a released host defines as\n // a function. The view is still reachable without the entry.\n configure(pluginManager: PluginManager) {\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n onClick: (session: AbstractSessionModel) => {\n session.addView('GraphGenomeView', {})\n },\n })\n }\n } catch (e) {\n console.warn('[GraphGenomeView] could not add the Add menu entry', e)\n }\n }\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"7.2\",\n cy: \"14.4\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"14.8\",\n cy: \"18\",\n r: \"2\"\n}, \"1\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"15.2\",\n cy: \"8.8\",\n r: \"4.8\"\n}, \"2\")], 'BubbleChart');", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function GbzBaseSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'GbzBaseSyntenyAdapter',\n displayName: 'gbz-base pangenome adapter',\n configSchema,\n // The same opened database serves the graph display's subgraph.\n // headerLanes: getHeader declares every haplotype as a lane, which is\n // what makes MultiWaySyntenyDisplay read the header of an untiered\n // adapter and offer its lane picker over the whole graph.\n // lanePairsOnAnchor: a window of the anchor answers any two lanes'\n // alignment to each other, so the display fetches each adjacent pair\n // rather than composing it through the reference.\n // lanePairBatches: every pair on a window comes from one cut\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./GbzBaseSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { GBZ_CUT_DEFAULTS } from '@jbrowse/bandage-core/gbzWindow'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config GbzBaseSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | gbz-base pangenome database | Haplotype alignments read from the graph at query time, no PAF conversion\n * Serves a pangenome graph stored as a gbz-base SQLite database (`.gbz.db`) as\n * haplotype-versus-reference alignments, the shape `MultiWaySyntenyDisplay`\n * draws as one lane per haplotype. A window on the reference is located on the\n * graph's reference path, every haplotype's walk through the nodes it covers\n * is recovered and named, and each haplotype becomes one alignment record with\n * a CIGAR, so the graph is read through HTTP range requests with no offline\n * conversion. Naming the walks takes the companion haplotype index that\n * `gbz-haplotype-index` writes; without it the graph cannot say which\n * haplotype a walk belongs to.\n *\n * Only the fine tier exists: a whole-chromosome view stays on a PIF's coarse\n * tier. A query on a haplotype lane answers nothing, so the multi-way display\n * composes its lane-to-lane links through the reference.\n *\n * #example\n * ```js\n * {\n * type: 'GbzBaseSyntenyAdapter',\n * uri: 'hprc-v2.gbz.db',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38#0' },\n * }\n * ```\n */\nconst GbzBaseSyntenyAdapter = ConfigurationSchema(\n 'GbzBaseSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the graph's reference\n * sample is loaded as. A haplotype needs no entry: its lane draws on the\n * session assembly named or aliased by its PanSN prefix (`HG002.1` with the\n * alias `HG002#1`), or the one `assemblyNameToPanSN` maps to it. A further\n * entry names an assembly by its sample (`HG002`), which takes both of the\n * sample's lanes. A haplotype with no assembly is still a lane, labelled by\n * its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * The `.gbz.db` written by `gbz-base construct`; read by HTTP range\n * requests, so it can be large.\n */\n gbzDbLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.gbz.db',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * The haplotype index `gbz-haplotype-index` writes beside the graph\n * database, which names its walks. One with stray rows (the tool from\n * 0.2.0) lets a fetch for a chosen set of lanes walk only those\n * haplotypes. Empty means `graph.haplotype-index.db` beside\n * `graph.gbz.db` if there is one; otherwise the walks go unnamed.\n */\n haplotypeIndexLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * Reads aligned to the graph as GAF, which the tube map layouts draw under\n * the haplotypes. Its segment names have to be the cut's: numeric node ids,\n * or `vg giraffe --named-coordinates` on a graph whose segments were\n * renamed or chopped. Empty means no reads.\n */\n readsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * The `tabix -p gaf` index of a bgzipped `readsLocation`, which fetches the\n * reads over each window's node ids. Empty reads the GAF whole, up to 50 MB.\n */\n readsIndex: ConfigurationSchema('GbzBaseReadsIndex', {\n /**\n * #slot\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot\n */\n location: {\n type: 'fileLocation',\n defaultValue: { uri: '', locationType: 'UriLocation' },\n },\n }),\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by (\"Group by\u2026\"). Its header row names the columns\n * (`population`, `superpopulation`, ...), and its first column is the\n * walk's sample (`HG00097`) or haplotype (`HG00097#1`). Empty means no\n * grouping.\n */\n samplesTsvLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n * How the graph view's subgraph is extended past the nodes the reference\n * window touches. `contained` adds every top-level snarl with both\n * boundary nodes in the window, which is what brings back the bubbles a\n * reference-only walk leaves out; a haplotype still breaks into a new W\n * line wherever it leaves the window's nodes (a 60 kb C4 window on the\n * HPRC graph: 2,703 nodes, 8,083 walks for 464 haplotypes). `overlapping`\n * also follows snarls that leave the window, so every haplotype is one\n * walk (464), at the price of every node in those snarls (4,184 there,\n * 24,547 across the KIV-2 repeat). `none` leaves only the bp `context`.\n */\n subgraphSnarls: {\n type: 'stringEnum',\n model: types.enumeration('SnarlOutput', [\n 'none',\n 'contained',\n 'overlapping',\n ]),\n defaultValue: GBZ_CUT_DEFAULTS.snarls,\n },\n /**\n * #slot\n * The graph sample the anchor window is located on. Empty means the sample\n * the anchor's PanSN prefix names, or the database's one reference sample\n * (`gbwt_reference_samples`) when the anchor names none; a database with\n * several reference samples then needs this set.\n */\n referenceSample: {\n type: 'string',\n defaultValue: '',\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38#0', 'HG002.1': 'HG002#1' }`). Each\n * session assembly with a `sample#haplotype` alias (`HG002#1`) is mapped to\n * it already, so this is the override: an entry takes its prefix from any\n * assembly aliased to it. An assembly in neither maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * Graph context around the window, in bp, on top of `subgraphSnarls`: the\n * cut, its reference walk and every haplotype walk extend this far past\n * the window on each side. A haplotype walk breaks into pieces wherever it\n * leaves the cut's nodes, so context and snarls together decide whether a\n * lane's bubble is one record or several. A window inside a snarl far\n * larger than itself (MHC class II on the HPRC graph, 90 kb) is 1.1M pieces\n * at 0 and 464 walks at 1000, three times faster.\n */\n context: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.context,\n advanced: true,\n },\n /**\n * #slot\n * The most graph nodes one window may load before the query fails rather\n * than reading a whole chromosome into the worker.\n */\n nodeLimit: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.limit,\n advanced: true,\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n *\n * preprocessor to allow minimal config, where a `.gz` `reads` is taken to\n * be bgzipped with a `.tbi` beside it:\n * ```json\n * {\n * \"type\": \"GbzBaseSyntenyAdapter\",\n * \"uri\": \"graph.gbz.db\",\n * \"reads\": \"reads.gaf.gz\",\n * \"assemblyNames\": [\"hg38\"]\n * }\n * ```\n */\n preProcessSnapshot: snap => {\n const { uri, baseUri, reads } = snap\n return {\n ...snap,\n ...(uri ? { gbzDbLocation: { uri, baseUri } } : {}),\n ...(typeof reads === 'string'\n ? {\n readsLocation: { uri: reads, baseUri },\n ...(reads.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${reads}.tbi`, baseUri } } }\n : {}),\n }\n : {}),\n }\n },\n },\n)\n\nexport type GbzBaseSyntenyAdapterConfig = Instance<typeof GbzBaseSyntenyAdapter>\n\nexport default GbzBaseSyntenyAdapter\n", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { GafReads } from './gaf/gafFile'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The reads aligned over a cut's segments, from an adapter whose config names\n// a GAF (GbzBaseSyntenyAdapter's `readsLocation`). Asked after the cut is\n// parsed, because the segment names are what a GAF index is keyed by.\n\nexport interface GetGraphReadsArgs {\n adapterConfig: Record<string, unknown>\n nodeNames: string[]\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphReads: {\n args: GetGraphReadsArgs\n return: GafReads\n }\n }\n}\n\ninterface ReadsAdapter {\n getReads(\n nodeNames: string[],\n opts: { signal?: AbortSignal },\n ): Promise<GafReads>\n}\n\nfunction isReadsAdapter(adapter: object): adapter is ReadsAdapter {\n return (\n 'getReads' in adapter &&\n typeof (adapter as ReadsAdapter).getReads === 'function'\n )\n}\n\nconst isNamed = (location: unknown) =>\n typeof location === 'object' &&\n location !== null &&\n Object.entries(location).some(\n ([key, value]) =>\n ['uri', 'localPath', 'blobId'].includes(key) &&\n typeof value === 'string' &&\n value !== '',\n )\n\n// Whether an adapter config as written names reads, so a graph without them\n// makes no round trip to ask\nexport function namesReads(adapterConfig: Record<string, unknown>) {\n return (\n (typeof adapterConfig.reads === 'string' && adapterConfig.reads !== '') ||\n isNamed(adapterConfig.readsLocation)\n )\n}\n\nexport default class GetGraphReads extends RpcMethodType<'GetGraphReads'> {\n name = 'GetGraphReads' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphReads'>) {\n const { adapterConfig, nodeNames, sessionId, signal } = args\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n return isReadsAdapter(dataAdapter)\n ? dataAdapter.getReads(nodeNames, { signal })\n : { records: [], total: 0 }\n }\n}\n", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\nimport { RpcMethodTypeWithRenameRegion } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\nimport type { Region } from '@jbrowse/core/util'\n\n// No `sessionId`, `signal` or `statusCallback` here: those belong to the\n// CALL, not to this payload, and core's `EntriesDeclaringCallLevelFields` fails\n// the build for a registry entry that declares one. `execute` still receives\n// them, because `RpcExecuteArgs` intersects `RpcCallContext` in.\n// `hops` is how far past the window a cut follows links, which only the rGFA\n// cut reads; the GBZ cut has its own bp `context` slot. `haplotypes` is the\n// set the cut is for, lane assembly names or PanSN prefixes, which only the GBZ\n// cut reads: it keeps those walks and the nodes they visit. Undefined or empty\n// is every haplotype. `tier` picks which of an rGFA track's two index pairs the\n// cut reads, the adapter's own or its `coarse` one; fine when absent.\nexport type SubgraphTier = 'fine' | 'coarse'\n\nexport interface SubgraphCutOptions {\n hops?: number\n haplotypes?: string[]\n tier?: SubgraphTier\n // which snarls a GBZ cut follows past the window, over the track's\n // `subgraphSnarls`; 'overlapping' when the layout measures whole walks\n snarls?: 'none' | 'contained' | 'overlapping'\n}\n\n// What an adapter's cut is handed: the payload, plus the call's own signal so\n// a cut the view has moved on from stops reading.\nexport interface SubgraphAdapterOptions extends SubgraphCutOptions {\n signal?: AbortSignal\n}\n\nexport interface SubgraphRegion {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport interface GetSubgraphArgs {\n adapterConfig: Record<string, unknown>\n region: Region\n opts?: SubgraphCutOptions\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetSubgraph: {\n args: GetSubgraphArgs\n return: string\n }\n }\n}\n\n// Adapters that can cut a local subgraph out of a graph file implement this:\n// RgfaTabixAdapter and GbzBaseSyntenyAdapter today.\ninterface SubgraphAdapter {\n getSubgraph(region: Region, opts?: SubgraphAdapterOptions): Promise<string>\n}\n\nfunction isSubgraphAdapter(adapter: object): adapter is SubgraphAdapter {\n return (\n 'getSubgraph' in adapter &&\n typeof (adapter as SubgraphAdapter).getSubgraph === 'function'\n )\n}\n\n// RpcMethodTypeWithRenameRegion, not the plain RpcMethodType: the base class is\n// what maps `region.refName` from the assembly's spelling onto the adapter's own\n// before the call crosses to the worker. Without it a launch on an hg38 whose\n// contigs are bare (`6`, which is what every GRCh38 FASTA on jbrowse.org uses)\n// asked RgfaTabixAdapter for `GRCh38#0#6`, matched nothing, and opened a view\n// reading \"0 nodes, 0 edges\" with no error. The segments track drew the whole\n// time, because CoreGetFeatures renames and this did not, so the graph looked\n// broken while its own track looked fine. `assemblyNameToPanSN` covers the\n// sample half of a PanSN name only; the contig half is refName aliasing, which\n// the assembly already knows and this now consults.\nexport default class GetSubgraph extends RpcMethodTypeWithRenameRegion<'GetSubgraph'> {\n name = 'GetSubgraph' as const\n\n // Parameterized by the registry key, not left at the default `string`: a bare\n // RpcMethodTypeWithRenameRegion resolves RpcExecuteArgs to `unknown`, so\n // `execute` type-checks against nothing at all. `invoke` has already run\n // `deserializeArguments` by the time this is called, so it does not.\n async execute(args: RpcExecuteArgs<'GetSubgraph'>) {\n // `signal` arrives on every call and has to be named to be forwarded:\n // unnamed, a cut the view had replaced went on querying to the end, one\n // tabix read per off-reference segment per hop.\n const { adapterConfig, region, sessionId, opts, signal } = args\n\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n if (isSubgraphAdapter(dataAdapter)) {\n return dataAdapter.getSubgraph(region, { ...opts, signal })\n }\n // An empty result is how the view and the launch menu detect \"this track\n // can't do subgraphs\" \u2014 see the pane's cutSubgraph.\n console.warn(\n `[GetSubgraph] ${dataAdapter.constructor.name} does not implement getSubgraph`,\n )\n return ''\n }\n}\n", "import { lazy } from 'react'\n\nimport { AddTrackWorkflowType } from '@jbrowse/core/pluggableElementTypes'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst GraphAddTrackWidget = lazy(() => import('./AddTrackWorkflow'))\n\nexport default function GraphAddTrackWorkflowF(pluginManager: PluginManager) {\n pluginManager.addAddTrackWorkflowType(\n () =>\n new AddTrackWorkflowType({\n name: 'Pangenome graph track',\n displayName: 'Add pangenome graph track',\n ReactComponent: GraphAddTrackWidget,\n stateModel: types.model({}),\n }),\n )\n}\n", "// src/loadBandage.ts\nvar cached;\nfunction loadBandage() {\n cached ??= import(\"./bandage-layout-3AR6BCUD.js\").then((mod) => mod.default()).catch((e) => {\n cached = void 0;\n throw e;\n });\n return cached;\n}\n\nexport {\n loadBandage\n};\n", "import loadBandage from '@jbrowse/bandage-core/loadBandage'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The payload is the pipeline's EngineRequest, the same request a standalone\n// page hands the engine. `sessionId` and `statusCallback` are the CALL's, not\n// the payload's: core's `EntriesDeclaringCallLevelFields` fails the build for a\n// registry entry that declares either. `execute` still receives both, through\n// `RpcExecuteArgs`'s intersection with `RpcCallContext`.\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GraphComputeLayout: {\n args: EngineRequest\n return: { result: LayoutResult; duration: number }\n }\n }\n}\n\nexport default class GraphComputeLayout extends RpcMethodType<'GraphComputeLayout'> {\n name = 'GraphComputeLayout' as const\n\n async execute(args: RpcExecuteArgs<'GraphComputeLayout'>) {\n const { graph, options, statusCallback } = args\n\n statusCallback?.('Loading layout engine')\n const module = await loadBandage()\n\n statusCallback?.('Computing layout')\n const startTime = performance.now()\n const result = module.computeLayout(graph, options)\n const duration = performance.now() - startTime\n\n return { result, duration }\n }\n}\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\nimport { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput'\n\nimport modelFactory from './viewModel'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// This view has NO launch keys, and saying so is what turns the check on.\n//\n// A launch key is a spec field the launcher interprets rather than assigns \u2014 an\n// LGV's `assembly` and `loc`, resolved into `displayedRegions`. Every field of\n// a graph launch is a plain persisted prop instead (see\n// LaunchGraphGenomeView), so the registration is empty; what it buys is\n// `ViewType.acceptedKeys`, which is `undefined` until a view declares its\n// launch vocabulary, and which `loadSessionSpec` needs to report\n// `ignored unknown key(s)`.\n//\n// Without it a session spec's typo in a GraphGenomeView entry is silent: the\n// key lands in the snapshot, MST drops it, and the view opens on the import\n// form with nothing said. That surface is written by hand with no compiler\n// behind it \u2014 `sessionSpec()` takes a bare `object` \u2014 and the docs build two\n// dozen graph figures through it, `loadedRegion` and `loadedTrackId` among the\n// fields a misspelling would silently cost.\n//\n// Ignored by a host that predates `acceptedKeys`: its ViewType constructor\n// reads the options it knows and this is not one of them.\nconst graphLaunchKeys = defineLaunchKeys<object>()({})\n\nexport default function GraphGenomeViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'GraphGenomeView',\n displayName: 'Graph genome view',\n stateModel: modelFactory(),\n launchKeys: graphLaunchKeys,\n ReactComponent: lazy(() => import('./components/GraphGenomeView')),\n })\n })\n}\n", "import { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer, types } from '@jbrowse/mobx-state-tree'\nimport { reaction } from 'mobx'\n\nimport { GraphPaneMixin, MAX_GRAPH_REGION_BP, formatSpanBp } from './model'\nimport {\n graphReferenceAssembly,\n offReferenceProblem,\n} from '../graphTrackConfig'\nimport { trackAdapterConfig } from '../panSNAliases/trackAdapterConfig'\n\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n// the last segment of a file's path, its query dropped, or a blob's own name\nfunction fileName(location: FileLocation) {\n const path =\n 'uri' in location\n ? location.uri.split(/[?#]/)[0]!\n : 'localPath' in location\n ? location.localPath\n : 'name' in location\n ? location.name\n : ''\n return path.split(/[\\\\/]/).at(-1) ?? ''\n}\n\nexport default function stateModelFactory() {\n return types\n .compose(\n 'GraphGenomeView',\n BaseViewModel,\n GraphPaneMixin(),\n types.model({\n type: types.literal('GraphGenomeView'),\n // a whole GFA the view loads on attach, kept so the source round-trips\n // through a session snapshot\n gfaLocation: types.maybe(types.frozen<FileLocation>()),\n // the reference window the file or the cut was stated beside\n loadedRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // A session track the view cuts `loadedRegion` from once, as 4.0\n // sessions and the docs' figure specs state it. Following the linear\n // view is the track's job (LinearGraphDisplay).\n loadedTrackId: types.optional(types.string, ''),\n subgraphContext: types.optional(types.number, 1),\n subgraphHaplotypes: types.maybe(types.frozen<string[]>()),\n maxRegionBp: types.optional(types.number, MAX_GRAPH_REGION_BP),\n }),\n )\n .views(self => ({\n get rpcSessionId() {\n return self.id\n },\n // a view is not its own containing view\n get paneWidth() {\n return self.width\n },\n get cutHaplotypes() {\n return self.subgraphHaplotypes\n },\n get sourceGfaLocation() {\n return self.gfaLocation\n },\n get sourceTrack(): AnyConfigurationModel | undefined {\n return self.loadedTrackId\n ? getSession(self).tracks.find(t => t.trackId === self.loadedTrackId)\n : undefined\n },\n get canRetryLoad() {\n return (\n self.gfaLocation !== undefined ||\n (self.loadedTrackId !== '' && self.loadedRegion !== undefined)\n )\n },\n }))\n .views(self => ({\n get hasPendingSource() {\n return self.canRetryLoad && !self.graph && !self.loadCanceled\n },\n menuItems() {\n return self.launchMenuItems()\n },\n }))\n .actions(self => {\n const clearPane = self.clearGraph\n return {\n // the stated source goes too, or a reloaded session would load the\n // dismissed graph again\n clearGraph() {\n clearPane()\n self.gfaLocation = undefined\n self.loadedRegion = undefined\n self.loadedTrackId = ''\n },\n load() {\n const region = self.loadedRegion\n if (self.gfaLocation) {\n // a whole file has no assembly to name the view by\n if (!self.displayName) {\n self.setDisplayName(fileName(self.gfaLocation))\n }\n return self.loadGFAFromLocation(self.gfaLocation, region)\n }\n if (!self.loadedTrackId || !region) {\n return\n }\n const track = self.sourceTrack\n const span = region.end - region.start\n const problem = track\n ? offReferenceProblem(\n graphReferenceAssembly(track),\n region.assemblyName,\n )\n : undefined\n if (!track) {\n self.setError(\n new Error(\n `The track this graph was cut from, \"${self.loadedTrackId}\", is not in this session`,\n ),\n )\n } else if (problem) {\n self.setError(new Error(problem))\n } else if (span > self.maxRegionBp) {\n self.setError(\n new Error(\n `Region too large (${formatSpanBp(span)}) \u2014 zoom in to view graph (max ${formatSpanBp(self.maxRegionBp)})`,\n ),\n )\n } else {\n return self.cutSubgraph(trackAdapterConfig(self, track), region, {\n hops: self.subgraphContext,\n haplotypes: self.subgraphHaplotypes,\n ...(self.cutsWholeWalks\n ? { snarls: 'overlapping' as const }\n : {}),\n })\n }\n return undefined\n },\n }\n })\n .actions(self => ({\n retryLoad() {\n void self.load()\n },\n // walk rows, and the strip of them under a node layout, measure whole\n // walks, which a GBZ cut only follows when asked, so a change in whether\n // the drawing needs them cuts the track again; the strip's toggle does\n // the same (afterAttach)\n switchLayout(mode: LayoutModeValue) {\n const before = self.cutsWholeWalks\n self.setLayoutMode(mode)\n return self.loadedTrackId && self.cutsWholeWalks !== before\n ? self.load()\n : self.recomputeLayout()\n },\n // Here rather than when the rendering backend starts: the canvas only\n // mounts once there is a graph, so a view whose graph must be fetched\n // would never fetch it.\n afterAttach() {\n if (!self.graph) {\n void self.load()\n }\n addDisposer(\n self,\n reaction(\n () => self.walkStrip,\n () => {\n if (\n self.loadedTrackId &&\n !layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ) {\n void self.load()\n }\n },\n ),\n )\n },\n }))\n}\n\nexport type GraphGenomeViewModel = Instance<\n ReturnType<typeof stateModelFactory>\n>\n", "import { COLOR_SCHEMES } from '@jbrowse/bandage-core/colorSchemes'\nimport { FACET_FIELDS } from '@jbrowse/bandage-core/facetGrid'\nimport { LAYOUT_MODES } from '@jbrowse/bandage-core/layoutModes'\nimport { WALK_FIELDS, WALK_SCHEMES } from '@jbrowse/bandage-core/walkEncoding'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n TUBE_MAP_FOLDS,\n TUBE_MAP_MODES,\n WALK_MENU_ITEMS,\n} from './paneBase'\nimport { withRenderingActions } from './renderingActions'\nimport { graphLaunchMenuItems } from '../../launchFromGraph/graphMenuItems'\nimport {\n highlightInLinearView,\n launchSyntenyView,\n showInLinearView,\n} from '../../launchFromGraph/launchFromGraph'\nimport { launchTracks } from '../../launchFromGraph/launchTracks'\nimport { launchableSyntenyTracks } from '../../launchFromGraph/syntenyTracks'\nimport { downloadText } from '../download'\n\nimport type { GraphLocation } from '../../launchFromGraph/contributors'\nimport type { MenuItem } from '@jbrowse/core/ui'\n\nexport const withLaunchActions = withRenderingActions\n .actions(self => ({\n // Move the linear view already on screen, or open one if there is none,\n // and pair with whichever it was. A view being created gets the session's\n // annotation for the assembly it opens on (see launchTracks), led by the\n // graph's own segments track when the launch is on the reference \u2014 the one\n // assembly that track is configured for.\n //\n // Only a view on the reference is paired with. A node's hover band is on\n // that assembly, so paired with a view on another the band fails that\n // view's assembly check and the reference view's id check, and is drawn\n // nowhere.\n showInLinearView(target: { location: GraphLocation; assembly: string }) {\n const session = getSession(self)\n const onReference = target.assembly === self.graphRegion?.assemblyName\n const viewId = showInLinearView({\n session,\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.connectedViewId,\n tracks: launchTracks({\n session,\n assemblyName: target.assembly,\n first: onReference ? self.sourceTrackId : undefined,\n }),\n })\n if (onReference) {\n self.pairWithLinearView(viewId)\n }\n },\n // Mark the node's reference interval in the linear view beside the graph.\n // Not an action that opens anything: with no view to mark, the menu does\n // not offer it (see nodeLaunchMenuItems).\n highlightInLinearView(target: {\n location: GraphLocation\n assembly: string\n }) {\n highlightInLinearView({\n session: getSession(self),\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.connectedViewId,\n })\n },\n showSyntenyView(trackId: string) {\n launchSyntenyView({\n session: getSession(self),\n contributors: self.launchableAssemblies,\n trackId,\n graphTrackId: self.sourceTrackId,\n })\n },\n }))\n .views(self => ({\n // Synteny datasets that could fill the panels of a multi-genome launch.\n // Below two openable contributors there is nothing to compare, so the scan\n // is skipped rather than run and discarded.\n get syntenyLaunchTracks() {\n const samples = self.launchableAssemblies.map(c => c.sample)\n return samples.length >= 2\n ? launchableSyntenyTracks(getSession(self), samples)\n : []\n },\n }))\n .views(self => ({\n // The graph's way out, in the same shared \"Launch view\" submenu every\n // other view contributes to. Until this existed the triangle had two edges:\n // a linear view could open a graph or a synteny view of a locus, and the\n // graph could open nothing at all.\n // Which samples' walks walk rows show: every one, those whose walk and\n // the picked repeat's call disagree, or a set picked by name\n walkRowSampleMenuItems(): MenuItem[] {\n const { disagreeing } = self.walkRowSampleChoices\n const shown = self.walkRowSamples\n const same = (a: string[]) => a.join('\\n') === shown?.join('\\n')\n return [\n {\n type: 'radio',\n label: 'Every sample',\n checked: shown === undefined,\n onClick: () => {\n self.setWalkRowSamples(undefined)\n },\n },\n ...(disagreeing.length > 0\n ? [\n {\n type: 'radio' as const,\n label: 'Where walk and call disagree',\n checked: same(disagreeing),\n onClick: () => {\n self.setWalkRowSamples(disagreeing)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Choose samples...',\n checked: shown !== undefined && !same(disagreeing),\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseSamplesDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n },\n // Which sample table column walk rows stack into sections by\n walkRowGroupMenuItems(): MenuItem[] {\n const field = self.walkRowGroups ? self.walkRowGroupBy?.field : undefined\n return [\n {\n type: 'radio',\n label: 'None',\n checked: field === undefined,\n onClick: () => {\n self.setWalkRowGroupBy(undefined)\n },\n },\n ...self.walkRowGroupFields.map(column => ({\n type: 'radio' as const,\n label: column,\n checked: field === column,\n onClick: () => {\n self.setWalkRowGroupBy({ field: column })\n },\n })),\n ]\n },\n graphMenuItems(): MenuItem[] {\n const walks = self.walkChoices\n return [\n {\n label: 'Layout',\n subMenu: LAYOUT_MODES.map(mode => ({\n type: 'radio' as const,\n label: mode.label,\n checked: self.chosenLayoutMode === mode.value,\n disabled: self.graph ? !mode.available(self.graph) : false,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n })),\n },\n {\n label: 'Color',\n subMenu: COLOR_SCHEMES.map(scheme => ({\n type: 'radio' as const,\n label: scheme.label,\n checked: self.chosenColorScheme === scheme.value,\n onClick: () => {\n self.setColorScheme(scheme.value)\n },\n })),\n },\n ...(walks.length > 0 && self.liftsWalks\n ? [\n {\n label: 'Walk',\n subMenu: [\n {\n label: 'None',\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n {\n label: 'Side by side',\n subMenu: FACET_FIELDS.map(({ value, label }) => ({\n type: 'radio' as const,\n label,\n checked: self.facet.field === value,\n onClick: () => {\n self.setFacet(value)\n },\n })),\n },\n ]\n : []),\n ...(self.facetPanels &&\n self.facet.field === 'walk' &&\n !self.hostPlacesX\n ? [\n {\n label: 'Columns',\n subMenu: [\n undefined,\n ...self.facetPanels.map((_, i) => i + 1),\n ].map(columns => ({\n type: 'radio' as const,\n label:\n columns === undefined ? 'Auto' : `${columns}`,\n checked: self.facet.columns === columns,\n onClick: () => {\n self.setFacetColumns(columns)\n },\n })),\n },\n ]\n : []),\n ...(walks.length > WALK_MENU_ITEMS\n ? [\n {\n label: 'Choose walks...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(walks.length > WALK_MENU_ITEMS\n ? walks.filter(walk =>\n self.walkLayers.some(l => l.walk === walk.name),\n )\n : walks\n ).map(walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: self.walkLayers.some(l => l.walk === walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n })),\n ...self.drawnWalks.map(lifted => ({\n label: `Colour ${self.walkLabel(lifted.name)}`,\n subMenu: [\n { type: 'subHeader' as const, label: 'Colour by' },\n ...WALK_FIELDS.map(field => ({\n type: 'radio' as const,\n label: field.label,\n checked: lifted.encoding.field === field.value,\n onClick: () => {\n self.setWalkColor(lifted.name, {\n field: field.value,\n })\n },\n })),\n { type: 'subHeader' as const, label: 'Palette' },\n // the rainbow is the reference-position ramp\n ...WALK_SCHEMES.filter(\n scheme =>\n scheme.value !== 'rainbow' ||\n lifted.encoding.field === 'reference',\n ).map(scheme => ({\n type: 'radio' as const,\n label: scheme.label,\n checked: lifted.encoding.scheme === scheme.value,\n onClick: () => {\n self.setWalkColor(lifted.name, {\n scheme: scheme.value,\n })\n },\n })),\n ],\n })),\n ],\n },\n ]\n : []),\n ...(TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? [\n {\n label: 'Fold variants',\n subMenu: TUBE_MAP_FOLDS.map(({ bp, label }) => ({\n type: 'radio' as const,\n label,\n checked: self.tubeMapFold === bp,\n disabled: bp > 0 && self.graph?.reads !== undefined,\n onClick: () => {\n self.setTubeMapFold(bp)\n void self.recomputeLayout()\n },\n })),\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.repeatChoices.length > 0\n ? [\n {\n label: 'Repeat',\n subMenu: [\n {\n type: 'radio' as const,\n label: 'Whole window',\n checked: self.repeatKey === '',\n onClick: () => {\n self.setRepeatKey('')\n },\n },\n ...self.repeatChoices.map(({ key, name, unit }) => ({\n type: 'radio' as const,\n label: `${name} \u00B7 ${unit.toLocaleString()} bp unit`,\n checked: self.repeatKey === key,\n onClick: () => {\n self.setRepeatKey(key)\n },\n })),\n ],\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' && self.walkRowBars\n ? [{ label: 'Samples', subMenu: this.walkRowSampleMenuItems() }]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.walkRowBars &&\n self.walkRowGroupFields.length > 0\n ? [{ label: 'Group by\u2026', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n {\n label: 'Zoom in',\n onClick: () => {\n self.zoom(\n 1.5,\n self.viewBox.width / 2,\n self.viewBox.height / 2,\n )\n },\n },\n {\n label: 'Zoom out',\n onClick: () => {\n self.zoom(\n 1 / 1.5,\n self.viewBox.width / 2,\n self.viewBox.height / 2,\n )\n },\n },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.zoomToFit()\n },\n },\n ]),\n {\n type: 'checkbox',\n label: 'Mark bubbles',\n checked: self.showBubbles,\n onClick: () => {\n self.setShowBubbles(!self.showBubbles)\n },\n },\n {\n type: 'checkbox',\n label: 'Show deletion edges',\n checked: self.showDeletionEdges,\n onClick: () => {\n void self.toggleDeletionEdges()\n },\n },\n {\n type: 'checkbox',\n label: 'Genes on the backbone',\n checked: self.showGenes,\n onClick: () => {\n self.setShowGenes(!self.showGenes)\n },\n },\n ...(!self.host &&\n self.modeDrawsNodes &&\n (self.graph?.paths?.length ?? 0) > 1\n ? [\n {\n type: 'checkbox' as const,\n label: 'Walk rows under the graph',\n checked: self.walkStrip,\n onClick: () => {\n self.setWalkStrip(!self.walkStrip)\n },\n },\n ]\n : []),\n ...(self.referenceStripApplies\n ? [\n {\n type: 'checkbox' as const,\n label: 'Reference strip at bp',\n checked: self.showReferenceStrip,\n onClick: () => {\n self.setShowReferenceStrip(!self.showReferenceStrip)\n },\n },\n ]\n : []),\n {\n label: 'Export SVG',\n disabled: self.figureUnavailable !== undefined,\n disabledHelpText: self.figureUnavailable,\n onClick: () => {\n const svg = self.figure()\n if (svg) {\n downloadText(\n svg,\n `${(self.graph?.name ?? 'graph').replaceAll(/[^\\w.-]+/g, '_')}.svg`,\n )\n }\n },\n },\n {\n label: 'Copy figure spec',\n disabled: self.figureSpecUnavailable !== undefined,\n disabledHelpText: self.figureSpecUnavailable,\n onClick: () => {\n const spec = self.figureSpec()\n const session = getSession(self)\n navigator.clipboard\n .writeText(`${JSON.stringify(spec, null, 2)}\\n`)\n .then(() => {\n session.notify(\n 'Figure spec copied. Save it as spec.json and run: npx -p @jbrowse/bandage-core bandage-figure spec.json -o figure.svg',\n 'info',\n )\n })\n .catch((e: unknown) => {\n session.notify(`Could not copy the figure spec: ${String(e)}`)\n })\n },\n },\n ]\n },\n launchMenuItems(): MenuItem[] {\n const items: MenuItem[] = []\n for (const item of graphLaunchMenuItems({\n contributors: self.launchableAssemblies,\n syntenyTracks: self.syntenyLaunchTracks,\n onShowLinear: target => {\n self.showInLinearView(target)\n },\n onShowSynteny: trackId => {\n self.showSyntenyView(trackId)\n },\n })) {\n pushLaunchViewMenuItem(items, item)\n }\n return items\n },\n }))\n", "import { lazy } from 'react'\n\nimport { BUBBLE_SPREAD_VALUES } from '@jbrowse/bandage-core/bubbleSpreads'\nimport { COLOR_SCHEME_VALUES } from '@jbrowse/bandage-core/colorSchemes'\nimport { facetSettingOf } from '@jbrowse/bandage-core/facetGrid'\nimport { createForceLayoutCache } from '@jbrowse/bandage-core/layout/forceCache'\nimport { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { NODE_WIDTH_VALUES } from '@jbrowse/bandage-core/nodeWidths'\nimport { viewportOf } from '@jbrowse/bandage-core/viewport'\nimport { types } from '@jbrowse/mobx-state-tree'\nimport { RenderLifecycleMixin } from '@jbrowse/render-core/RenderLifecycleMixin'\n\nimport { lenientMaybeEnum, lenientOptionalEnum } from '../lenientEnum'\nimport { groupByOf } from '../walkRowGroups'\n\nimport type { SubgraphRegion } from '../../GetSubgraph'\nimport type { RepeatArray } from '../repeats/repeatFeatures'\nimport type { SampleRow, WalkRowGroupBy } from '../walkRowGroups'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { FacetInput } from '@jbrowse/bandage-core/facetGrid'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { AxisScale } from '@jbrowse/bandage-core/util/geometry'\nimport type { WalkLayer } from '@jbrowse/bandage-core/walkEncoding'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\n// Ceiling on the pane, and what it falls back to before there is a layout to\n// size against. A roughly square drawing (FMMM) hits this and keeps the\n// scrollable pane it has always had.\nexport const MAX_CANVAS_HEIGHT = 600\n// Floor, so a window holding only backbone \u2014 one row, no height at all \u2014 still\n// leaves room to hover a node and read its tooltip.\nexport const MIN_CANVAS_HEIGHT = 160\n// the pane's background, as the renderer clears to it and as CSS\nexport const PAPER_LIGHT: [number, number, number, number] = [1, 1, 1, 1]\nexport const PAPER_DARK: [number, number, number, number] = [\n 0.12, 0.12, 0.12, 1,\n]\nexport const paperCss = ([r, g, b]: number[]) =>\n `rgb(${[r, g, b].map(v => Math.round(v! * 255)).join(', ')})`\n// The thinnest a fit draws a tube map's tubes\nexport const MIN_FIT_TUBE_PX = 5\n\nexport const TUBE_MAP_MODES = new Set<string>(['tubemap', 'tubemapref'])\n\nexport const ChooseSamplesDialog = lazy(\n () => import('../components/ChooseSamplesDialog'),\n)\nexport const ChooseWalksDialog = lazy(\n () => import('../components/ChooseWalksDialog'),\n)\n\n// Past this many walks the Walk menu lists only the lifted ones and offers a\n// searchable picker\nexport const WALK_MENU_ITEMS = 12\n\n// The facet as a session writes it, in the shape every JBrowse display's\n// `facet` takes: a bare field, or the field with the panels' order and how\n// many go across. A field this pane cannot split on reads as none.\nconst facetModel = types.snapshotProcessor(\n types.model('GraphFacet', {\n field: types.optional(types.enumeration(['', 'walk', 'sample']), ''),\n domain: types.optional(types.frozen<string[]>(), []),\n columns: types.maybe(types.number),\n }),\n {\n preProcessor: (snap: FacetInput | undefined) => facetSettingOf(snap),\n },\n)\n\n// The sizes a tube map folds variants under. MICB's 22 kb cut draws 475\n// columns whole, 34 under 3 bp and one under 50, where only its structural\n// variants would stand: human windows are mostly SNPs.\nexport const TUBE_MAP_FOLDS = [\n { bp: 0, label: 'None' },\n { bp: 3, label: 'Under 3 bp' },\n { bp: 10, label: 'Under 10 bp' },\n { bp: 50, label: 'Under 50 bp, leaving structural variants' },\n { bp: 1000, label: 'Under 1 kb' },\n]\n\nconst SEGMENTS_SUFFIX = '.segs.bed.gz'\n\n// The rGFA index prefix an adapter config names, from either spelling the\n// config schema accepts: the `uri` shorthand or an explicit segments location.\nexport function bubblePrefix(adapterConfig: Record<string, unknown>) {\n if (typeof adapterConfig.uri === 'string') {\n return adapterConfig.uri\n }\n const segments = adapterConfig.segmentsLocation as\n { uri?: string } | undefined\n const uri = segments?.uri\n return typeof uri === 'string' && uri.endsWith(SEGMENTS_SUFFIX)\n ? uri.slice(0, -SEGMENTS_SUFFIX.length)\n : undefined\n}\nexport const HOVER_BRIGHTEN = 1.4\nexport const SELECT_BRIGHTEN = 1.6\nexport const VIEWPORT_DEBOUNCE_MS = 150\nexport const VIEWPORT_PANES_BUILT = 1\n// How many walk rows read their haplotype's genes, the first rows down\nexport const WALK_GENE_ROWS = 40\n\n// What the canvas draws under the tube map, whose ink is all TubeMapOverlay's\nexport const EMPTY_BATCH: RenderBatch = {\n nodeStrokes: [],\n nodeStrokeRuns: new Map(),\n arrows: [],\n arrowRuns: new Map(),\n edgeCurves: [],\n edgeCurveRuns: new Map(),\n}\n\n// MobX tracks every observable read while a computed or autorun runs, so\n// passing values here registers them as dependencies without otherwise using\n// them.\nexport function dependOn(..._values: unknown[]) {}\n\n// Hard size cap for the single-mode graph view. Past it the view declines with a\n// \"zoom in\" message rather than switching to a degraded rendering mode \u2014 one mode\n// only, since the large-region case is a linear synteny view, not a graph.\n// (The `adr-027` citation this used to carry was stale: that number was reused\n// for wheel-input semantics after the large-mode ADR was removed in 9d8102f0b5.)\n//\n// This bounds the *fetch*, and it is the only cap that can be applied before one\n// happens. It is a poor proxy for cost, because cost tracks node count, so the\n// number is chosen against the density of the graphs it can actually guard: a\n// region is fetched through `getSubgraph`, and the rGFA cut is what this number\n// was chosen against (the GBZ cut is base-level and has its own `nodeLimit`,\n// which trips long before 5 Mb). Both measured rGFAs are sparse, and at 5 Mb\n// both land at or under the ~2k nodes that redraw in under 10 ms (see agent-docs/reference/GRAPH_SCALE_AND_LOD.md):\n//\n// HPRC MC GRCh38 ~7,000 bp/segment whole 4.9 Mb MHC 1,173 nodes\n// ecoli minigraph 3,078 bp/segment whole 4.6 Mb genome 2,415 nodes\n//\n// Fetch cost does not scale with the window either: against the hosted HPRC\n// index a 4.9 Mb links query and a 100 kb one both cost ~1.3 s, being dominated\n// by HTTP setup. FMMM is the slowest consumer at this size and stays tolerable,\n// ~0.1-3 s for ~1k nodes depending on layout quality (bandage-layout-js), and it\n// runs off the main thread.\n//\n// A dense graph is what this cannot protect against, because bp per node varies\n// by orders of magnitude between graph types \u2014 a base-level pggb graph runs ~17\n// bp/node, where 5 Mb would be hundreds of thousands. Such a graph has no region\n// query to reach this check with today, and the node budget below is the cap that\n// catches it if one ever does.\nexport const MAX_GRAPH_REGION_BP = 5_000_000\n\n// The cap in a message, in the unit that reads: `5 Mb`, not `5000 kb`.\nexport function formatSpanBp(bp: number) {\n return bp >= 1_000_000\n ? `${+(bp / 1_000_000).toFixed(1)} Mb`\n : `${Math.round(bp / 1000)} kb`\n}\n\n// What the view will actually draw, checked once the graph is parsed and so\n// applying to a whole-file import as much as to a subgraph fetch. Measured on\n// bubble-chain graphs: ~1-2k nodes redraws in under 10 ms, 10k takes ~43 ms of\n// geometry and ~125k canvas draw calls per frame (single-digit fps while\n// panning), and 100k needs 632 ms and 75 MB of vertex buffers. So this is set\n// where the tab stops being usable rather than where it stops being smooth, and\n// it is a view prop rather than a constant so a session can raise it \u2014 the same\n// escape hatch strangepg gives with `-T N`.\nexport const DEFAULT_MAX_GRAPH_NODES = 20_000\n\n// A url bandage-figure can read again, or undefined for a local file\nexport function uriOf(location: FileLocation | undefined) {\n return location && 'uri' in location && location.uri\n ? new URL(location.uri, location.baseUri ?? window.location.href).href\n : undefined\n}\n\ntype ViewportOwner = 'fit' | 'user' | 'host'\n\ninterface BuiltViewport {\n scale: number\n bounds: Bounds\n viewportDirty: number\n}\n\nexport function geometryPainted(model: {\n viewportRebuildPending: boolean\n viewportDirty: number\n builtViewport?: BuiltViewport\n paintedViewport?: BuiltViewport\n}) {\n return (\n model.builtViewport !== undefined &&\n model.paintedViewport === model.builtViewport &&\n model.builtViewport.viewportDirty === model.viewportDirty &&\n !model.viewportRebuildPending\n )\n}\n\n// What the pane shows, in layout units: what each panel shows while faceted\nexport function paneViewportOf(model: {\n translateX: number\n translateY: number\n axisScale: AxisScale\n viewBox: { width: number; height: number }\n}): Bounds {\n const { width, height } = model.viewBox\n return viewportOf(model, model.axisScale, width, height)\n}\n\n// Force layouts already computed for a graph, keyed by the view props the\n// engine reads. Every layout mode is local and costs a millisecond except this\n// one, which is seconds: measured on the committed engine, a 1,201-node bubble\n// chain is 0.6 s proportional, 4.3 s at 'Wide bubbles' and 3.4 s at the highest\n// quality.\n//\n// Worth keeping because a session revisits the same layout. The two drawings\n// answer different questions and the README's own figure is one subgraph in\n// both, so Anchored <-> Force is a round trip a reader makes repeatedly \u2014 and\n// every control in the settings dialog calls `recomputeLayout` on change\n// whether or not the current mode reads what it changed, which made picking a\n// reference path in force mode a multi-second re-run of an identical layout.\n// Both are hits. The cache itself is core's, which BandageJS keeps too.\nexport const forceLayouts = createForceLayoutCache()\n\nexport const paneBase = types\n .compose(\n 'GraphPane',\n RenderLifecycleMixin(),\n types.model({\n // FMMM's iteration budget, 0-4, the same scale Bandage's own settings\n // dialog exposes: 3+1 iterations at 0, 15+10 at 1, 30+20 at 2, 60+40 at\n // 3, 120+60 at 4 (BandageNG layout/graphlayoutworker.cpp).\n //\n // 2 because that is what the engine we vendor ships as its default\n // (`graphLayoutQuality = IntSetting(2, 0, 4)`, program/settings.cpp).\n // This was 1 for no recorded reason, i.e. one step BELOW upstream, and a\n // first sight of any graph is the default: review kept asking whether\n // the drawing could be iterated more (\"are you sure you can't iterate it\n // more times for better layout?\") of figures that were simply on a lower\n // setting than the tool they come from. Cost at the sizes this view\n // draws is milliseconds, and the header states the layout time so the\n // difference is visible rather than asserted.\n layoutQuality: types.optional(types.number, 2),\n linearLayout: types.optional(types.boolean, false),\n // unset takes the host's default: force in a view of its own, the\n // display config's in a track\n layoutMode: lenientMaybeEnum(LAYOUT_MODE_VALUES),\n colorScheme: lenientMaybeEnum(COLOR_SCHEME_VALUES),\n // How far the force layout opens a bubble, which on a variation graph is\n // the difference between a legible drawing and a rope. See\n // BUBBLE_SPREADS; no effect on the reference-anchored layouts, which\n // place a node from its coordinates rather than from a force sim.\n bubbleSpread: lenientOptionalEnum(BUBBLE_SPREAD_VALUES, 'auto'),\n // Node thickness by depth, Bandage's own device; see NODE_WIDTHS.\n nodeWidth: lenientOptionalEnum(NODE_WIDTH_VALUES, 'depth'),\n // Whether the node layouts draw each bubble as a halo along its nodes\n // with a label that opens it. Off by default: on a base-level cut\n // every SNP's halo is a blob.\n showBubbles: types.optional(types.boolean, false),\n showDeletionEdges: types.optional(types.boolean, true),\n // The session's genes drawn onto the backbone: exons along the nodes\n // that carry them, names pinned at their midpoints. See genes/.\n showGenes: types.optional(types.boolean, true),\n // Whether a drawing in its own coordinates inside a linear view gets\n // the strip of reference segments at their bp. See referenceStrip.ts.\n showReferenceStrip: types.optional(types.boolean, true),\n // Variants under this many bp fold into the reference before a tube map\n // is laid out, each kept as a tick on its walk's tube (coarsen.ts); 0\n // draws every one\n tubeMapFold: types.optional(types.number, 0),\n // Which track the genes come from; empty picks the assembly's\n // annotation track (pickGeneTrack).\n geneTrackId: types.optional(types.string, ''),\n // Which track the walk rows read tandem repeat arrays from; empty\n // picks a track whose name says repeats (pickRepeatTrack).\n repeatTrackId: types.optional(types.string, ''),\n // The array the walk rows measure between and tile by, as\n // RepeatArray.key; empty measures the whole window untiled.\n repeatKey: types.optional(types.string, ''),\n // Samples whose walks the walk rows show, by the name before the\n // haplotype number; undefined shows every walk the cut holds.\n walkRowSamples: types.maybe(types.frozen<string[]>()),\n // The sample table column walk rows stack into sections by, read from\n // the source track's samplesTsvLocation; a bare field name or\n // `{ field, domain }`, anything else reading as ungrouped\n walkRowGroupBy: types.maybe(\n types.snapshotProcessor(types.frozen<WalkRowGroupBy | undefined>(), {\n preProcessor: (snap: unknown) => groupByOf(snap),\n }),\n ),\n // Walk rows in a strip under a layout that draws nodes, linked to the\n // drawing: a node's passes tick each bar, a bar's point lights its node\n walkStrip: types.optional(types.boolean, false),\n // Walks lifted out of the drawing, each a layer with a lane of its own\n // and the rest fading, coloured by the encoding it states or by the\n // default one. See walkEncoding.ts. Empty lifts none.\n walkLayers: types.optional(types.frozen<WalkLayer[]>(), []),\n // Facets, as a grammar of graphics splits a plot: `walk` draws the\n // pane once per lifted walk, side by side on the same layout, each\n // panel with that walk alone; `sample` puts a sample's haplotypes in\n // a row; `domain` orders the panels and `columns` fixes how many go\n // across. See facetPanels and facetCells.\n facet: types.optional(facetModel, {}),\n // Which of a general GFA's paths the anchored layouts put on x. A path\n // GFA's names are arbitrary and none of them is marked as the\n // reference, so this is a choice; empty means \"infer\", which is the\n // assembly a subgraph was cut against, and the first path in the file\n // for a whole-file import. No effect on an rGFA, whose segments carry\n // their own coordinates. See pathAnchoring.ts.\n referencePath: types.optional(types.string, ''),\n // Whether the toolbar spells out `fetch 12371ms \u00B7 layout 4ms \u00B7 geom 9ms`.\n // Off by default because it was in the toolbar of every published graph\n // figure, where a machine's fetch time is noise a reader has to skip\n // past. The numbers themselves are always on the element as `data-*`\n // attributes, which is what browser tests assert against, so hiding the\n // text costs no coverage.\n showPerf: types.optional(types.boolean, false),\n contigThickness: types.optional(types.number, 6),\n connectorThickness: types.optional(types.number, 2),\n darkMode: types.optional(types.boolean, false),\n scale: types.optional(types.number, 1),\n translateX: types.optional(types.number, 0),\n translateY: types.optional(types.number, 0),\n drawPaths: types.optional(types.boolean, false),\n // Ceiling on the drawing pane, in css px, for a session or a figure that\n // wants a shorter one than the drawing asks for. Unset means the built-in\n // MAX_CANVAS_HEIGHT, which is what every existing session gets.\n //\n // Why this is a knob rather than a smaller default: the pane is as tall\n // as the drawing's own aspect ratio (see canvasHeight), which is right \u2014\n // a graph that is twice as tall as it is wide should not be squeezed\n // into a strip. But one very long node in a cut of short ones makes that\n // aspect ratio all arc: the HPRC CHM13 figure draws a 142 kb allele\n // among sub-kb backbone segments, pins the 600 px ceiling and spends\n // most of it on the loop, with the chain squashed along the bottom edge.\n // Lowering the ceiling there scales the whole drawing down, which is\n // exactly the trade that figure wants and the wrong default for a graph\n // whose height is carrying information.\n paneHeight: types.maybe(types.number),\n // Raise to draw a bigger graph than the default budget allows; see\n // DEFAULT_MAX_GRAPH_NODES for what the numbers cost.\n maxGraphNodes: types.optional(types.number, DEFAULT_MAX_GRAPH_NODES),\n // The reference span the reference-position ramp runs over, for a graph\n // with no region of its own to span it\n colorDomain: types.maybe(types.frozen<{ start: number; end: number }>()),\n // the linear view a graph of its own is paired with for the hover sync\n connectedViewId: types.maybe(types.string),\n }),\n )\n .volatile(() => ({\n graph: undefined as Graph | undefined,\n // the reference window the graph on screen was cut for, set with it\n graphRegion: undefined as SubgraphRegion | undefined,\n // The walk the track's graph lies on for the region's assembly, which\n // the track's config declares; x starts along it unless the user chose\n // another. Undefined for an rGFA, whose backbone is fixed, and for a\n // graph with no region.\n loadedReferencePath: undefined as string | undefined,\n layoutResult: undefined as LayoutResult | undefined,\n // what the legends in the pane's top-right corner measure, so no label\n // is placed under them\n legendSize: { width: 0, height: 0 },\n // The bubble index rows over the cut window, when the source track has\n // one beside its segments. Undefined for a graph with no index, whose\n // bubbles are `derivedBubbles` instead.\n indexBubbles: undefined as MinigraphBubble[] | undefined,\n // the gene track's features over the cut window, read once per cut\n geneTrackFeatures: undefined as Feature[] | undefined,\n // each walk row's genes, read from its haplotype's own assembly, by walk\n // name\n walkGeneFeatures: undefined as Map<string, GeneModel[]> | undefined,\n // the source track's samples TSV, which walk rows group by\n walkRowSampleTable: undefined as SampleRow[] | undefined,\n // the tandem repeat arrays over the cut window, from the repeat track\n repeatArrays: undefined as RepeatArray[] | undefined,\n // The graphs the open bubble was popped out of, outermost first, each\n // with what closing back to it restores without a refetch. A stack so a\n // popped superbubble can be mapped and popped again.\n popStack: [] as {\n graph: Graph\n layoutMode: LayoutModeValue\n label: string\n indexBubbles: MinigraphBubble[] | undefined\n }[],\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n error: undefined as unknown,\n isLoading: false,\n loadCanceled: false,\n statusMessage: '',\n hoveredNode: null as string | null,\n // the walks of the per-sample lane row the linear view's pointer is on\n hoveredRowWalks: [] as string[],\n // the bubble whose label the pointer is on\n hoveredBubble: null as MinigraphBubble | null,\n // whether the pointer is over this pane, whose own hit test then says\n // what it is on\n pointerInPane: false,\n // the strip point the pointer is over, which lights its node above\n stripHover: null as { row: string; offset: number } | null,\n // the walk row the pointer is on, by walk name\n hoveredWalkRow: null as string | null,\n hoveredEdge: null as number | null,\n selectedNode: null as string | null,\n viewportDirty: 0,\n // Bumped when the layout's positions are mutated IN PLACE, which only a\n // node drag does. Separate from `viewportDirty` because that one also\n // fires on pan and zoom, and the things keyed off this \u2014 the two hit\n // indexes and the label placement's per-layout caches \u2014 do not depend on\n // the transform at all. Rebuilding a 12k-edge hit index because the user\n // panned cost ~14 ms of the first mousemove after every gesture.\n positionsVersion: 0,\n // Bumped per upload, so the hover autorun re-states its highlights\n // against the batch the renderer now holds.\n geometryVersion: 0,\n // The zoom and the window the current batch was built for; a pan that\n // stays inside it needs no rebuild.\n builtViewport: undefined as BuiltViewport | undefined,\n // The builtViewport whose batch is on the canvas\n paintedViewport: undefined as BuiltViewport | undefined,\n draggingNode: null as string | null,\n // Dragging the background rather than a node. Lives here beside\n // draggingNode instead of in a component ref+state pair, so the two\n // mutually exclusive drag modes are one piece of state read from one place.\n isPanning: false,\n // Who places the view. 'fit' refits it to every new layout, 'user' leaves\n // it where a gesture or a restored session put it, and 'host' takes x\n // from the linear view the pane sits in. Not derived from\n // `isDefaultViewport`, which zoomToFit itself invalidates on its first\n // run \u2014 that made the fit fire once against not-yet-measured dimensions\n // and then never re-fit.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n viewportOwner: 'fit' as ViewportOwner,\n viewportDirtyTimer: undefined as ReturnType<typeof setTimeout> | undefined,\n // 0 is never a live rAF handle, so it doubles as \"nothing pending\"\n positionsDirtyFrame: 0,\n // Performance instrumentation, surfaced in GraphStats for browser tests\n // to assert against budgets. `fetchMs` is the GetSubgraph RPC round-trip,\n // `layoutMs` is the Bandage FMMM compute time reported by the\n // GraphComputeLayout RPC, `geometryMs` is the main-thread buildGeometry\n // pass and `geometryStrokeCount` the node strokes it produced.\n lastFetchMs: undefined as number | undefined,\n // how many of the cut's reads the tube map was handed, of how many\n readsShown: undefined as { shown: number; total: number } | undefined,\n lastLayoutMs: undefined as number | undefined,\n lastGeometryMs: undefined as number | undefined,\n lastGeometryStrokeCount: undefined as number | undefined,\n viewportRebuildPending: false,\n }))\n", "import {\n buildNeighbors\n} from \"./chunk-ES2N6V56.js\";\nimport {\n drawnNodeLength\n} from \"./chunk-6JEWNXCQ.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/referenceSeeds.ts\nvar LANE_GAP = 30;\nfunction referenceSeeds(graph, scaling) {\n const { opts } = scaling;\n const drawn = new Map(\n scaling.nodes.map((node) => [node.id, drawnNodeLength(opts, node.length)])\n );\n const drawnOf = (id) => drawn.get(id) ?? opts.minimumNodeLength;\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const seeds = /* @__PURE__ */ new Map();\n let x = 0;\n for (const node of backbone) {\n seeds.set(node.id, { x, y: 0 });\n x += drawnOf(node.id) + opts.edgeLength;\n }\n const adjacent = buildNeighbors(graph);\n const depth = new Map(backbone.map((node) => [node.id, 0]));\n const queue = backbone.map((node) => node.id);\n for (const id of queue) {\n const at = seeds.get(id);\n const next = depth.get(id) + 1;\n for (const neighbour of adjacent.get(id) ?? []) {\n if (depth.has(neighbour)) {\n continue;\n }\n depth.set(neighbour, next);\n seeds.set(neighbour, { x: at.x + drawnOf(id) / 2, y: LANE_GAP * next });\n queue.push(neighbour);\n }\n }\n let unreached = 0;\n for (const node of graph.nodes) {\n if (!seeds.has(node.id)) {\n seeds.set(node.id, {\n x: unreached++ * x / graph.nodes.length,\n y: LANE_GAP * 3\n });\n }\n }\n return seeds;\n}\nfunction seededNodes(graph, scaling) {\n const seeds = referenceSeeds(graph, scaling);\n return scaling.nodes.map((node) => ({ ...node, ...seeds.get(node.id) }));\n}\n\nexport {\n referenceSeeds,\n seededNodes\n};\n", "import {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/layout/orientToReference.ts\nfunction orientToReference(graph, positions) {\n const backbone = graph.nodes.filter(\n (node) => isBackbone(node) && (positions[node.id]?.length ?? 0) > 0\n );\n if (backbone.length < 2) {\n return positions;\n }\n const points = backbone.map((node) => {\n const segments = positions[node.id];\n const mid = segments[Math.floor(segments.length / 2)];\n return {\n x: mid.x,\n y: mid.y,\n r: node.stable.start + node.length / 2,\n w: node.length\n };\n });\n const weight = points.reduce((sum, p) => sum + p.w, 0);\n const cx = points.reduce((sum, p) => sum + p.x * p.w, 0) / weight;\n const cy = points.reduce((sum, p) => sum + p.y * p.w, 0) / weight;\n const cr = points.reduce((sum, p) => sum + p.r * p.w, 0) / weight;\n let sxr = 0;\n let syr = 0;\n for (const p of points) {\n sxr += p.w * (p.x - cx) * (p.r - cr);\n syr += p.w * (p.y - cy) * (p.r - cr);\n }\n const angle = -Math.atan2(syr, sxr);\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const out = {};\n for (const [id, segments] of Object.entries(positions)) {\n out[id] = segments.map((p) => {\n const x = p.x - cx;\n const y = p.y - cy;\n return { x: cx + c * x - s * y, y: cy + s * x + c * y };\n });\n }\n let below = 0;\n let above = 0;\n for (const node of graph.nodes) {\n if (isBackbone(node)) {\n continue;\n }\n for (const p of out[node.id] ?? []) {\n if (p.y > cy) {\n below++;\n } else {\n above++;\n }\n }\n }\n if (above > below) {\n for (const segments of Object.values(out)) {\n for (const p of segments) {\n p.y = 2 * cy - p.y;\n }\n }\n }\n return out;\n}\n\nexport {\n orientToReference\n};\n", "// src/gfa-core/gfaParser.ts\nfunction parseTag(tag, tags) {\n const nameEnd = tag.indexOf(\":\");\n const typeEnd = tag.indexOf(\":\", nameEnd + 1);\n if (nameEnd !== -1 && typeEnd !== -1) {\n const name = tag.slice(0, nameEnd);\n const type = tag.slice(nameEnd + 1, typeEnd);\n const val = tag.slice(typeEnd + 1);\n if (type === \"i\" || type === \"f\") {\n tags[name] = +val;\n } else if (type === \"Z\") {\n tags[name] = val;\n }\n }\n}\nfunction parseTags(fields) {\n const tags = {};\n for (const field of fields) {\n parseTag(field, tags);\n }\n return tags;\n}\nfunction stableCoordinate(node) {\n const { SN, SO, SR } = node.tags;\n return typeof SN === \"string\" && typeof SO === \"number\" && typeof SR === \"number\" ? { refName: SN, start: SO, rank: SR } : void 0;\n}\nvar GT = 62;\nvar LT = 60;\nfunction parseWalkBody(body) {\n const segments = [];\n let strand = \"+\";\n let start = 0;\n function push(end) {\n if (end > start) {\n segments.push({ id: body.slice(start, end), strand });\n }\n }\n for (let i = 0; i < body.length; i++) {\n const ch = body.charCodeAt(i);\n if (ch === GT || ch === LT) {\n push(i);\n strand = ch === GT ? \"+\" : \"-\";\n start = i + 1;\n }\n }\n push(body.length);\n return segments;\n}\nfunction parseGFA(file) {\n const graph = {\n nodes: [],\n links: [],\n paths: [],\n walks: [],\n header: [],\n id: \"\"\n };\n for (const rawLine of file.split(\"\\n\")) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n if (line.startsWith(\"H\")) {\n const [, ...rest] = line.split(\"\t\");\n graph.header.push(parseTags(rest));\n } else if (line.startsWith(\"S\")) {\n const [, name, ...rest] = line.split(\"\t\");\n let len;\n let seq;\n let tagfields;\n let gfa1 = false;\n const first = rest[0] ?? \"*\";\n if (/^\\d+$/.test(first)) {\n len = +first;\n seq = rest[1] ?? \"*\";\n tagfields = rest.slice(2);\n } else {\n gfa1 = true;\n seq = first;\n len = seq === \"*\" ? 0 : seq.length;\n tagfields = rest.slice(1);\n }\n const tags = parseTags(tagfields);\n if (gfa1 && \"LN\" in tags) {\n len = +tags.LN;\n }\n graph.nodes.push({ id: name, length: len, sequence: seq, tags });\n } else if (line.startsWith(\"E\")) {\n const [, , source, target, , , , , cigar, ...rest] = line.split(\"\t\");\n if (source && target) {\n graph.links.push({\n source: source.slice(0, -1),\n target: target.slice(0, -1),\n strand1: source.at(-1),\n strand2: target.at(-1),\n cigar: cigar ?? \"*\",\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"L\")) {\n const [, source, strand1, target, strand2, cigar, ...rest] = line.split(\"\t\");\n if (source && target && strand2) {\n graph.links.push({\n source,\n target,\n strand1,\n strand2,\n cigar: cigar ?? \"*\",\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"W\")) {\n const [, sample, hap, contig, start, end, body, ...rest] = line.split(\"\t\");\n if (sample && hap && contig && start && end && body) {\n graph.walks.push({\n sample,\n haplotype: +hap,\n contig,\n start: start === \"*\" ? -1 : +start,\n end: end === \"*\" ? -1 : +end,\n segments: parseWalkBody(body),\n tags: parseTags(rest)\n });\n }\n } else if (line.startsWith(\"P\")) {\n const [, name, path, ...rest] = line.split(\"\t\");\n if (name && path) {\n graph.paths.push({ name, path, rest });\n }\n }\n }\n return graph;\n}\n\nexport {\n stableCoordinate,\n parseGFA\n};\n", "import {\n stableCoordinate\n} from \"./chunk-CDLPYR5O.js\";\nimport {\n pathOrigin,\n surveyPaths\n} from \"./chunk-ST2IBUAN.js\";\n\n// src/gfa/gfaConverter.ts\nfunction surveySegments(gfaGraph) {\n const canonical = /* @__PURE__ */ new Map();\n const traversals = /* @__PURE__ */ new Map();\n function claim(id, strand) {\n if (!canonical.has(id)) {\n canonical.set(id, strand);\n }\n }\n function traverse(id, strand) {\n claim(id, strand);\n traversals.set(id, (traversals.get(id) ?? 0) + 1);\n }\n for (const link of gfaGraph.links) {\n claim(link.source, link.strand1 === \"-\" ? \"-\" : \"+\");\n claim(link.target, link.strand2 === \"-\" ? \"-\" : \"+\");\n }\n for (const gfaPath of gfaGraph.paths) {\n for (const segment of gfaPath.path.split(\",\")) {\n traverse(segment.slice(0, -1), segment.endsWith(\"-\") ? \"-\" : \"+\");\n }\n }\n for (const walk of gfaGraph.walks) {\n for (const seg of walk.segments) {\n traverse(seg.id, seg.strand === \"-\" ? \"-\" : \"+\");\n }\n }\n return { canonical, traversals };\n}\nvar walkStart = (w) => w.start === -1 ? 0 : w.start;\nfunction anchorablePaths(gfaGraph) {\n return [\n ...gfaGraph.paths.map((p) => ({\n ...pathOrigin(p.name),\n steps: p.path.split(\",\").map((segment) => ({\n id: segment.slice(0, -1),\n strand: segment.endsWith(\"-\") ? \"-\" : \"+\"\n }))\n })),\n ...gfaGraph.walks.map((w) => ({\n name: `${w.sample}#${w.haplotype}#${w.contig}`,\n start: walkStart(w),\n steps: w.segments.map((s) => ({\n id: s.id,\n strand: s.strand === \"-\" ? \"-\" : \"+\"\n }))\n }))\n ];\n}\nfunction carriedSamples(gfaNode) {\n const sm = gfaNode.tags.SM;\n if (typeof sm !== \"string\") {\n return void 0;\n }\n const samples = sm.split(\",\").map((s) => s.trim()).filter(Boolean);\n return samples.length > 0 ? samples : void 0;\n}\nvar positive = (v) => typeof v === \"number\" && v > 0 ? v : void 0;\nfunction statedDepth({ tags, length }) {\n const count = positive(tags.RC) ?? positive(tags.FC) ?? positive(tags.KC);\n return positive(tags.dp) ?? positive(tags.DP) ?? (count !== void 0 && length > 0 ? count / length : void 0);\n}\nfunction makeNode(gfaNode, strand, depth) {\n return {\n id: `${gfaNode.id}${strand}`,\n name: gfaNode.id,\n length: gfaNode.length,\n depth,\n stable: stableCoordinate(gfaNode),\n samples: carriedSamples(gfaNode)\n };\n}\nfunction convertGFAToGraph(gfaGraph, name = \"Imported GFA\") {\n const nodes = [];\n const edges = [];\n const { canonical, traversals } = surveySegments(gfaGraph);\n const nodeId = (segmentId) => `${segmentId}${canonical.get(segmentId) ?? \"+\"}`;\n for (const gfaNode of gfaGraph.nodes) {\n const depth = statedDepth(gfaNode) ?? Math.max(traversals.get(gfaNode.id) ?? 1, 1);\n nodes.push(makeNode(gfaNode, canonical.get(gfaNode.id) ?? \"+\", depth));\n }\n for (const link of gfaGraph.links) {\n edges.push({\n from: nodeId(link.source),\n to: nodeId(link.target),\n fromStrand: link.strand1 === \"-\" ? \"-\" : \"+\",\n toStrand: link.strand2 === \"-\" ? \"-\" : \"+\"\n });\n }\n const paths = [];\n const edgeToPathsMap = /* @__PURE__ */ new Map();\n const edgeKey = (a, b) => [a, b].sort().join(\"--\");\n function recordPathEdges(nodeIds, name2) {\n for (let i = 0; i < nodeIds.length - 1; i++) {\n const key = edgeKey(nodeIds[i], nodeIds[i + 1]);\n if (!edgeToPathsMap.has(key)) {\n edgeToPathsMap.set(key, /* @__PURE__ */ new Set());\n }\n edgeToPathsMap.get(key).add(name2);\n }\n }\n for (const gfaPath of gfaGraph.paths) {\n const nodeIds = gfaPath.path.split(\",\").map((segment) => nodeId(segment.slice(0, -1)));\n paths.push({\n name: gfaPath.name,\n nodeIds,\n start: pathOrigin(gfaPath.name).start\n });\n recordPathEdges(nodeIds, gfaPath.name);\n }\n for (const walk of gfaGraph.walks) {\n const nodeIds = walk.segments.map((seg) => nodeId(seg.id));\n const name2 = `${walk.sample}#${walk.haplotype}#${walk.contig}`;\n paths.push({\n name: name2,\n nodeIds,\n start: walkStart(walk),\n sample: walk.sample,\n haplotype: walk.haplotype,\n contig: walk.contig\n });\n recordPathEdges(nodeIds, name2);\n }\n for (const edge of edges) {\n const pathIds = edgeToPathsMap.get(edgeKey(edge.from, edge.to));\n if (pathIds && pathIds.size > 0) {\n edge.pathIds = [...pathIds];\n }\n }\n const lengths = new Map(gfaGraph.nodes.map((n) => [n.id, n.length]));\n const anchoring = gfaGraph.paths.length > 0 || gfaGraph.walks.length > 0 ? surveyPaths(anchorablePaths(gfaGraph), (id) => lengths.get(id) ?? 0) : void 0;\n return {\n name,\n nodes,\n edges,\n paths: paths.length > 0 ? paths : void 0,\n anchorPaths: anchoring?.anchorPaths,\n pathVisits: anchoring?.pathVisits,\n // rGFA's own tags win wherever they are present; pathAnchoring only ever\n // fills in for a graph that carries none.\n anchoredBy: nodes.some((n) => n.stable) ? \"tags\" : void 0\n };\n}\n\nexport {\n convertGFAToGraph\n};\n", "// src/layout/deletionRoutes.ts\nvar ROUTE_ID = \"\\0deletion:\";\nvar ROUTE_FRACTION = 0.5;\nfunction withDeletionRoutes(graph, deletions, dropped = /* @__PURE__ */ new Set()) {\n const routes = new Map(\n deletions.map((d) => [d.edgeIndex, `${ROUTE_ID}${d.edgeIndex}`])\n );\n const edges = [];\n graph.edges.forEach((edge, ei) => {\n const id = routes.get(ei);\n if (dropped.has(ei)) {\n return;\n }\n if (id === void 0) {\n edges.push(edge);\n } else {\n const { fromStrand, toStrand } = edge;\n edges.push(\n { from: edge.from, to: id, ...fromStrand ? { fromStrand } : {} },\n { from: id, to: edge.to, ...toStrand ? { toStrand } : {} }\n );\n }\n });\n return {\n graph: {\n ...graph,\n nodes: [\n ...graph.nodes,\n ...[...routes.values()].map((id) => ({\n id,\n name: id,\n length: 0,\n depth: 0\n }))\n ],\n edges\n },\n routes,\n ids: new Set(routes.values())\n };\n}\nfunction routeNodes(graph, deletions, routes, drawnOf, opts) {\n const lengths = new Map(graph.nodes.map((n) => [n.id, n.length]));\n return deletions.map((d) => {\n const skipped = d.bypassed.reduce(\n (sum, id2) => sum + (lengths.get(id2) ?? 0),\n 0\n );\n const drawn = Math.max(\n opts.minimumNodeLength,\n drawnOf(skipped) * ROUTE_FRACTION\n );\n const id = routes.get(d.edgeIndex);\n return {\n id,\n name: id,\n length: Math.round(drawn * 1e6 / opts.nodeLengthPerMegabase),\n depth: 0\n };\n });\n}\nfunction takeRoutes(positions, routes) {\n const nodePositions = { ...positions };\n const deletionRoutes = {};\n for (const [edgeIndex, id] of routes) {\n const route = nodePositions[id];\n delete nodePositions[id];\n if (route?.length) {\n deletionRoutes[edgeIndex] = route;\n }\n }\n return { nodePositions, deletionRoutes };\n}\n\nexport {\n ROUTE_ID,\n withDeletionRoutes,\n routeNodes,\n takeRoutes\n};\n", "import {\n seededNodes\n} from \"./chunk-IGVV37VI.js\";\nimport {\n orientToReference\n} from \"./chunk-PUG7LXDF.js\";\nimport {\n convertGFAToGraph\n} from \"./chunk-72N5DJHZ.js\";\nimport {\n parseGFA\n} from \"./chunk-CDLPYR5O.js\";\nimport {\n anchorGraph\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n mergeRuns,\n splitRuns\n} from \"./chunk-TAMCZHLW.js\";\nimport {\n routeNodes,\n takeRoutes,\n withDeletionRoutes\n} from \"./chunk-JVLURPFW.js\";\nimport {\n spreadFor\n} from \"./chunk-UVBGRJQX.js\";\nimport {\n drawnLengthOf,\n drawnNodeLength,\n layoutScaling\n} from \"./chunk-6JEWNXCQ.js\";\nimport {\n closableDeletions,\n deletionEdges\n} from \"./chunk-N6FECAXP.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/pipeline.ts\nfunction loadGraph(text, name, opts = {}) {\n const graph = anchorGraph(\n convertGFAToGraph(parseGFA(text), name),\n opts.referencePath\n );\n if (graph.nodes.length === 0) {\n throw new Error(`No graph segments in ${name}`);\n }\n if (opts.maxNodes !== void 0 && graph.nodes.length > opts.maxNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${opts.maxNodes.toLocaleString()}). Zoom in to a smaller region, or raise maxGraphNodes on this view.`\n );\n }\n return graph;\n}\nvar ENGINE_DEFAULTS = {\n engine: \"fmmm\",\n quality: 2,\n linearLayout: false,\n bubbleSpread: \"auto\",\n spacing: 1,\n componentSeparation: 1,\n showDeletionEdges: true\n};\nfunction engineSettingsOf(s = {}) {\n return {\n engine: s.engine ?? ENGINE_DEFAULTS.engine,\n quality: s.quality ?? ENGINE_DEFAULTS.quality,\n linearLayout: s.linearLayout ?? ENGINE_DEFAULTS.linearLayout,\n bubbleSpread: s.bubbleSpread ?? ENGINE_DEFAULTS.bubbleSpread,\n spacing: s.spacing ?? ENGINE_DEFAULTS.spacing,\n componentSeparation: s.componentSeparation ?? ENGINE_DEFAULTS.componentSeparation,\n showDeletionEdges: s.showDeletionEdges ?? ENGINE_DEFAULTS.showDeletionEdges\n };\n}\nvar COMPONENT_SEPARATION = 15;\nfunction engineRequest(graph, scaling, settings) {\n const anchored = graph.nodes.some(isBackbone);\n const spaced = {\n ...scaling,\n opts: {\n ...scaling.opts,\n edgeLength: scaling.opts.edgeLength * (settings.spacing ?? 1)\n }\n };\n return {\n graph: {\n nodes: anchored ? seededNodes(graph, spaced) : spaced.nodes,\n edges: graph.edges\n },\n options: {\n quality: settings.quality,\n linearLayout: settings.linearLayout,\n ...spaced.opts,\n componentSeparation: COMPONENT_SEPARATION * (settings.componentSeparation ?? 1),\n ...anchored ? { rotateComponents: false } : {},\n engine: settings.engine ?? \"fmmm\"\n }\n };\n}\nfunction engineKey(graph, settings) {\n const anchored = graph.nodes.some(isBackbone);\n return `${settings.engine ?? \"fmmm\"}|${settings.quality}|${settings.linearLayout}|${settings.bubbleSpread}|${settings.spacing ?? 1}|${settings.componentSeparation ?? 1}|${settings.showDeletionEdges !== false}|${anchored}|${graph.referencePath ?? \"\"}`;\n}\nasync function forceLayout(graph, settings, engine) {\n const spread = spreadFor(settings.bubbleSpread);\n const found = deletionEdges(graph);\n const dropped = settings.showDeletionEdges === false ? closableDeletions(graph, found) : /* @__PURE__ */ new Set();\n const deletions = found.filter((d) => !dropped.has(d.edgeIndex));\n const routed = withDeletionRoutes(graph, deletions, dropped);\n const merged = mergeRuns(routed.graph, routed.ids);\n const runs = {\n ...merged.graph,\n nodes: merged.graph.nodes.filter((n) => !routed.ids.has(n.id))\n };\n const engineScaling = layoutScaling(runs, spread);\n const { result, duration } = await engine(\n engineRequest(\n merged.graph,\n {\n ...engineScaling,\n nodes: [\n ...engineScaling.nodes,\n ...routeNodes(\n graph,\n deletions,\n routed.routes,\n drawnLengthOf(runs, spread),\n engineScaling.opts\n )\n ]\n },\n settings\n )\n );\n const scaling = layoutScaling(graph, spread);\n const drawn = new Map(\n scaling.nodes.map((n) => [n.id, drawnNodeLength(scaling.opts, n.length)])\n );\n const positions = splitRuns(\n result.nodePositions,\n merged.runs,\n (id) => drawn.get(id) ?? 0\n );\n const { nodePositions, deletionRoutes } = takeRoutes(\n graph.nodes.some(isBackbone) ? orientToReference(graph, positions) : positions,\n routed.routes\n );\n return {\n result: {\n ...result,\n nodePositions,\n stranded: true,\n ...deletions.length ? { deletionRoutes, extent: layoutExtent(deletionRoutes) } : {}\n },\n duration\n };\n}\nfunction layoutExtent(nodePositions) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const segments of Object.values(nodePositions)) {\n for (const seg of segments) {\n minX = Math.min(minX, seg.x);\n minY = Math.min(minY, seg.y);\n maxX = Math.max(maxX, seg.x);\n maxY = Math.max(maxY, seg.y);\n }\n }\n return { minX, minY, maxX, maxY };\n}\nvar FIT_PADDING = 40;\nvar MIN_ZOOM = 1e-6;\nvar MAX_ZOOM = 100;\nfunction clampZoom(zoom) {\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoom));\n}\nfunction fittedTranslateY(bounds, usableHeight, yScale, padTop = FIT_PADDING) {\n const leftoverY = usableHeight - bounds.h * yScale;\n return padTop - bounds.minY * yScale + Math.max(0, leftoverY) / 2;\n}\nfunction fitTransform(bounds, paneWidth, paneHeight, pixelRows, {\n minScale = 0,\n padLeft = FIT_PADDING,\n padTop = FIT_PADDING,\n padRight = FIT_PADDING,\n padBottom = FIT_PADDING\n} = {}) {\n const usableWidth = paneWidth - padLeft - padRight;\n const usableHeight = paneHeight - padTop - padBottom;\n if (usableWidth <= 0 || usableHeight <= 0 || !(bounds.w > 0 || !pixelRows && bounds.h > 0)) {\n return void 0;\n }\n const fitX = bounds.w > 0 ? usableWidth / bounds.w : Infinity;\n const fitY = bounds.h > 0 ? usableHeight / bounds.h : Infinity;\n const scale = clampZoom(\n Math.max(minScale, pixelRows ? fitX : Math.min(fitX, fitY))\n );\n const leftoverX = usableWidth - bounds.w * scale;\n return {\n scale,\n translateX: padLeft - bounds.minX * scale + Math.max(0, leftoverX) / 2,\n translateY: fittedTranslateY(\n bounds,\n usableHeight,\n pixelRows ? 1 : scale,\n padTop\n )\n };\n}\nfunction drawingBounds(layout, opts = {}) {\n let { minX, minY, maxX, maxY } = layoutExtent(layout.nodePositions);\n const { region } = opts;\n if (layout.referenceAxis && region && region.end > region.start) {\n minX = region.start;\n maxX = region.end;\n }\n const extent = opts.extent ?? layout.extent;\n if (extent) {\n minX = Math.min(minX, extent.minX ?? minX);\n minY = Math.min(minY, extent.minY ?? minY);\n maxX = Math.max(maxX, extent.maxX ?? maxX);\n maxY = Math.max(maxY, extent.maxY ?? maxY);\n }\n return { minX, minY, w: maxX - minX, h: maxY - minY };\n}\n\nexport {\n loadGraph,\n ENGINE_DEFAULTS,\n engineSettingsOf,\n engineRequest,\n engineKey,\n forceLayout,\n layoutExtent,\n FIT_PADDING,\n clampZoom,\n fittedTranslateY,\n fitTransform,\n drawingBounds\n};\n", "import {\n engineKey,\n forceLayout\n} from \"./chunk-WZATPZNH.js\";\n\n// src/layout/forceCache.ts\nvar DEFAULT_SIZE = 4;\nfunction createForceLayoutCache(size = DEFAULT_SIZE) {\n const caches = /* @__PURE__ */ new WeakMap();\n const cacheOf = (graph) => {\n let cache = caches.get(graph);\n if (!cache) {\n cache = /* @__PURE__ */ new Map();\n caches.set(graph, cache);\n }\n return cache;\n };\n return {\n layout(graph, settings, engine) {\n const cache = cacheOf(graph);\n const key = engineKey(graph, settings);\n const hit = cache.get(key);\n if (hit) {\n return hit.run;\n }\n if (cache.size >= size) {\n cache.delete(cache.keys().next().value);\n }\n const started = performance.now();\n const entry = {\n run: forceLayout(graph, settings, engine).then((r) => {\n entry.done = r.result;\n return { ...r, duration: r.duration || performance.now() - started };\n })\n };\n entry.run.catch(() => cache.delete(key));\n cache.set(key, entry);\n return entry.run;\n },\n ready(graph, settings) {\n return caches.get(graph)?.get(engineKey(graph, settings))?.done;\n },\n inherit(from, to) {\n const cache = caches.get(from);\n if (cache && from !== to) {\n caches.set(to, cache);\n }\n }\n };\n}\n\nexport {\n createForceLayoutCache\n};\n", "import {\n clampZoom\n} from \"./chunk-WZATPZNH.js\";\n\n// src/viewport.ts\nfunction axisScaleOf(scale, pixelRows) {\n return { scaleX: scale, scaleY: pixelRows ? 1 : scale, pixelRows };\n}\nfunction viewportOf(t, axis, width, height) {\n return {\n minX: -t.translateX / axis.scaleX,\n minY: -t.translateY / axis.scaleY,\n maxX: (width - t.translateX) / axis.scaleX,\n maxY: (height - t.translateY) / axis.scaleY\n };\n}\nfunction padded(v, panes) {\n const w = (v.maxX - v.minX) * panes;\n const h = (v.maxY - v.minY) * panes;\n return {\n minX: v.minX - w,\n minY: v.minY - h,\n maxX: v.maxX + w,\n maxY: v.maxY + h\n };\n}\nfunction contains(outer, inner) {\n return inner.minX >= outer.minX && inner.maxX <= outer.maxX && inner.minY >= outer.minY && inner.maxY <= outer.maxY;\n}\nfunction zoomAbout(t, factor, centerX, centerY, pixelRows) {\n const scale = clampZoom(t.scale * factor);\n const ratio = scale / t.scale;\n return {\n scale,\n translateX: centerX - (centerX - t.translateX) * ratio,\n translateY: pixelRows ? t.translateY : centerY - (centerY - t.translateY) * ratio\n };\n}\nfunction screenToLayout(x, y, t, axis) {\n return {\n x: (x - t.translateX) / axis.scaleX,\n y: (y - t.translateY) / axis.scaleY\n };\n}\n\nexport {\n axisScaleOf,\n viewportOf,\n padded,\n contains,\n zoomAbout,\n screenToLayout\n};\n", "import { types } from '@jbrowse/mobx-state-tree'\n\n// Persisted choices that read a value outside `values` as unset. A plain\n// `types.enumeration` throws on one, so a session saved by a build that had an\n// option this one dropped failed to load at all; here it opens on the default.\nfunction knownOrUnset<T extends string>(values: readonly T[]) {\n return (value: string | undefined) =>\n values.includes(value as T) ? (value as T) : undefined\n}\n\nexport function lenientMaybeEnum<T extends string>(values: T[]) {\n return types.snapshotProcessor(types.maybe(types.enumeration(values)), {\n preProcessor: knownOrUnset(values),\n })\n}\n\nexport function lenientOptionalEnum<T extends string>(\n values: T[],\n fallback: T,\n) {\n return types.snapshotProcessor(\n types.optional(types.enumeration(values), fallback),\n { preProcessor: knownOrUnset(values) },\n )\n}\n", "import { contains } from '@jbrowse/bandage-core/viewport'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer } from '@jbrowse/mobx-state-tree'\nimport { autorun, reaction, untracked } from 'mobx'\n\nimport { withLoadActions } from './loadActions'\nimport { EMPTY_BATCH, dependOn, paneViewportOf } from './paneBase'\nimport {\n hoverInRegion,\n nodeForLgvHover,\n readLgvHover,\n} from '../../hoverSync/lgvHover'\nimport { walksForRow } from '../../hoverSync/rowWalks'\n\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\n\nexport const withRenderingActions = withLoadActions\n .actions(self => ({\n startRenderingBackend(backend: Renderer) {\n if (!self.autorunsInstalled) {\n // Autorun: keep the view fitted to the graph until the user moves it.\n // Reading fittedTransform tracks everything the fit depends on, so\n // it re-fits as the layout arrives, the canvas is measured and the\n // genes over a tube map claim their rows. A manual pan/zoom (or a\n // restored-session transform) makes the viewport the user's, and a\n // host makes it the linear view's.\n addDisposer(\n self,\n autorun(() => {\n if (\n self.fittedTransform &&\n untracked(() => self.viewportOwner === 'fit')\n ) {\n self.zoomToFit()\n }\n }),\n )\n\n addDisposer(\n self,\n // Faceting on or off, its columns, its count of panels and what\n // they split by each reshape the boxes the drawing is fitted into\n reaction(\n () => {\n const grid = self.facetGrid\n return grid\n ? `${self.facet.field} ${self.facetPanels?.length} ${grid.columns}`\n : ''\n },\n () => {\n self.refitView()\n },\n ),\n )\n // The walk rows' genes follow the rows: a new cut, a repeat pick or\n // a sample filter changes which haplotypes and spans they read\n addDisposer(\n self,\n reaction(\n () => ({\n graph: self.graph,\n reads: JSON.stringify(self.walkGeneReads?.reads ?? []),\n }),\n () => {\n void self.loadWalkGenes()\n },\n {\n fireImmediately: true,\n equals: (a, b) => a.graph === b.graph && a.reads === b.reads,\n },\n ),\n )\n // Walk rows read the source track's samples TSV, for Group by\u2026\n addDisposer(\n self,\n reaction(\n () =>\n self.chosenLayoutMode === 'walkrows'\n ? JSON.stringify(self.walkRowSamplesTsv ?? null)\n : undefined,\n key => {\n if (key !== undefined) {\n void self.loadWalkRowSampleTable()\n }\n },\n { fireImmediately: true },\n ),\n )\n // A host fits the rows once, when it takes the pane over, which is\n // before the legend measures the room it needs above them\n addDisposer(\n self,\n reaction(\n () => self.fitPadTop,\n () => {\n if (self.viewportOwner === 'host') {\n self.zoomToFit()\n }\n },\n ),\n )\n\n // Autorun: mirror a connected linear view's hover onto the graph. An\n // LGV writes `{hoverPosition, hoverFeature}` to session.hovered on\n // every mousemove; neither field names the source view, so the guard\n // is that the position lies in the region this graph was cut from.\n // A pointer over the pane itself is the host's too, at a bp its x\n // only means on a reference-axis layout, so there the pane's own hit\n // test is the hover.\n //\n // Only `hovered` is tracked \u2014 the graph reads are untracked, so a\n // geometry rebuild can't re-fire this and clobber a hover the canvas\n // itself set. Assigning an unchanged id doesn't notify, so a hover\n // that travels within one segment costs nothing downstream.\n addDisposer(\n self,\n autorun(() => {\n const hover = readLgvHover(getSession(self).hovered)\n untracked(() => {\n const region = self.graphRegion\n const graph = self.graph\n const inRegion =\n hover && region && hoverInRegion(hover, region)\n ? hover\n : undefined\n // a row naming a walk is the hover, not the node at its bp,\n // whose band would cover the row's own cells\n const rowWalks =\n inRegion?.featureName && graph?.paths\n ? walksForRow(inRegion.featureName, graph.paths)\n : []\n if (region && graph && !self.pointerInPane) {\n self.setHoveredNode(\n inRegion && rowWalks.length === 0\n ? nodeForLgvHover({ hover: inRegion, nodes: graph.nodes })\n : null,\n )\n }\n self.setHoveredRowWalks(rowWalks)\n })\n }),\n )\n\n // Reaction: drop a hover the pointer cannot still be over.\n //\n // A hover is set by a mousemove on the canvas, and here the drawing\n // moves under a STATIONARY cursor on three axes \u2014 the wheel zoom, the\n // toolbar's zoom and fit buttons, and a pan \u2014 none of which fire a\n // pointer event. Left alone the tooltip goes on naming the node that\n // used to be under the cursor, `hoverHighlight` goes on publishing its\n // span, and the paired linear view paints a band over the wrong\n // sequence until the mouse happens to move.\n //\n // This is jbrowse-components' `installClearHoverOnViewportChange`\n // (BaseLinearDisplay), whose three axes are bpPerPx / offsetPx /\n // scrollTop; a graph view's are its own transform. Its rule is worth\n // restating rather than just citing: a sticky canvas gets no\n // mousemove and no mouseleave for any of them. Not imported because\n // it lives in the LGV plugin and reads a containing LGV, and this\n // plugin deliberately takes no runtime dependency on that plugin\n // (see hoverSync/index.tsx).\n //\n // A `reaction`, not an autorun, for the reason stated there: the\n // effect touches hover state, and an autorun would re-enter itself.\n // Selection is untouched \u2014 a click is a choice, and the content\n // moving does not unmake it.\n addDisposer(\n self,\n reaction(\n () => `${self.scale}-${self.translateX}-${self.translateY}`,\n () => {\n self.setHoveredNode(null)\n self.setHoveredBubble(null)\n self.setHoveredEdge(null)\n },\n { name: 'GraphClearHoverOnViewportChange' },\n ),\n )\n\n // Autorun: a zoom, or a pan that leaves the window the last build\n // covered, schedules a debounced rebuild. A pan inside it costs a\n // repaint and nothing else. Skips the first run.\n let firstViewport = true\n addDisposer(\n self,\n autorun(() => {\n const { scale } = self\n const viewport = paneViewportOf(self)\n if (firstViewport) {\n firstViewport = false\n return\n }\n const built = untracked(() => self.builtViewport)\n if (built?.scale === scale && contains(built.bounds, viewport)) {\n return\n }\n self.scheduleViewportDirty()\n }),\n )\n\n // Autorun: hover and selection. Tracks `geometryVersion` because an\n // upload drops the renderer's edge highlight.\n addDisposer(\n self,\n autorun(() => {\n const b = self.currentRenderingBackend as Renderer | undefined\n dependOn(self.geometryVersion)\n if (b) {\n self.applyHighlights(b)\n self.renderNow()\n }\n }),\n )\n }\n\n // The second argument is a SETUP THUNK, not the callbacks themselves:\n // anything it closes over lives exactly as long as the callbacks that\n // read it, which is what lets a per-backend memo work.\n self.attachRenderingBackend<Renderer>(backend, () => ({\n // Autorun: rebuild geometry when graph data or display options\n // change. scale/translate are untracked so they don't trigger a full\n // rebuild \u2014 only the debounced viewportDirty flag does.\n upload: (b: Renderer) => {\n b.resize(self.paneWidth, self.canvasHeight)\n if (self.layoutResult?.tubeMap) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, 0, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => paneViewportOf(self)),\n })\n return true\n }\n if (self.facetPanels) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, 0, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => self.viewportToBuild()),\n })\n return true\n }\n const geometryStart = performance.now()\n const built = self.buildDrawing(\n self.walkLift,\n self.effectiveDrawPaths,\n )\n if (built) {\n b.uploadGeometry(built.batch)\n self.setGeometryMetrics(\n performance.now() - geometryStart,\n built.batch.nodeStrokes.length,\n {\n scale: untracked(() => self.scale),\n bounds: built.viewportBounds,\n },\n )\n return true\n }\n // Nothing reached the backend, so the autorun may skip the redraw\n // it would otherwise force. Safe despite the resize above: with no\n // positions there is nothing to draw, which is the same case\n // `render` below returns false for.\n return false\n },\n // Autorun: re-render on pan/zoom/darkMode without rebuilding geometry\n render: (b: Renderer) => {\n if (!self.nodePositions) {\n return false\n }\n self.paint(b)\n self.markPainted()\n return true\n },\n releaseTargets: (b: Renderer) => {\n b.releaseOffscreenTargets()\n },\n }))\n },\n }))\n .actions(self => ({\n // A layout picked from a menu: the mode, then the drawing it makes.\n switchLayout(mode: LayoutModeValue) {\n self.setLayoutMode(mode)\n return self.recomputeLayout()\n },\n // Deletion edges shape a force layout, so it is laid out again without them\n toggleDeletionEdges() {\n self.setShowDeletionEdges(!self.showDeletionEdges)\n return self.usesLayoutEngine ? self.recomputeLayout() : undefined\n },\n // loads the source again, for a host that has one\n retryLoad() {},\n afterAttach() {\n // A restored session that already carries a non-default transform is\n // the user's own view \u2014 mark it so the fit autorun leaves it alone.\n if (!self.isDefaultViewport) {\n self.viewportOwner = 'user'\n }\n },\n }))\n", "import {\n trimOrigins\n} from \"./chunk-ST2IBUAN.js\";\n\n// src/bubbles/popBubble.ts\nfunction bubbleSubgraph(graph, segmentIds) {\n const keep = new Set(segmentIds);\n const nodes = graph.nodes.filter((n) => keep.has(n.name));\n const ids = new Set(nodes.map((n) => n.id));\n const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));\n const kept = /* @__PURE__ */ new Map();\n const paths = graph.paths?.flatMap((p) => {\n const first = p.nodeIds.findIndex((id) => ids.has(id));\n if (first < 0) {\n return [];\n }\n const nodeIds = p.nodeIds.filter((id) => ids.has(id));\n kept.set(p.name, { first, nodeIds });\n const before = p.nodeIds.slice(0, first).reduce((sum, id) => sum + (lengthOf.get(id) ?? 0), 0);\n return [\n {\n ...p,\n nodeIds,\n ...p.start === void 0 ? {} : { start: p.start + before }\n }\n ];\n });\n return {\n name: graph.name,\n nodes,\n edges: graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to)),\n ...paths?.length ? { paths } : {},\n anchorPaths: trimOrigins(graph, kept),\n pathVisits: graph.pathVisits,\n anchoredBy: graph.anchoredBy,\n referencePath: graph.referencePath\n };\n}\n\nexport {\n bubbleSubgraph\n};\n", "import {\n pathOrigin,\n trimOrigins\n} from \"../chunks/chunk-ST2IBUAN.js\";\nimport \"../chunks/chunk-BPLIXMH7.js\";\nimport {\n isBackbone,\n overlapsWindow\n} from \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/layout/trimToWindow.ts\nfunction trimToWindow(graph, window) {\n const inWindow = new Set(\n graph.nodes.filter((n) => isBackbone(n) && overlapsWindow(n, window)).map((n) => n.id)\n );\n const paths = graph.paths ?? [];\n if (inWindow.size === 0 || paths.length === 0) {\n return graph;\n }\n const spans = paths.map((path) => {\n let first = -1;\n let last = -1;\n path.nodeIds.forEach((id, i) => {\n if (inWindow.has(id)) {\n if (first < 0) {\n first = i;\n }\n last = i;\n }\n });\n return first < 0 ? void 0 : { first, last };\n });\n if (spans.every(\n (span, i) => span?.first === 0 && span.last === paths[i].nodeIds.length - 1\n )) {\n return graph;\n }\n const kept = /* @__PURE__ */ new Set();\n const trimmed = [];\n const stretches = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n const span = spans[i];\n if (span) {\n const nodeIds = path.nodeIds.slice(span.first, span.last + 1);\n for (const id of nodeIds) {\n kept.add(id);\n }\n trimmed.push({ ...path, nodeIds });\n stretches.set(path.name, { first: span.first, nodeIds });\n }\n });\n return {\n ...graph,\n nodes: graph.nodes.filter((n) => kept.has(n.id)),\n edges: graph.edges.filter((e) => kept.has(e.from) && kept.has(e.to)),\n paths: trimmed,\n pathVisits: graph.pathVisits && trimVisits(\n graph.pathVisits,\n paths,\n spans,\n new Map(graph.nodes.map((n) => [n.id, n.name]))\n ),\n anchorPaths: trimOrigins(graph, stretches)\n };\n}\nfunction trimVisits(visits, paths, spans, nameOf) {\n const cursor = /* @__PURE__ */ new Map();\n const out = /* @__PURE__ */ new Map();\n paths.forEach((path, p) => {\n const origin = pathOrigin(path.name).name;\n const span = spans[p];\n path.nodeIds.forEach((id, i) => {\n const segment = nameOf.get(id) ?? id;\n const list = visits.get(segment);\n if (!list) {\n return;\n }\n const key = `${origin}\t${segment}`;\n let at = cursor.get(key) ?? 0;\n while (at < list.length && list[at].path !== origin) {\n at++;\n }\n const visit = list[at];\n cursor.set(key, at + 1);\n if (visit && span && i >= span.first && i <= span.last) {\n const keptVisits = out.get(segment);\n if (keptVisits) {\n keptVisits.push(visit);\n } else {\n out.set(segment, [visit]);\n }\n }\n });\n });\n return out;\n}\nexport {\n trimToWindow\n};\n", "import {\n visitStrands\n} from \"../chunks/chunk-W2I4DOL4.js\";\nimport {\n canonicalStrand\n} from \"../chunks/chunk-TEDQJPMI.js\";\nimport \"../chunks/chunk-C44YRP5F.js\";\nimport \"../chunks/chunk-7GBL7SJY.js\";\nimport \"../chunks/chunk-3ZZSX5HN.js\";\nimport \"../chunks/chunk-AB35TJST.js\";\nimport {\n pathOrigin\n} from \"../chunks/chunk-ST2IBUAN.js\";\nimport \"../chunks/chunk-BPLIXMH7.js\";\nimport \"../chunks/chunk-TAMCZHLW.js\";\nimport \"../chunks/chunk-N6FECAXP.js\";\nimport \"../chunks/chunk-2CVHXFK7.js\";\nimport \"../chunks/chunk-CPMHA4W5.js\";\nimport {\n isBackbone\n} from \"../chunks/chunk-FYQWPEEY.js\";\n\n// src/tubeMap/coarsen.ts\nfunction readWalk(path, nodeById, strands) {\n const visitName = pathOrigin(path.name).name;\n const seen = /* @__PURE__ */ new Map();\n const runs = [];\n const open = () => ({ a: -Infinity, b: Infinity, detour: [], bp: 0 });\n const gaps = [open()];\n for (const id of path.nodeIds) {\n const node = nodeById.get(id);\n if (!node) {\n continue;\n }\n const k = seen.get(node.name) ?? 0;\n seen.set(node.name, k + 1);\n const strand = strands.get(`${visitName}\t${node.name}`)?.[k] ?? canonicalStrand(node);\n const gap = gaps.at(-1);\n const last = runs.at(-1);\n if (isBackbone(node)) {\n const start = node.stable.start;\n const end = start + node.length;\n const inverted = strand !== (node.stable.strand ?? \"+\");\n const joins = last !== void 0 && gap.detour.length === 0;\n if (joins && !last.inverted && !inverted && last.end === start) {\n last.end = end;\n } else if (joins && last.inverted && inverted && last.start === end) {\n last.start = start;\n } else {\n runs.push({ start, end, inverted });\n gaps.push(open());\n }\n } else {\n gap.detour.push({ node, strand });\n gap.bp += node.length;\n }\n }\n runs.forEach((run, i) => {\n gaps[i].b = run.start;\n gaps[i + 1].a = run.end;\n });\n return { path, runs, gaps };\n}\nfunction isSmall(gap, sigma) {\n return Number.isFinite(gap.a) && Number.isFinite(gap.b) && gap.b >= gap.a && Math.max(gap.b - gap.a, gap.bp) < sigma;\n}\nfunction strictlyInside(cuts, a, b) {\n let lo = 0;\n let hi = cuts.length;\n while (lo < hi) {\n const mid = lo + hi >> 1;\n if (cuts[mid] <= a) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n return lo < cuts.length && cuts[lo] < b;\n}\nfunction referenceGaps(backbone) {\n const cuts = /* @__PURE__ */ new Map();\n for (let i = 1; i < backbone.length; i++) {\n const prev = backbone[i - 1];\n const node = backbone[i];\n const end = prev.stable.start + prev.length;\n if (end !== node.stable.start) {\n cuts.set(end, \"reference-gap\");\n cuts.set(node.stable.start, \"reference-gap\");\n }\n }\n return cuts;\n}\nfunction findCuts(walks, sigma, cuts) {\n const cut = (bp, cause) => {\n if (Number.isFinite(bp) && !cuts.has(bp)) {\n cuts.set(bp, cause);\n }\n };\n for (const { runs, gaps } of walks) {\n const first = runs[0];\n const last = runs.at(-1);\n if (first && last) {\n cut(first.start, \"walk-end\");\n cut(last.end, \"walk-end\");\n }\n for (const run of runs) {\n if (run.inverted && run.end - run.start >= sigma) {\n cut(run.start, \"inversion\");\n cut(run.end, \"inversion\");\n }\n }\n for (const gap of gaps) {\n if (gap.b < gap.a) {\n cut(gap.a, \"backward\");\n cut(gap.b, \"backward\");\n } else if (!isSmall(gap, sigma)) {\n cut(gap.a, \"variant\");\n cut(gap.b, \"variant\");\n }\n }\n }\n for (let changed = true; changed; ) {\n changed = false;\n const sorted = [...cuts.keys()].sort((x, y) => x - y);\n const spans = walks.flatMap(({ runs, gaps }) => [\n ...gaps.filter((g) => isSmall(g, sigma)).map((g) => [g.a, g.b]),\n ...runs.filter((r) => r.inverted && r.end - r.start < sigma).map((r) => [r.start, r.end])\n ]);\n for (const [a, b] of spans) {\n if (strictlyInside(sorted, a, b)) {\n changed ||= !cuts.has(a) || !cuts.has(b);\n cut(a, \"overlap\");\n cut(b, \"overlap\");\n }\n }\n }\n return cuts;\n}\nfunction mergeReference(backbone, cuts) {\n const merged = [];\n let group = [];\n const close = () => {\n const first = group[0];\n const last = group.at(-1);\n if (first && last) {\n const bp0 = first.stable.start;\n const bp1 = last.stable.start + last.length;\n const name = `${bp0}-${bp1}`;\n merged.push({\n node: {\n id: `${name}+`,\n name,\n length: bp1 - bp0,\n depth: 0,\n stable: {\n refName: first.stable.refName,\n start: bp0,\n rank: 0,\n strand: \"+\"\n }\n },\n members: group\n });\n }\n group = [];\n };\n for (const node of backbone) {\n if (cuts.has(node.stable.start)) {\n close();\n }\n group.push(node);\n }\n close();\n return merged;\n}\nfunction coarsenTubeMap(graph, sigma) {\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const paths = graph.paths ?? [];\n if (backbone.length === 0 || paths.length === 0) {\n return void 0;\n }\n const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));\n const strands = visitStrands(graph);\n const walks = paths.map((p) => readWalk(p, nodeById, strands));\n const cuts = findCuts(walks, sigma, referenceGaps(backbone));\n const sortedCuts = [...cuts.keys()].sort((x, y) => x - y);\n const merged = mergeReference(backbone, cuts);\n const starts = merged.map((m) => m.node.stable.start);\n const mergedAt = (bp) => {\n let lo = 0;\n let hi = starts.length - 1;\n while (lo < hi) {\n const mid = lo + hi + 1 >> 1;\n if (starts[mid] <= bp) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo;\n };\n const members = /* @__PURE__ */ new Map();\n const coarseOf = /* @__PURE__ */ new Map();\n for (const m of merged) {\n members.set(\n m.node.id,\n m.members.map((n) => n.id)\n );\n for (const n of m.members) {\n coarseOf.set(n.id, m.node.id);\n }\n }\n const routes = /* @__PURE__ */ new Map();\n const routeFor = (gap) => {\n const key = `${gap.a}\t${gap.b}\t${gap.detour.map((s) => s.node.id + s.strand).join(\",\")}`;\n let node = routes.get(key);\n if (!node) {\n const name = `r${routes.size}`;\n node = {\n id: `${name}+`,\n name,\n length: gap.bp,\n depth: 0,\n stable: {\n refName: backbone[0].stable.refName,\n start: Number.isFinite(gap.a) ? gap.a : gap.b,\n rank: 1,\n strand: \"+\"\n }\n };\n routes.set(key, node);\n members.set(\n node.id,\n gap.detour.map((s) => s.node.id)\n );\n for (const s of gap.detour) {\n if (!coarseOf.has(s.node.id)) {\n coarseOf.set(s.node.id, node.id);\n }\n }\n }\n return node;\n };\n const deviations = /* @__PURE__ */ new Map();\n const coarsePaths = [];\n const pathVisits = /* @__PURE__ */ new Map();\n const edges = /* @__PURE__ */ new Map();\n const depth = /* @__PURE__ */ new Map();\n for (const { path, runs, gaps } of walks) {\n const steps = [];\n const devs = [];\n let continuing = false;\n const append = (node, strand) => {\n const last = steps.at(-1);\n if (!(continuing && last?.node === node && last.strand === strand)) {\n steps.push({ node, strand });\n }\n continuing = true;\n };\n const structural = (gap) => {\n continuing = false;\n if (gap.detour.length > 0) {\n append(routeFor(gap), \"+\");\n continuing = false;\n }\n };\n const fold = (gap) => {\n if (gap.bp > 0 || gap.b > gap.a) {\n devs.push({ start: gap.a, end: gap.b, bp: gap.bp });\n }\n const home = merged[mergedAt(gap.b > gap.a ? gap.a : gap.a - 1)];\n for (const s of gap.detour) {\n if (!coarseOf.has(s.node.id)) {\n coarseOf.set(s.node.id, home.node.id);\n members.get(home.node.id).push(s.node.id);\n }\n }\n };\n runs.forEach((run, i) => {\n const gap = gaps[i];\n if (isSmall(gap, sigma) && !strictlyInside(sortedCuts, gap.a, gap.b)) {\n fold(gap);\n } else {\n structural(gap);\n }\n const i0 = mergedAt(run.start);\n const i1 = mergedAt(run.end - 1);\n const small = run.end - run.start < sigma;\n if (run.inverted && !small) {\n continuing = false;\n for (let j = i1; j >= i0; j--) {\n append(merged[j].node, \"-\");\n }\n continuing = false;\n } else {\n if (run.inverted) {\n devs.push({\n start: run.start,\n end: run.end,\n bp: run.end - run.start,\n inverted: true\n });\n }\n for (let j = i0; j <= i1; j++) {\n append(merged[j].node, \"+\");\n }\n }\n });\n structural(gaps.at(-1));\n const visitName = pathOrigin(path.name).name;\n let pos = 0;\n steps.forEach(({ node, strand }, i) => {\n depth.set(node.id, (depth.get(node.id) ?? 0) + 1);\n const visits = pathVisits.get(node.name) ?? [];\n visits.push({\n path: visitName,\n sample: path.sample ?? visitName,\n start: pos,\n strand\n });\n pathVisits.set(node.name, visits);\n pos += node.length;\n const next = steps[i + 1];\n if (next) {\n const key = `${node.id}${strand}\t${next.node.id}${next.strand}`;\n const edge = edges.get(key);\n if (edge) {\n edge.pathIds.push(path.name);\n } else {\n edges.set(key, {\n from: node.id,\n to: next.node.id,\n fromStrand: strand,\n toStrand: next.strand,\n pathIds: [path.name]\n });\n }\n }\n });\n coarsePaths.push({ ...path, nodeIds: steps.map((s) => s.node.id) });\n deviations.set(path.name, devs);\n }\n const nodes = [...merged.map((m) => m.node), ...routes.values()].filter((n) => depth.has(n.id)).map((n) => ({ ...n, depth: depth.get(n.id) }));\n return {\n graph: {\n ...graph,\n nodes,\n edges: [...edges.values()],\n paths: coarsePaths,\n pathVisits,\n reads: void 0\n },\n members,\n coarseOf,\n deviations,\n cuts\n };\n}\nexport {\n coarsenTubeMap\n};\n", "import {\n BUBBLE_KIND_NAMES,\n bubbleSegmentIds,\n classifyBubble,\n} from '@jbrowse/bandage-core/bubbles/classifyBubble'\nimport { bubbleSubgraph } from '@jbrowse/bandage-core/bubbles/popBubble'\nimport { trimToWindow } from '@jbrowse/bandage-core/layout/trimToWindow'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n anchorFromPaths,\n chooseReferencePath,\n} from '@jbrowse/bandage-core/pathAnchoring'\nimport { engineSettingsOf, loadGraph } from '@jbrowse/bandage-core/pipeline'\nimport { assemblyWalk } from '@jbrowse/bandage-core/reference'\nimport { coarsenTubeMap } from '@jbrowse/bandage-core/tubeMap/coarsen'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport {\n getRpcSessionId,\n getSession,\n statusMessageText,\n} from '@jbrowse/core/util'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { flow, isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { TUBE_MAP_MODES, bubblePrefix, forceLayouts } from './paneBase'\nimport { withSettingActions } from './settingActions'\nimport { namesReads } from '../../GetGraphReads'\nimport { locLabel } from '../../launchFromGraph/contributors'\nimport { geneModelsFrom } from '../genes/geneFeatures'\nimport { repeatArraysFrom } from '../repeats/repeatFeatures'\nimport { parseSamplesTsv } from '../walkRowGroups'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../../GetSubgraph'\nimport type { GafReads } from '../../gaf/gafFile'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport const withLoadActions = withSettingActions.actions(self => {\n let loadController: AbortController | undefined\n // the samples TSV location the table was read from, or is being read from\n let sampleTableKey: string | undefined\n\n function callEngine(request: EngineRequest) {\n const { rpcManager } = getSession(self)\n return rpcManager.call(getRpcSessionId(self), 'GraphComputeLayout', {\n ...request,\n signal: loadController?.signal,\n // A StatusCallback takes an RpcStatus, not a string \u2014 it may be a\n // bare label, a phase, or a phase that threw. `statusMessageText` is\n // core's reader for the human-facing line.\n statusCallback: status => {\n self.setStatusMessage(statusMessageText(status) ?? '')\n },\n }) as Promise<{ result: LayoutResult; duration: number }>\n }\n\n function engineSettings() {\n return engineSettingsOf({\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n })\n }\n\n // Single dispatch point for every layout mode. A mode that returns a\n // result computed it locally; one that returns undefined can't draw this\n // graph and hands off to the remote FMMM engine, which is also how\n // 'force' is expressed. See LAYOUT_MODES.\n function* computeLayout(graph: Graph) {\n const start = performance.now()\n const tubeMap = TUBE_MAP_MODES.has(self.chosenLayoutMode)\n // a tube map draws the window; the cut's context is for walk rows\n const region = self.graphRegion\n const drawn = tubeMap && region ? trimToWindow(graph, region) : graph\n // reads are placed by the cut's segment names, which a fold renames\n const coarse =\n tubeMap && self.tubeMapFold > 0 && !drawn.reads\n ? coarsenTubeMap(drawn, self.tubeMapFold)\n : undefined\n const local = layoutModeByValue(self.chosenLayoutMode).run(\n coarse?.graph ?? drawn,\n self.graphRegion,\n self.host ? self.layoutResult?.sampleRows : undefined,\n )\n if (local) {\n const result =\n coarse && local.tubeMap\n ? { ...local, tubeMap: { ...local.tubeMap, coarse } }\n : local\n return { result, duration: performance.now() - start }\n }\n const settings = engineSettings()\n const hit = forceLayouts.ready(graph, settings)\n if (hit) {\n return { result: hit, duration: performance.now() - start }\n }\n return (yield forceLayouts.layout(graph, settings, callEngine)) as {\n result: LayoutResult\n duration: number\n }\n }\n\n // Which layout request is the live one. A layout is async and nothing in\n // the UI waits for it, so several are routinely in flight: every control\n // in the settings dialog fires `recomputeLayout` on change, and a force\n // layout takes seconds where an anchored one is instant.\n //\n // The graph identity below is not enough to order them, because the\n // competing requests are usually layouts of the SAME graph. Left to\n // resolve order the last one to FINISH won rather than the last one\n // asked for, so switching away from a slow force layout \u2014 to an anchored\n // mode, a cheaper bubble spread, a lower quality \u2014 drew the abandoned\n // one over the top of the chosen one seconds later, with the dropdown\n // still naming the choice that was discarded.\n let liveRequest = 0\n // a haplotype's genes by track and contig span, kept across cuts\n const walkGeneCache = new Map<string, GeneModel[]>()\n\n // Applied under a guard because a layout is async and the user can load a\n // different graph, or ask for a different layout of it, while one is in\n // flight; the stale result must not land.\n function* layoutInto(graph: Graph) {\n const request = ++liveRequest\n const isLive = () => self.graph === graph && request === liveRequest\n const signal = loadController?.signal\n let computed\n try {\n // the node cap is a drawing's cost, and walk rows draw a bar per walk\n if (self.modeDrawsNodes && graph.nodes.length > self.maxGraphNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${self.maxGraphNodes.toLocaleString()}). Pick Layout \u2192 Walk rows, zoom in to a smaller region, or raise maxGraphNodes on this view.`,\n )\n }\n computed = yield* computeLayout(graph)\n } catch (e) {\n // A discarded layout's failure is not the user's problem: the drawing\n // they asked for is on screen or on its way, and raising a banner\n // over it reports a graph as broken because a setting they moved on\n // from could not be drawn. An aborted one was discarded by the load\n // that replaced it, even when the graph is still the same object.\n if (!isLive() || signal?.aborted) {\n return false\n }\n throw e\n }\n const live = isLive()\n if (live) {\n self.layoutResult = computed.result\n self.setLayoutMs(computed.duration)\n }\n return live\n }\n\n // The walk a path graph's track puts on the region's assembly: the one\n // that names it, else the one chooseReferencePath infers\n function loadedReference(graph: Graph, region: SubgraphRegion) {\n const paths = graph.anchorPaths\n return graph.anchoredBy === 'paths' && paths\n ? (\n assemblyWalk(graph, self.assemblySpellings(region.assemblyName)) ??\n chooseReferencePath(paths, region.assemblyName)\n )?.name\n : undefined\n }\n\n // `keepSelection` for a re-cut of the same source: node ids survive one\n // where edge indexes do not, so the selection is found again by id.\n // `readsOf` fetches the reads over the parsed graph before its one\n // layout, since the tube map lays them out with the paths.\n function* parseAndLayout(\n text: string,\n name: string,\n region: SubgraphRegion | undefined,\n keepSelection = false,\n readsOf?: (graph: Graph) => Promise<GafReads>,\n ) {\n const signal = loadController?.signal\n self.setStatusMessage('Parsing GFA')\n const parsed = loadGraph(text, name, {\n referencePath: self.referencePath || region?.assemblyName,\n })\n const loaded = region ? loadedReference(parsed, region) : undefined\n const graph =\n !self.referencePath &&\n loaded !== undefined &&\n loaded !== parsed.referencePath\n ? anchorFromPaths(parsed, loaded)\n : parsed\n if (readsOf) {\n self.setStatusMessage('Reading alignments')\n try {\n const { records, total } = (yield readsOf(graph)) as GafReads\n graph.reads = records\n self.readsShown = { shown: records.length, total }\n } catch (e) {\n if (signal?.aborted) {\n return\n }\n console.warn('[GraphGenomeView] no reads for this graph', e)\n self.readsShown = undefined\n }\n if (signal?.aborted) {\n return\n }\n } else {\n self.readsShown = undefined\n }\n const selected = keepSelection ? self.selectedNode : null\n self.graph = graph\n self.graphRegion = region\n self.loadedReferencePath = loaded\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.popStack = []\n // hoveredEdge is an index into graph.edges and hoveredNode/selectedNode\n // are ids, so all three address the graph being replaced here. Carrying\n // them over points the tooltip and the highlight at whatever now happens\n // to sit at that index.\n self.clearInteractionState()\n if (selected !== null && self.nodeById?.has(selected)) {\n self.selectedNode = selected\n }\n self.setStatusMessage('Computing layout')\n yield* layoutInto(graph)\n }\n\n // Which load is the live one, for the reason liveRequest orders layouts:\n // every change in the settings dialog re-cuts, a remote cut takes seconds,\n // and the last one to finish is not the last one asked for.\n let liveLoad = 0\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n // The bubble index that the hosted HPRC build keeps beside its segments,\n // `<prefix>.bubbles.bed.gz`, read through the bubble adapter over the same\n // window. A graph whose source has no such file, the ordinary case for a\n // graph of one's own, keeps its derived bubbles, so a failure here is not\n // the graph's problem. A coarse cut reads none: its nodes are the\n // bubbles, and the index over its window can run to a chromosome's rows.\n function* loadBubbles(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n isLive: () => boolean,\n ) {\n // The track config arrives as written, so the prefix is either the\n // `uri` shorthand or the segments location it expands to.\n const prefix = bubblePrefix(adapterConfig)\n if (adapterConfig.type !== 'RgfaTabixAdapter' || prefix === undefined) {\n return\n }\n try {\n const features = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n {\n adapterConfig: {\n type: 'MinigraphBubbleAdapter',\n uri: `${prefix}.bubbles.bed.gz`,\n baseUri: adapterConfig.baseUri,\n assemblyNameToPanSN: adapterConfig.assemblyNameToPanSN,\n },\n regions: [region],\n },\n )) as Feature[]\n if (isLive()) {\n self.indexBubbles = features.map(f => ({\n refName: region.refName,\n start: f.get('start'),\n end: f.get('end'),\n segmentCount: f.get('segmentCount') as number,\n pathCount: (f.get('pathCount') as number | undefined) ?? 0,\n inversion: f.get('inversion') as boolean,\n shortestAlleleLength: f.get('shortestAlleleLength') as number,\n longestAlleleLength: f.get('longestAlleleLength') as number,\n segments: f.get('segments') as string,\n shortestAllele: undefined,\n longestAllele: undefined,\n }))\n }\n } catch (e) {\n console.warn('[GraphGenomeView] no bubble index for this graph', e)\n }\n }\n\n // A session track's features over the cut. Undefined when the session\n // has no such track or the read fails: an annotation is never the\n // graph's problem.\n function* trackFeatures(\n trackId: string | undefined,\n region: SubgraphRegion,\n what: string,\n ) {\n const session = getSession(self)\n const config = trackId\n ? session.tracks.find(t => t.trackId === trackId)\n : undefined\n if (!config) {\n return undefined\n }\n try {\n return (yield session.rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n {\n adapterConfig: readConfObject(config, 'adapter'),\n regions: [region],\n },\n )) as Feature[]\n } catch (e) {\n console.warn(`[GraphGenomeView] no ${what} for this graph`, e)\n return undefined\n }\n }\n\n // The gene track's features over the cut, which `geneFeatures` makes genes\n // of for the backbone to carry.\n function* loadGenes(region: SubgraphRegion, isLive: () => boolean) {\n const features = yield* trackFeatures(\n self.geneTrack?.trackId,\n region,\n 'genes',\n )\n if (features && isLive()) {\n self.geneTrackFeatures = features\n }\n }\n\n // The tandem repeat arrays over the cut, from the session's repeat\n // track, for the walk rows to measure between and tile by.\n function* loadRepeats(region: SubgraphRegion, isLive: () => boolean) {\n const features = yield* trackFeatures(\n self.repeatTrack?.trackId,\n region,\n 'repeats',\n )\n if (features && isLive()) {\n self.repeatArrays = repeatArraysFrom(features)\n }\n }\n\n // Raises `isLoading` before any fetch, so a view waiting on a remote file\n // shows its loading state instead of the import form. Text already in\n // hand is parsed without yielding first. `region` is the window a\n // declared file was stated beside, which the parse anchors on.\n function* loadWholeGFA(\n name: string,\n source: string | ((signal: AbortSignal) => Promise<string>),\n region?: SubgraphRegion,\n ) {\n const { isLive, signal } = beginLoad()\n self.isLoading = true\n self.error = undefined\n try {\n const text =\n typeof source === 'string' ? source : ((yield source(signal)) as string)\n if (isLive()) {\n yield* parseAndLayout(text, name, region)\n }\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.loadWholeGFA]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n self.finishLoading()\n }\n }\n return isLive()\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n liveLoad++\n liveRequest++\n }\n\n // The graph and everything derived from it, dropped; any load in\n // flight ends too, or it would land its graph afterwards\n function dropGraph() {\n abortLoad()\n self.graph = undefined\n self.graphRegion = undefined\n self.loadedReferencePath = undefined\n self.layoutResult = undefined\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.readsShown = undefined\n self.popStack = []\n self.error = undefined\n self.isLoading = false\n self.loadCanceled = false\n self.statusMessage = ''\n self.clearInteractionState()\n self.clearPerfMetrics()\n }\n\n return {\n // back to the import form\n clearGraph() {\n dropGraph()\n },\n // The user's stop before anything is drawn. The source stays, so a\n // retry can load it again.\n cancelLoad() {\n if (self.canCancelLoad) {\n dropGraph()\n self.loadCanceled = true\n }\n },\n // The user's stop, leaving whatever is drawn under it\n stopLoad() {\n abortLoad()\n self.isLoading = false\n self.statusMessage = ''\n self.loadCanceled = true\n },\n beforeDestroy() {\n abortLoad()\n },\n loadGFA: flow(function* (text: string, name = 'Imported GFA') {\n yield* loadWholeGFA(name, text)\n }),\n loadGFAFromLocation: flow(function* (\n location: FileLocation,\n region?: SubgraphRegion,\n ) {\n self.setStatusMessage('Fetching GFA')\n const live = yield* loadWholeGFA(\n 'uri' in location ? (location.uri.split('/').pop() ?? 'GFA') : 'GFA',\n signal => openLocation(location).readFile({ encoding: 'utf8', signal }),\n region,\n )\n if (region && live && self.graph) {\n yield* loadRepeats(region, () => self.graphRegion === region)\n }\n }),\n // One cut of a region, laid out with the annotations over it. Whether\n // the region may be cut is the caller's call; overlapping cuts are\n // ordered by liveLoad, so the latest one lands.\n cutSubgraph: flow(function* (\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n opts: SubgraphCutOptions = {},\n ) {\n const { isLive, signal } = beginLoad()\n self.isLoading = true\n self.error = undefined\n self.setStatusMessage('Fetching subgraph')\n try {\n const fetchStart = performance.now()\n const gfaText = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetSubgraph',\n { adapterConfig, region, opts, signal },\n )) as string\n if (!isLive()) {\n return\n }\n self.setFetchMs(performance.now() - fetchStart)\n if (!gfaText) {\n throw new Error(\n 'Adapter returned no GFA \u2014 region may be outside indexed data or the adapter does not implement getSubgraph',\n )\n }\n yield* parseAndLayout(\n gfaText,\n locLabel(region),\n region,\n true,\n namesReads(adapterConfig)\n ? graph =>\n getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphReads',\n {\n adapterConfig,\n nodeNames: graph.nodes.map(n => n.name),\n signal,\n },\n )\n : undefined,\n )\n if (!isLive()) {\n return\n }\n // Independent remote reads, each landing as it arrives. A coarse\n // cut reads no bubble index: its nodes are the bubbles, and the\n // index over its window can run to a chromosome's rows.\n self.setStatusMessage('Reading annotations')\n yield Promise.all([\n opts.tier === 'coarse'\n ? undefined\n : flow(loadBubbles)(adapterConfig, region, isLive),\n flow(loadGenes)(region, isLive),\n flow(loadRepeats)(region, isLive),\n ])\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.cutSubgraph]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n self.finishLoading()\n }\n }\n }),\n // Re-read one annotation track alone, for a track change. The graph,\n // its layout and any open bubble stay as they are. Live only while the\n // track it read is still the one chosen, so a slow read cannot land\n // over the pick that followed it.\n reloadRepeats: flow(function* () {\n const region = self.graphRegion\n const trackId = self.repeatTrack?.trackId\n if (region) {\n yield* loadRepeats(\n region,\n () =>\n self.graphRegion === region &&\n self.repeatTrack?.trackId === trackId,\n )\n }\n }),\n // The source track's samples TSV, read once per location, for walk\n // rows to group by. A failed read leaves the rows ungrouped and says so.\n loadWalkRowSampleTable: flow(function* () {\n const location = self.walkRowSamplesTsv\n const key = location ? JSON.stringify(location) : undefined\n if (key === sampleTableKey) {\n return\n }\n sampleTableKey = key\n self.walkRowSampleTable = undefined\n if (!location) {\n return\n }\n try {\n const text = (yield openLocation(location).readFile('utf8')) as string\n if (isAlive(self) && key === sampleTableKey) {\n self.walkRowSampleTable = parseSamplesTsv(text)\n }\n } catch (e) {\n if (isAlive(self) && key === sampleTableKey) {\n getSession(self).notify(\n `Walk rows cannot be grouped: the samples table did not load (${String(e)})`,\n 'warning',\n )\n }\n }\n }),\n // The walk rows' genes, each row's from its haplotype's assembly. A\n // row's genes are its own contig's, so they take the row's name for\n // their contig, whatever the track calls it.\n loadWalkGenes: flow(function* () {\n const reads = self.walkGeneReads?.reads ?? []\n const key = JSON.stringify(reads)\n const graph = self.graph\n const fetched = new Map<string, GeneModel[]>()\n yield Promise.all(\n reads.map(({ row, trackId, region }) =>\n flow(function* () {\n const cacheKey = `${trackId} ${region.refName}:${region.start}-${region.end}`\n let genes = walkGeneCache.get(cacheKey)\n if (!genes) {\n const features = yield* trackFeatures(\n trackId,\n region,\n 'haplotype genes',\n )\n if (!features) {\n return\n }\n genes = geneModelsFrom(features).map(g => ({\n ...g,\n refName: region.refName,\n }))\n walkGeneCache.set(cacheKey, genes)\n }\n fetched.set(row, genes)\n })(),\n ),\n )\n if (\n isAlive(self) &&\n self.graph === graph &&\n JSON.stringify(self.walkGeneReads?.reads ?? []) === key\n ) {\n self.walkGeneFeatures = reads.length ? fetched : undefined\n }\n }),\n reloadGenes: flow(function* () {\n walkGeneCache.clear()\n const region = self.graphRegion\n const trackId = self.geneTrack?.trackId\n if (region) {\n yield* loadGenes(\n region,\n () =>\n self.graphRegion === region && self.geneTrack?.trackId === trackId,\n )\n }\n }),\n // Open one bubble: the graph becomes the segments the bubble row names,\n // drawn in the layout the reader is in. The graph it came from stays\n // behind it, one click away, and the popped graph gets its own derived\n // bubbles, so a superbubble opens progressively.\n popBubble: flow(function* (bubble: MinigraphBubble) {\n const graph = self.graph\n if (!graph) {\n return\n }\n const sub = bubbleSubgraph(graph, bubbleSegmentIds(bubble))\n if (sub.nodes.length === 0) {\n getSession(self).notify(\n 'None of the segments of this bubble are in the cut; widen the graph context to open it',\n 'info',\n )\n return\n }\n const { isLive } = beginLoad()\n self.popStack = [\n ...self.popStack,\n {\n graph,\n layoutMode: self.chosenLayoutMode,\n label: graph.name,\n indexBubbles: self.indexBubbles,\n },\n ]\n self.indexBubbles = undefined\n const label = `${BUBBLE_KIND_NAMES[classifyBubble(bubble, self.repeatArrays).kind]} at ${bubble.refName}:${bubble.start.toLocaleString()}`\n self.graph = { ...sub, name: label }\n self.clearInteractionState()\n self.viewportOwner = 'fit'\n self.isLoading = true\n try {\n if (yield* layoutInto(self.graph)) {\n self.finishLoading()\n }\n } catch (e) {\n if (isLive()) {\n self.error = e\n self.finishLoading()\n }\n }\n }),\n unpopBubble: flow(function* () {\n const from = self.poppedFrom\n if (!from) {\n return\n }\n self.popStack = self.popStack.slice(0, -1)\n self.graph = from.graph\n self.layoutMode = from.layoutMode\n self.indexBubbles = from.indexBubbles\n self.clearInteractionState()\n self.viewportOwner = 'fit'\n self.isLoading = true\n try {\n if (yield* layoutInto(from.graph)) {\n self.finishLoading()\n }\n } catch (e) {\n self.error = e\n self.finishLoading()\n }\n }),\n recomputeLayout: flow(function* () {\n const graph = self.graph\n if (!graph) {\n return\n }\n self.isLoading = true\n self.setStatusMessage('Computing layout')\n\n try {\n // A superseded request leaves the spinner to the request that\n // replaced it: clearing it here reports \"done\" while the layout the\n // user actually asked for is still being computed, which is the\n // common case when a cheap choice follows an expensive one.\n if (yield* layoutInto(graph)) {\n self.finishLoading()\n }\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n self.finishLoading()\n }\n }),\n }\n})\n", "import { FACET_PAD_PX } from '@jbrowse/bandage-core/facetGrid'\nimport { segmentAt } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { anchorFromPaths } from '@jbrowse/bandage-core/pathAnchoring'\nimport {\n FIT_PADDING,\n clampZoom,\n fittedTranslateY,\n} from '@jbrowse/bandage-core/pipeline'\nimport { nodeReferenceSpan } from '@jbrowse/bandage-core/referenceSpan'\nimport { zoomAbout } from '@jbrowse/bandage-core/viewport'\nimport { getSession, isSessionModelWithWidgets } from '@jbrowse/core/util'\nimport { isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { withFitViews } from './fitViews'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\n\nimport type { SampleRow, WalkRowGroupBy } from '../walkRowGroups'\nimport type { BubbleSpread } from '@jbrowse/bandage-core/bubbleSpreads'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { NodeWidth } from '@jbrowse/bandage-core/nodeWidths'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withFitViews\n .actions(self => ({\n setError(error: unknown) {\n self.error = error\n self.isLoading = false\n self.statusMessage = ''\n },\n finishLoading() {\n self.isLoading = false\n self.statusMessage = ''\n },\n setStatusMessage(message: string) {\n self.statusMessage = message\n },\n setFetchMs(ms: number) {\n self.lastFetchMs = ms\n },\n setLayoutMs(ms: number) {\n self.lastLayoutMs = ms\n },\n setGeometryMetrics(\n ms: number,\n strokeCount: number,\n built: { scale: number; bounds: Bounds },\n ) {\n self.lastGeometryMs = ms\n self.lastGeometryStrokeCount = strokeCount\n self.builtViewport = { ...built, viewportDirty: self.viewportDirty }\n self.geometryVersion++\n },\n markPainted() {\n self.paintedViewport = self.builtViewport\n },\n setLayoutQuality(quality: number) {\n self.layoutQuality = quality\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.layoutMode = mode\n },\n // Re-anchor in place rather than re-parsing: the coordinate walk is\n // already recorded on the graph, and only which path counts as rank 0\n // changes. The caller recomputes the layout, the same way it does after\n // setLayoutMode. An rGFA is left alone \u2014 its coordinates are not derived.\n setReferencePath(name: string) {\n self.referencePath = name\n const graph = self.graph\n if (graph?.anchoredBy === 'paths') {\n const reanchored = anchorFromPaths(graph, name)\n forceLayouts.inherit(graph, reanchored)\n self.graph = reanchored\n }\n },\n setDrawPaths(draw: boolean) {\n self.drawPaths = draw\n },\n setShowPerf(show: boolean) {\n self.showPerf = show\n },\n setColorScheme(scheme: ColorScheme) {\n self.colorScheme = scheme\n },\n setBubbleSpread(spread: BubbleSpread) {\n self.bubbleSpread = spread\n },\n setNodeWidth(width: NodeWidth) {\n self.nodeWidth = width\n },\n setShowBubbles(show: boolean) {\n self.showBubbles = show\n },\n setShowDeletionEdges(show: boolean) {\n self.showDeletionEdges = show\n },\n setShowGenes(show: boolean) {\n self.showGenes = show\n },\n setShowReferenceStrip(show: boolean) {\n self.showReferenceStrip = show\n },\n setTubeMapFold(bp: number) {\n self.tubeMapFold = bp\n },\n setGeneTrackId(trackId: string) {\n self.geneTrackId = trackId\n },\n setRepeatTrackId(trackId: string) {\n self.repeatTrackId = trackId\n },\n setRepeatKey(key: string) {\n self.repeatKey = key\n },\n setWalkLayers(layers: WalkLayer[]) {\n self.walkLayers = layers\n },\n // Lift the walks named, in that order, keeping the colour any of them\n // already had\n liftWalks(names: string[]) {\n const had = new Map(self.walkLayers.map(l => [l.walk, l]))\n self.walkLayers = names.map(walk => had.get(walk) ?? { walk })\n },\n // The field the panels split on; a change of field drops the order\n // written for the old one and keeps the column count\n setFacet(field: FacetSetting['field']) {\n if (field !== self.facet.field) {\n self.facet.domain = []\n }\n self.facet.field = field\n },\n setFacetColumns(columns: number | undefined) {\n self.facet.columns = columns\n },\n toggleWalk(walk: string) {\n const layers = self.walkLayers\n self.walkLayers = layers.some(l => l.walk === walk)\n ? layers.filter(l => l.walk !== walk)\n : [...layers, { walk }]\n },\n setWalkColor(walk: string, color: Partial<WalkEncoding>) {\n self.walkLayers = self.walkLayers.map(l =>\n l.walk === walk ? { ...l, color: { ...l.color, ...color } } : l,\n )\n },\n\n // Undefined restores the built-in ceiling. Nothing recomputes: the pane\n // reads canvasHeight and the drawing is placed by zoomToFit, which the\n // caller runs if it wants the drawing refitted into the new pane.\n setPaneHeight(px: number | undefined) {\n self.paneHeight = px\n },\n setWalkRowSamples(samples: string[] | undefined) {\n self.walkRowSamples = samples\n },\n setWalkRowGroupBy(groupBy: WalkRowGroupBy | undefined) {\n self.walkRowGroupBy = groupBy\n },\n setWalkRowSampleTable(table: SampleRow[] | undefined) {\n self.walkRowSampleTable = table\n },\n // Pair with a linear view for the hover sync, without ever repointing an\n // existing pairing: a graph launched *from* an LGV is already paired with\n // it, and stealing that would break the sync the user came in on. So a\n // launch out of the graph only claims the slot when it is empty.\n //\n // A slot naming a view that has been closed is empty too. Held, the view\n // the graph opened next never got its hover, since a highlight is drawn\n // only in the paired view.\n pairWithLinearView(viewId: string) {\n const paired = self.connectedViewId\n const stillOpen =\n paired !== undefined &&\n withRows([...getSession(self).views]).some(\n view => (view as { id?: unknown }).id === paired,\n )\n if (!stillOpen) {\n self.connectedViewId = viewId\n }\n },\n setHoveredNode(nodeId: string | null) {\n self.hoveredNode = nodeId\n },\n setHoveredRowWalks(walks: string[]) {\n if (walks.join('\\n') !== self.hoveredRowWalks.join('\\n')) {\n self.hoveredRowWalks = walks\n }\n },\n setHoveredWalkRow(name: string | null) {\n self.hoveredWalkRow = name\n },\n setHoveredBubble(bubble: MinigraphBubble | null) {\n self.hoveredBubble = bubble\n },\n setPointerInPane(inside: boolean) {\n self.pointerInPane = inside\n },\n setWalkStrip(show: boolean) {\n self.walkStrip = show\n self.stripHover = null\n },\n // The pointer over the strip: the node under it becomes the hovered\n // node, so the drawing, the tooltip and a linked linear view follow\n setStripHover(hover: { row: string; offset: number } | null) {\n self.stripHover = hover\n const bars = self.walkStripRows\n const frame = self.walkStripFrame\n const row =\n hover && bars\n ? [bars.reference, ...bars.rows].find(r => r.name === hover.row)\n : undefined\n const node =\n row && frame && self.graph\n ? segmentAt(self.graph, row, hover!.offset, frame.scaleX)\n : undefined\n self.hoveredNode = node ?? null\n },\n setLegendSize(size: { width: number; height: number }) {\n self.legendSize = size\n },\n setHoveredEdge(edgeIdx: number | null) {\n self.hoveredEdge = edgeIdx\n },\n setSelectedNode(nodeId: string | null) {\n self.selectedNode = nodeId\n },\n setDraggingNode(nodeId: string | null) {\n self.draggingNode = nodeId\n },\n setPanning(panning: boolean) {\n self.isPanning = panning\n },\n stopDragging() {\n self.draggingNode = null\n self.isPanning = false\n },\n // Everything that names a part of the current graph. Reset when the graph\n // is replaced, and by clearGraph.\n clearInteractionState() {\n self.hoveredNode = null\n self.hoveredWalkRow = null\n self.hoveredBubble = null\n self.hoveredEdge = null\n self.selectedNode = null\n self.draggingNode = null\n self.isPanning = false\n },\n showNodeDetails(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n const nodeById = self.nodeById\n const neighbors = self.nodeNeighbors\n if (node && nodeById && neighbors) {\n const session = getSession(self)\n const region = self.graphRegion\n // refName/start/end are what makes the widget show a location rather\n // than a bare id, and they are the same span the linear view\n // highlights on hover.\n const span = region\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n if (isSessionModelWithWidgets(session)) {\n session.showWidget(\n session.addWidget('BaseFeatureWidget', 'baseFeature', {\n featureData: {\n id: node.id,\n name: node.name,\n length: node.length,\n depth: node.depth,\n rank: node.stable?.rank,\n stableName: node.stable?.refName,\n // The assembly that contributed this segment, split off the\n // stable name. On an HPRC graph this is the only thing that\n // says which of 400-odd haplotypes an allele came from.\n contributingAssembly: nodeOwnLocation(node)?.sample,\n // and the haplotype, where the graph's names state one:\n // the assembly to load to open this node on its own\n // coordinates\n contributingHaplotype: nodeOwnLocation(node)?.haplotype,\n // Every haplotype whose path visits it, which only a path\n // GFA records. Absent on an rGFA, where\n // `contributingAssembly` is the first-seen assembly alone.\n sampleCount: node.samples?.length,\n samples: node.samples,\n ...(region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n start: span.start,\n end: span.end,\n }\n : {}),\n },\n }),\n )\n }\n }\n },\n\n // A gesture on a hosted graph moves the linear view, and the frame\n // clock brings x back here; y stays the pane's own.\n setTransform(s: number, tx: number, ty: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.horizontalScroll(self.translateX - tx)\n } else {\n self.viewportOwner = 'user'\n self.scale = clampZoom(s)\n self.translateX = tx\n }\n self.translateY = ty\n },\n zoom(factor: number, centerX: number, centerY: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.zoomTo(host.bpPerPx / factor, centerX)\n return\n }\n self.viewportOwner = 'user'\n const t = zoomAbout(self, factor, centerX, centerY, self.pixelRows)\n self.scale = t.scale\n self.translateX = t.translateX\n self.translateY = t.translateY\n },\n setViewportDirty() {\n self.viewportRebuildPending = false\n self.viewportDirty++\n },\n // The positions themselves moved, as opposed to the window onto them.\n setPositionsDirty() {\n self.positionsVersion++\n },\n zoomToFit() {\n // A host owns x, so a fit while hosted places the rows only.\n if (self.viewportOwner === 'host') {\n const bounds = self.layoutBounds\n const faceted = self.facetGrid !== undefined\n const pad = faceted ? FACET_PAD_PX : FIT_PADDING\n const padTop = faceted ? FACET_PAD_PX : self.fitPadTop\n const usableHeight = self.viewBox.height - padTop - pad\n if (bounds && usableHeight > 0) {\n self.translateY = fittedTranslateY(\n bounds,\n usableHeight,\n self.scaleY,\n padTop,\n )\n }\n return\n }\n // Nothing to fit into before the canvas is measured. The fit autorun\n // runs again once width lands, so skipping beats persisting a negative\n // scale into the session snapshot.\n const fit = self.fittedTransform\n if (fit) {\n self.scale = fit.scale\n self.translateX = fit.translateX\n self.translateY = fit.translateY\n }\n },\n clearPerfMetrics() {\n self.lastFetchMs = undefined\n self.lastLayoutMs = undefined\n self.lastGeometryMs = undefined\n self.lastGeometryStrokeCount = undefined\n self.builtViewport = undefined\n },\n }))\n .actions(self => ({\n // The frame clock. Unclamped, since clampZoom's floor is there to keep a\n // scale finite and 1 / bpPerPx already is; clamped, a whole-chromosome\n // window would stop lining up.\n hostTransform(scale: number, translateX: number) {\n const engaging = self.viewportOwner !== 'host'\n if (engaging) {\n self.viewportOwner = 'host'\n }\n self.scale = scale\n self.translateX = translateX\n if (engaging) {\n self.zoomToFit()\n }\n },\n // Faceting changes the box the drawing is fitted into, so a drawing the\n // user placed is fitted again; a host keeps its x\n refitView() {\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n self.zoomToFit()\n },\n // A drawing still on the reference stays where the host left it; one\n // whose x no longer means bp is refit.\n releaseHost() {\n if (self.viewportOwner === 'host') {\n if (self.xIsReferenceBp) {\n self.viewportOwner = 'user'\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n }\n },\n }))\n .actions(self => {\n // Pan/zoom can wait: the geometry on screen is still correct while the\n // gesture runs (the viewport bounds carry 20% overscan), so rebuilding is\n // deferred until the user settles.\n function scheduleViewportDirty() {\n clearTimeout(self.viewportDirtyTimer)\n self.viewportRebuildPending = true\n self.viewportDirtyTimer = setTimeout(() => {\n if (isAlive(self)) {\n self.setViewportDirty()\n }\n }, VIEWPORT_DEBOUNCE_MS)\n }\n\n // A node drag cannot wait \u2014 the node only moves on screen when its\n // geometry is rebuilt \u2014 but a bump costs a full geometry rebuild plus\n // invalidation of both hit-detection indexes, and mousemove fires in\n // bursts well above the frame rate. Coalescing to the next frame keeps the\n // drag live while bounding that work to once per frame instead of once\n // per event.\n function requestPositionsDirtyFrame() {\n cancelAnimationFrame(self.positionsDirtyFrame)\n self.positionsDirtyFrame = requestAnimationFrame(() => {\n if (isAlive(self)) {\n self.setPositionsDirty()\n }\n })\n }\n\n return {\n // Moves the position objects IN PLACE, which is the one thing\n // jbrowse-components' upload invariant says not to do (\"per-region\n // upload values must be freshly constructed, never mutated \u2014 backends\n // diff by reference identity\"), so it is worth saying why this is not\n // that case and what it costs instead.\n //\n // Nothing here diffs by identity: the geometry is rebuilt wholesale and\n // handed over as one batch, so `nodePositions` identity is not a\n // protocol between the model and the backend the way a per-region map\n // is. What identity DOES drive is the fit: the zoom-to-fit autorun and\n // `layoutBounds` \u2014 and so `canvasHeight` \u2014 key off `layoutResult`, and\n // they mean \"a new LAYOUT arrived\", not \"a node moved\". Publishing a\n // fresh positions record per frame of a drag would refit the drawing\n // and resize the pane under the cursor, sixty times a second.\n //\n // So the change is announced by `positionsVersion` instead, and every\n // cache that would otherwise trust identity takes it as a key. The cost\n // of that trade is that the version is a thing to remember: a caller\n // that mutates here and does not bump it gets stale curves, stale hit\n // boxes and stale labels, silently. Everything downstream of it is\n // reached from this one action.\n moveNode(nodeId: string, dx: number, dy: number) {\n const positions = self.layoutResult?.nodePositions\n if (positions?.[nodeId]) {\n for (const seg of positions[nodeId]) {\n seg.x += dx\n seg.y += dy\n }\n requestPositionsDirtyFrame()\n }\n },\n scheduleViewportDirty,\n }\n })\n", "// src/renderer/geometryInputs.ts\nfunction layoutGeometryInputs(layout, drawing, o = {}) {\n return {\n nodePositions: o.drawsRows ? {} : layout.nodePositions,\n deletions: drawing.bypassed,\n deletionRoutes: layout.deletionRoutes,\n stranded: layout.stranded,\n hiddenEdges: drawing.hidden\n };\n}\n\nexport {\n layoutGeometryInputs\n};\n", "// src/renderer/svgCanvas.ts\nvar n = (v) => +v.toFixed(1);\nfunction paint(css) {\n const m = /^rgba?\\(([^,]+),([^,]+),([^,)]+)(?:,([^)]+))?\\)$/.exec(\n css.replaceAll(\" \", \"\")\n );\n if (!m) {\n return { color: css, opacity: 1 };\n }\n const opacity = m[4] === void 0 ? 1 : Number(m[4]);\n return { color: `rgb(${m[1]},${m[2]},${m[3]})`, opacity };\n}\nfunction paintAttrs(kind, css) {\n const { color, opacity } = paint(css);\n return `${kind}=\"${color}\"${opacity < 1 ? ` ${kind}-opacity=\"${n(opacity)}\"` : \"\"}`;\n}\nvar DOT_PX = 0.5;\nvar DOT_CELL_PX = 0.25;\nfunction svgCanvas(width, height) {\n const out = [];\n let subpaths = [];\n const start = (x, y) => {\n const s = { d: `M${n(x)} ${n(y)}`, segments: 0, x0: x, x1: x, y0: y, y1: y };\n subpaths.push(s);\n return s;\n };\n const reach = (points) => {\n const s = subpaths.at(-1) ?? start(points[0], points[1]);\n for (let i = 0; i < points.length; i += 2) {\n s.x0 = Math.min(s.x0, points[i]);\n s.x1 = Math.max(s.x1, points[i]);\n s.y0 = Math.min(s.y0, points[i + 1]);\n s.y1 = Math.max(s.y1, points[i + 1]);\n }\n s.segments++;\n return s;\n };\n const pathData = (dots) => {\n const seen = /* @__PURE__ */ new Set();\n return subpaths.map((s) => {\n if (!dots || s.x1 - s.x0 >= DOT_PX || s.y1 - s.y0 >= DOT_PX) {\n return s.d;\n }\n const x = (s.x0 + s.x1) / 2;\n const y = (s.y0 + s.y1) / 2;\n const cell = `${Math.round(x / DOT_CELL_PX)} ${Math.round(y / DOT_CELL_PX)}`;\n if (s.segments === 0 || seen.has(cell)) {\n return \"\";\n }\n seen.add(cell);\n return `M${n(x)} ${n(y)}h0`;\n }).join(\"\");\n };\n const ctx = {\n canvas: void 0,\n fillStyle: \"#000\",\n strokeStyle: \"#000\",\n lineWidth: 1,\n lineCap: \"butt\",\n lineJoin: \"miter\",\n beginPath() {\n subpaths = [];\n },\n moveTo(x, y) {\n start(x, y);\n },\n lineTo(x, y) {\n reach([x, y]).d += `L${n(x)} ${n(y)}`;\n },\n bezierCurveTo(cx0, cy0, cx1, cy1, x, y) {\n reach([cx0, cy0, cx1, cy1, x, y]).d += `C${n(cx0)} ${n(cy0)} ${n(cx1)} ${n(cy1)} ${n(x)} ${n(y)}`;\n },\n closePath() {\n const s = subpaths.at(-1);\n if (s) {\n s.d += \"Z\";\n }\n },\n stroke() {\n const d = pathData(ctx.lineCap !== \"butt\");\n if (d) {\n out.push(\n `<path d=\"${d}\" fill=\"none\" ${paintAttrs(\"stroke\", ctx.strokeStyle)} stroke-width=\"${n(ctx.lineWidth)}\" stroke-linecap=\"${ctx.lineCap}\" stroke-linejoin=\"${ctx.lineJoin}\"/>`\n );\n }\n },\n fill() {\n const d = pathData(false);\n if (d) {\n out.push(`<path d=\"${d}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`);\n }\n },\n fillRect(x, y, w, h) {\n out.push(\n `<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(w)}\" height=\"${n(h)}\" ${paintAttrs(\"fill\", ctx.fillStyle)}/>`\n );\n }\n };\n const canvas = {\n width,\n height,\n style: {},\n getContext: () => ctx\n };\n ctx.canvas = canvas;\n return {\n canvas,\n // the drawing so far, as SVG elements in canvas pixels\n markup: () => out.join(\"\")\n };\n}\n\nexport {\n svgCanvas\n};\n", "import {\n polylineSlice\n} from \"./chunk-TAMCZHLW.js\";\nimport {\n svgPath\n} from \"./chunk-2CVHXFK7.js\";\nimport {\n firstNodeAtOrAfter,\n isAnchored\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/genes/genePins.ts\nfunction genePins(graph, genes, positions) {\n const byRefName = /* @__PURE__ */ new Map();\n for (const node of graph.nodes) {\n if (isAnchored(node)) {\n const { refName } = node.stable;\n if (positions[node.id]?.length) {\n const entry = byRefName.get(refName) ?? byRefName.set(refName, { nodes: [], reach: 0 }).get(refName);\n entry.nodes.push(node);\n entry.reach = Math.max(entry.reach, node.length);\n }\n }\n }\n for (const { nodes } of byRefName.values()) {\n nodes.sort((a, b) => a.stable.start - b.stable.start);\n }\n const pins = [];\n for (const gene of genes) {\n const onRefName = byRefName.get(gene.refName);\n if (!onRefName) {\n continue;\n }\n const parts = [];\n const exonsByNode = [];\n const nodeIds = /* @__PURE__ */ new Set();\n let at;\n let atDistance = Infinity;\n let covered = 0;\n const mid = (gene.start + gene.end) / 2;\n const { nodes, reach } = onRefName;\n for (let i = firstNodeAtOrAfter(nodes, gene.start - reach); i < nodes.length && nodes[i].stable.start < gene.end; i++) {\n const node = nodes[i];\n const nodeStart = node.stable.start;\n const nodeEnd = nodeStart + node.length;\n if (nodeEnd <= gene.start) {\n continue;\n }\n const line = positions[node.id];\n nodeIds.add(node.id);\n covered += Math.min(nodeEnd, gene.end) - Math.max(nodeStart, gene.start);\n const nodeParts = [];\n for (const exon of gene.exons) {\n const a = Math.max(exon.start, nodeStart);\n const b = Math.min(exon.end, nodeEnd);\n if (b <= a) {\n continue;\n }\n const stretch = polylineSlice(\n line,\n (a - nodeStart) / node.length,\n (b - nodeStart) / node.length\n );\n if (stretch.length === 1) {\n stretch.push({ ...stretch[0] });\n }\n nodeParts.push(svgPath(stretch));\n }\n if (nodeParts.length > 0) {\n parts.push(...nodeParts);\n exonsByNode.push({ nodeId: node.id, d: nodeParts.join(\"\") });\n }\n const pinBp = Math.min(Math.max(mid, nodeStart), nodeEnd);\n const distance = Math.abs(pinBp - mid);\n if (distance < atDistance) {\n atDistance = distance;\n const [p] = polylineSlice(\n line,\n (pinBp - nodeStart) / node.length,\n (pinBp - nodeStart) / node.length\n );\n at = p;\n }\n }\n if (at) {\n pins.push({\n gene,\n exons: parts.join(\"\"),\n exonsByNode,\n nodeIds,\n at,\n covered: covered / (gene.end - gene.start)\n });\n }\n }\n return pins;\n}\n\nexport {\n genePins\n};\n", "import {\n encodedColor,\n resolveEncoding\n} from \"./chunk-ZNMHIPUZ.js\";\nimport {\n pathOrigin\n} from \"./chunk-ST2IBUAN.js\";\nimport {\n panSNContig\n} from \"./chunk-BPLIXMH7.js\";\n\n// src/walkHighlight.ts\nvar isReference = (graph, name) => !!graph.referencePath && pathOrigin(name).name === graph.referencePath;\nfunction piecesOf(graph, name) {\n return (graph.paths ?? []).filter((p) => p.name === name).sort((a, b) => (a.start ?? 0) - (b.start ?? 0));\n}\nfunction walkHighlight(graph, name) {\n const pieces = piecesOf(graph, name);\n const first = pieces[0];\n if (!first) {\n return void 0;\n }\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const edgeAt = /* @__PURE__ */ new Map();\n graph.edges.forEach((e, i) => {\n edgeAt.set(`${e.from}>${e.to}`, i);\n });\n const lengthOf = (id) => byId.get(id)?.length ?? 0;\n const bpOf = (path) => path.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0);\n const bp = pieces.reduce((sum, piece) => sum + bpOf(piece), 0);\n const range = first.start === void 0 ? void 0 : {\n contig: first.contig ?? panSNContig(pathOrigin(name).name),\n start: first.start,\n end: Math.max(...pieces.map((p) => (p.start ?? 0) + bpOf(p)))\n };\n const span = range ? range.end - range.start : bp;\n const nodeIds = /* @__PURE__ */ new Set();\n const edgeIndexes = /* @__PURE__ */ new Set();\n const progress = /* @__PURE__ */ new Map();\n let before = 0;\n for (const piece of pieces) {\n if (range) {\n before = Math.max(before, (piece.start ?? 0) - range.start);\n }\n piece.nodeIds.forEach((id, i) => {\n nodeIds.add(id);\n if (i > 0) {\n const a = piece.nodeIds[i - 1];\n const index = edgeAt.get(`${a}>${id}`) ?? edgeAt.get(`${id}>${a}`);\n if (index !== void 0) {\n edgeIndexes.add(index);\n }\n }\n const length = lengthOf(id);\n if (!progress.has(id)) {\n progress.set(id, span > 0 ? (before + length / 2) / span : 0);\n }\n before += length;\n });\n }\n const reference = isReference(graph, name);\n const referencePieces = reference ? [] : (graph.paths ?? []).filter((p) => isReference(graph, p.name));\n return {\n name,\n reference,\n range,\n nodeIds,\n edgeIndexes,\n progress,\n steps: pieces.reduce((sum, piece) => sum + piece.nodeIds.length, 0),\n bp,\n referenceBp: referencePieces.length > 0 ? referencePieces.reduce((sum, piece) => sum + bpOf(piece), 0) : void 0\n };\n}\nfunction laneColors(graph, walk, encoding, ramp) {\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const colors = /* @__PURE__ */ new Map();\n for (const [id, progress] of walk.progress) {\n const node = byId.get(id);\n const mid = ramp?.midpoints.get(id);\n const t = encoding.field === \"progress\" ? progress : ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;\n colors.set(id, encodedColor(encoding, t));\n }\n return colors;\n}\nfunction reversedNodes(graph, walk) {\n const reversed = /* @__PURE__ */ new Set();\n let bp = 0;\n const referencePath = graph.referencePath;\n if (!referencePath || walk.reference) {\n return { reversed, bp };\n }\n const walkPath = pathOrigin(walk.name).name;\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n for (const id of walk.progress.keys()) {\n const node = byId.get(id);\n const visits = node ? graph.pathVisits?.get(node.name) : void 0;\n const own = visits?.find((v) => v.path === walkPath)?.strand;\n const theirs = visits?.find((v) => v.path === referencePath)?.strand;\n if (own && theirs && own !== theirs) {\n reversed.add(id);\n bp += node.length;\n }\n }\n return { reversed, bp };\n}\nfunction walkLift(graph, layers, ramp) {\n const seen = /* @__PURE__ */ new Set();\n const lifted = layers.filter((layer) => !seen.has(layer.walk) && seen.add(layer.walk)).flatMap((layer) => {\n const walk = walkHighlight(graph, layer.walk);\n return walk ? [{ walk, layer }] : [];\n }).sort((a, b) => Number(b.walk.reference) - Number(a.walk.reference));\n if (lifted.length === 0) {\n return void 0;\n }\n let picked = 0;\n const walks = lifted.map(({ walk, layer }) => {\n const encoding = resolveEncoding(\n layer,\n walk.reference,\n walk.reference ? 0 : picked++,\n lifted.length === 1\n );\n const { reversed, bp } = reversedNodes(graph, walk);\n return {\n ...walk,\n encoding,\n colors: laneColors(graph, walk, encoding, ramp),\n reversed,\n reversedBp: bp\n };\n });\n return liftOf(walks, ramp);\n}\nvar FACET_COLOR = { field: \"progress\", scheme: \"red\" };\nfunction facetLifts(graph, lift, layers, ramp) {\n return lift.walks.map((walk) => {\n const stated = layers.find((l) => l.walk === walk.name)?.color;\n const encoding = resolveEncoding(\n { walk: walk.name, color: { ...FACET_COLOR, ...stated } },\n walk.reference,\n 0\n );\n return liftOf(\n [\n {\n ...walk,\n encoding,\n colors: laneColors(graph, walk, encoding, ramp)\n }\n ],\n ramp\n );\n });\n}\nfunction liftOf(walks, ramp) {\n return {\n walks,\n referenceDomain: ramp ? { start: ramp.start, end: ramp.start + ramp.span } : void 0,\n nodeIds: new Set(walks.flatMap((w) => [...w.nodeIds])),\n edgeIndexes: new Set(walks.flatMap((w) => [...w.edgeIndexes])),\n names: new Set(walks.map((w) => w.name))\n };\n}\n\nexport {\n walkHighlight,\n walkLift,\n facetLifts\n};\n", "// src/version.ts\nvar version = \"8.0.0\";\n\nexport {\n version\n};\n", "import {\n layoutGeometryInputs\n} from \"./chunk-LOCJN3BZ.js\";\nimport {\n svgCanvas\n} from \"./chunk-47DYCZOK.js\";\nimport {\n stripGeneGaps,\n walkStripFrame,\n walkStripLabelsTree\n} from \"./chunk-ZYHSUNQO.js\";\nimport {\n walkRowsKey,\n walkRowsKeyTree,\n walkRowsTree\n} from \"./chunk-7G7TFATC.js\";\nimport {\n Canvas2DRenderer\n} from \"./chunk-CH3DLBUT.js\";\nimport {\n EXON_COLOR,\n exonOutlineTree,\n exonStretches\n} from \"./chunk-3S3YVOJ7.js\";\nimport {\n genePins\n} from \"./chunk-BUBZ32IC.js\";\nimport {\n facetLifts,\n walkLift\n} from \"./chunk-3LXG54PN.js\";\nimport {\n encodingStops\n} from \"./chunk-ZNMHIPUZ.js\";\nimport {\n rangeText,\n walkKey\n} from \"./chunk-2LQ5BWT7.js\";\nimport {\n buildGeometry,\n computeReferenceRamp\n} from \"./chunk-RCWYY6XA.js\";\nimport {\n version\n} from \"./chunk-XMNHWMGM.js\";\nimport {\n axisScaleOf\n} from \"./chunk-4UBWXZVX.js\";\nimport {\n walkRowLabels,\n walkRowsExtent\n} from \"./chunk-MP7LXLWV.js\";\nimport {\n nodeInk\n} from \"./chunk-PBENCR5L.js\";\nimport {\n pathLegend,\n walkLabelsOf\n} from \"./chunk-7GBL7SJY.js\";\nimport {\n referenceLabel\n} from \"./chunk-RAKOB6IV.js\";\nimport {\n geneLabelCandidates\n} from \"./chunk-GJMC3PGM.js\";\nimport {\n nodesUnderBox\n} from \"./chunk-FP4H7SFT.js\";\nimport {\n LABEL_CHAR_PX,\n LABEL_PAD,\n LABEL_PX,\n occupancy,\n placeLabels\n} from \"./chunk-AB35TJST.js\";\nimport {\n resolveColorScheme\n} from \"./chunk-JKJWSY4V.js\";\nimport {\n serializeEl\n} from \"./chunk-NNODIW4U.js\";\nimport {\n FACET_GAP_PX,\n FACET_PAD_PX,\n FACET_TITLE_PX,\n facetCells,\n facetGrid,\n facetSettingOf\n} from \"./chunk-XV4P5KEQ.js\";\nimport {\n FIT_PADDING,\n drawingBounds,\n fitTransform\n} from \"./chunk-WZATPZNH.js\";\nimport {\n deletionDrawing,\n deletionEdges\n} from \"./chunk-N6FECAXP.js\";\n\n// src/figure.ts\nvar FONT = 'font-family=\"Helvetica, Arial, sans-serif\" font-size=\"11\"';\nvar BAR_PX = 48;\nvar SWATCH_PX = 18;\nvar KEY_GAP_PX = 16;\nvar STRIP_KEY_PX = 22;\nvar FADED = \"rgb(160,160,160)\";\nvar GENE_INK = \"#1c1c22\";\nfunction esc(s) {\n return s.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\");\n}\nfunction keySvg(id, x, y, stops, label, after, under, opacity = 1) {\n const bar = stops.length > 1 ? BAR_PX : SWATCH_PX;\n const fill = stops.length > 1 ? `fill=\"url(#${id})\"` : `fill=\"${stops[0].color}\"${opacity < 1 ? ` fill-opacity=\"${opacity}\"` : \"\"}`;\n const defs = stops.length > 1 ? `<linearGradient id=\"${id}\">${stops.map((s) => `<stop offset=\"${s.offset}\" stop-color=\"${s.color}\"/>`).join(\"\")}</linearGradient>` : \"\";\n const width = Math.max(\n bar + 5 + (label.length + after.length) * LABEL_CHAR_PX,\n (under?.length ?? 0) * LABEL_CHAR_PX\n );\n return {\n width,\n markup: `${defs}<g transform=\"translate(${x} ${y})\" ${FONT}><rect y=\"5\" width=\"${bar}\" height=\"8\" rx=\"2\" ${fill}/><text x=\"${bar + 5}\" y=\"13\"><tspan font-weight=\"bold\">${esc(label)}</tspan>${esc(after)}</text>${under ? `<text y=\"28\">${esc(under)}</text>` : \"\"}</g>`\n };\n}\nfunction exonKeySvg(x, y) {\n return {\n width: SWATCH_PX + 5 + 4 * LABEL_CHAR_PX,\n markup: `<g transform=\"translate(${x} ${y})\" ${FONT}><rect x=\"1\" y=\"4\" width=\"${SWATCH_PX - 2}\" height=\"10\" rx=\"4\" fill=\"none\" stroke=\"${EXON_COLOR}\" stroke-width=\"2\"/><text x=\"${SWATCH_PX + 5}\" y=\"13\">exon</text></g>`\n };\n}\nfunction walkKeySvg(id, x, y, walk, label, reference) {\n const key = walkKey(walk, reference);\n return keySvg(\n id,\n x,\n y,\n encodingStops(walk.encoding),\n label,\n key.delta + key.outside + key.reversed,\n key.scale\n );\n}\nfunction screenPath(d, t) {\n return d.replaceAll(\n /([ML])(-?[\\d.e-]+),(-?[\\d.e-]+)/g,\n (_, cmd, x, y) => `${cmd}${+(Number(x) * t.scaleX + t.translateX).toFixed(1)},${+(Number(y) * t.scaleY + t.translateY).toFixed(1)}`\n );\n}\nfunction chip(x, y, w, name, note) {\n return `<rect x=\"${x - w / 2}\" y=\"${y - LABEL_PX - LABEL_PAD + 2}\" width=\"${w}\" height=\"${LABEL_PX + LABEL_PAD * 2 - 2}\" rx=\"3\" fill=\"#fff\" fill-opacity=\"0.85\" stroke=\"${EXON_COLOR}\"/><text x=\"${x}\" y=\"${y}\" font-family=\"Helvetica, Arial, sans-serif\" font-size=\"${LABEL_PX}\" fill=\"${GENE_INK}\" text-anchor=\"middle\"><tspan font-style=\"italic\" font-weight=\"600\">${esc(name)}</tspan>${note ? esc(note) : \"\"}</text>`;\n}\nfunction figureSvg(graph, layout, o = {}) {\n const width = o.width ?? 1200;\n const room = o.height ?? 800;\n const region = o.region;\n const rampDomain = o.colorDomain ?? region;\n const rows = o.walkRows;\n const bounds = drawingBounds(layout, {\n region: o.fitToDrawing ? void 0 : region,\n extent: rows && layout.extent ? walkRowsExtent(rows, o.walkRowPitch) : void 0\n });\n const pixelRows = layout.pixelRows ?? false;\n const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));\n const colorScheme = resolveColorScheme(o.colorScheme ?? \"auto\", graph);\n const referenceRamp = colorScheme === \"reference-position\" && !layout.tubeMap ? computeReferenceRamp(graph, rampDomain) : void 0;\n const rampInterval = referenceRamp && {\n start: referenceRamp.start,\n end: referenceRamp.start + referenceRamp.span\n };\n const drawnDeletions = deletionDrawing(\n graph,\n layout.tubeMap ? [] : deletionEdges(graph),\n o.showDeletionEdges\n );\n const layers = o.walks ?? [];\n const walkRamp = layers.some((l) => l.color?.field === \"reference\") ? referenceRamp ?? computeReferenceRamp(graph, rampDomain) : void 0;\n const lift = layers.length > 0 && !layout.tubeMap ? walkLift(graph, layers, walkRamp) : void 0;\n const facet = facetSettingOf(o.facet);\n const panels = facet.field && lift && lift.walks.length > 1 ? facetLifts(graph, lift, layers, walkRamp) : void 0;\n const labels = walkLabelsOf(\n graph.paths?.length ? pathLegend(graph.paths) : []\n );\n const labelOf = (name) => labels.get(name) ?? name;\n const referenceName = o.referenceName ?? referenceLabel(graph, region);\n const reference = lift?.referenceDomain && {\n ...lift.referenceDomain,\n name: referenceName\n };\n const contigThickness = o.contigThickness ?? 6;\n const nodeWidth = o.nodeWidth ?? \"depth\";\n const pins = o.genes?.length && !layout.tubeMap && !rows ? genePins(graph, o.genes, layout.nodePositions) : [];\n const ink = nodeInk(graph, nodeById, contigThickness, nodeWidth);\n let masks = 0;\n function overlays(highlight, t, w, h) {\n const out = [];\n const outlines = exonOutlineTree(\n exonStretches(pins, ink.halfWidthPx, highlight, (d) => screenPath(d, t)),\n { id: `exons${masks++}`, width: w, height: h }\n );\n if (outlines) {\n out.push(serializeEl(outlines));\n }\n const screen = (p) => ({\n x: p.x * t.scaleX + t.translateX,\n y: p.y * t.scaleY + t.translateY\n });\n const frame = { width: w, height: h };\n for (const { item: pin, x, y, w: cw, text } of placeLabels(\n geneLabelCandidates(\n pins,\n screen,\n contigThickness,\n nodesUnderBox(layout.nodePositions, t)\n ),\n frame,\n occupancy(frame)\n )) {\n const pinY = screen(pin.at).y + contigThickness / 2;\n out.push(\n `<line x1=\"${x}\" x2=\"${x}\" y1=\"${y - LABEL_PX - 2}\" y2=\"${pinY}\" stroke=\"${GENE_INK}\" stroke-width=\"0.8\" stroke-opacity=\"0.6\"/>`,\n chip(x, y, cw, pin.gene.name, text.slice(pin.gene.name.length))\n );\n }\n if (rows) {\n out.push(\n serializeEl(\n walkRowsTree(\n rows,\n { ...t, width: w, height: h, ...o.walkRowPitch },\n {\n ramp: rampInterval,\n rowGenes: o.rowGenes\n }\n )\n )\n );\n }\n const rowLabels = walkRowLabels(rows, layout, o.walkRowPitch);\n for (const { label, y } of rowLabels) {\n const sy = y * t.scaleY + t.translateY;\n if (sy >= 0 && sy <= h) {\n out.push(\n `<text x=\"6\" y=\"${sy + 4}\" ${FONT} stroke=\"#fff\" stroke-width=\"3\" paint-order=\"stroke\">${esc(label)}</text>`\n );\n }\n }\n return out.join(\"\");\n }\n function drawing(highlight, w, h) {\n const fit = fitTransform(\n bounds,\n w,\n h,\n pixelRows,\n panels ? {\n padLeft: FACET_PAD_PX,\n padTop: FACET_PAD_PX,\n padRight: FACET_PAD_PX,\n padBottom: FACET_PAD_PX\n } : {}\n );\n if (!fit) {\n return \"\";\n }\n const axis = axisScaleOf(fit.scale, pixelRows);\n const { canvas, markup } = svgCanvas(w, h);\n const renderer = new Canvas2DRenderer(canvas);\n renderer.uploadGeometry(\n buildGeometry({\n ...layoutGeometryInputs(layout, drawnDeletions, {\n drawsRows: !!rows\n }),\n graph,\n nodeById,\n colorScheme,\n contigThickness,\n connectorThickness: o.connectorThickness ?? 2,\n drawPaths: false,\n nodeWidth,\n linearLayout: o.linearLayout,\n highlight,\n axis,\n referenceRamp\n })\n );\n const t = {\n scaleX: axis.scaleX,\n scaleY: axis.scaleY,\n translateX: fit.translateX,\n translateY: fit.translateY\n };\n renderer.updateTransform({ ...t, dpr: 1 });\n renderer.render([1, 1, 1, 1]);\n return markup() + overlays(highlight, t, w, h);\n }\n const parts = [];\n let height;\n if (panels) {\n const place = facetCells(\n panels.map((p) => p.walks[0].name),\n facet.field || \"walk\",\n facet.domain\n );\n const grid = facetGrid({\n count: place.count,\n bounds,\n pixelRows,\n width,\n room,\n columns: place.columns ?? facet.columns\n });\n panels.forEach((panel, i) => {\n const cell = place.cells[i];\n const x = cell % grid.columns * (grid.width + FACET_GAP_PX);\n const y = Math.floor(cell / grid.columns) * (grid.height + FACET_TITLE_PX + FACET_GAP_PX);\n const walk = panel.walks[0];\n parts.push(\n walkKeySvg(`key${i}`, x + 6, y + 2, walk, labelOf(walk.name), reference).markup,\n `<svg x=\"${x}\" y=\"${y + FACET_TITLE_PX}\" width=\"${grid.width}\" height=\"${grid.height}\">${drawing(panel, grid.width, grid.height)}</svg>`\n );\n });\n height = grid.total;\n } else {\n let x = 6;\n const push = (key) => {\n parts.push(key.markup);\n x += key.width + KEY_GAP_PX;\n };\n if (lift) {\n lift.walks.forEach((walk, i) => {\n push(walkKeySvg(`key${i}`, x, 2, walk, labelOf(walk.name), reference));\n });\n push(\n keySvg(\n \"faded\",\n x,\n 2,\n [{ offset: 0, color: FADED }],\n \"\",\n `not on ${lift.walks.length === 1 ? labelOf(lift.walks[0].name) : \"these walks\"}`,\n void 0,\n 0.3\n )\n );\n }\n if (rows) {\n const key = walkRowsKeyTree(\n walkRowsKey(rows, {\n ramp: rampInterval,\n genes: o.rowGenes?.size ? o.rowGeneGaps : void 0\n }),\n x,\n 2,\n \"rows-key\"\n );\n push({ width: key.width, markup: serializeEl(key.tree) });\n } else if (!lift && referenceRamp) {\n push(\n keySvg(\n \"ramp\",\n x,\n 2,\n encodingStops({ field: \"reference\", scheme: \"rainbow\" }),\n referenceName ? `${referenceName} position` : \"Reference position\",\n \"\",\n rangeText(\n referenceName,\n referenceRamp.start,\n referenceRamp.start + referenceRamp.span\n )\n )\n );\n }\n if (pins.some((pin) => pin.exonsByNode.length > 0)) {\n push(exonKeySvg(x, 2));\n }\n const header = parts.length > 0 ? FACET_TITLE_PX : 0;\n const usable = width - 2 * FIT_PADDING;\n const drawn = pixelRows || !(bounds.w > 0) ? bounds.h : bounds.h * usable / bounds.w;\n const h = Math.max(\n 160,\n Math.min(room - header, Math.ceil(drawn + 2 * FIT_PADDING))\n );\n parts.push(\n `<svg y=\"${header}\" width=\"${width}\" height=\"${h}\">${drawing(lift, width, h)}</svg>`\n );\n height = header + h;\n }\n const strip = o.walkStrip;\n if (strip && !rows && !layout.tubeMap) {\n const frame = walkStripFrame(strip.rows, { width });\n const key = walkRowsKeyTree(\n walkRowsKey(strip.rows, {\n ramp: rampInterval,\n genes: stripGeneGaps(frame, strip.rowGenes, strip.rowGeneGaps)\n }),\n 6,\n height + frame.height,\n \"strip-key\"\n );\n parts.push(\n `<line x1=\"0\" x2=\"${width}\" y1=\"${height + 0.5}\" y2=\"${height + 0.5}\" stroke=\"#ddd\"/>`,\n `<svg y=\"${height}\" width=\"${width}\" height=\"${frame.height}\">${serializeEl(\n walkRowsTree(strip.rows, frame, {\n ramp: rampInterval,\n rowGenes: strip.rowGenes,\n idPrefix: \"strip\"\n })\n )}${serializeEl(\n walkStripLabelsTree(\n strip.rows,\n frame,\n new Set(layers.map((l) => l.walk))\n )\n )}</svg>`,\n serializeEl(key.tree)\n );\n height += frame.height + STRIP_KEY_PX;\n }\n const metadata = JSON.stringify({\n generator: `@jbrowse/bandage-core@${version}`,\n ...o.spec === void 0 ? {} : { spec: o.spec }\n });\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\"><metadata>${esc(metadata)}</metadata><rect width=\"${width}\" height=\"${height}\" fill=\"#fff\"/>${parts.join(\"\")}</svg>\n`;\n}\n\nexport {\n figureSvg\n};\n", "import {\n ENGINE_DEFAULTS\n} from \"./chunk-WZATPZNH.js\";\n\n// src/figureSettings.ts\nvar FIGURE_DEFAULTS = {\n ...ENGINE_DEFAULTS,\n colorScheme: \"auto\",\n nodeWidth: \"depth\",\n contigThickness: 6,\n connectorThickness: 2\n};\nfunction figureSpecSettings(s) {\n const defaults = FIGURE_DEFAULTS;\n const out = {};\n for (const [k, v] of Object.entries(s)) {\n if (v !== void 0 && v !== defaults[k]) {\n out[k] = v;\n }\n }\n return out;\n}\n\nexport {\n FIGURE_DEFAULTS,\n figureSpecSettings\n};\n", "// src/tubeMap/warp.ts\nvar MAX_GAP_PX = 24;\nvar isReal = (c) => c.bp1 > c.bp0;\nfunction referenceKnots(columns, bpToScreen) {\n const real = columns.filter(isReal);\n if (real.length === 0) {\n const first = columns[0];\n return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];\n }\n const screen = real.map((c) => ({\n c,\n s0: bpToScreen(c.bp0),\n s1: bpToScreen(c.bp1),\n trimLeft: 0,\n trimRight: 0\n }));\n for (let i = 0; i + 1 < screen.length; i++) {\n const left = screen[i];\n const right = screen[i + 1];\n const demand = Math.min(right.c.x0 - left.c.x1, MAX_GAP_PX);\n const short = demand - (right.s0 - left.s1);\n if (short > 0) {\n const capLeft = (left.s1 - left.s0) / 2;\n const capRight = (right.s1 - right.s0) / 2;\n let fromLeft = Math.min(short / 2, capLeft);\n const fromRight = Math.min(short - fromLeft, capRight);\n fromLeft = Math.min(short - fromRight, capLeft);\n left.trimRight = fromLeft;\n right.trimLeft = fromRight;\n }\n }\n const knots = [];\n for (const { c, s0, s1, trimLeft, trimRight } of screen) {\n knots.push(\n { tx: c.x0, sx: s0 + trimLeft },\n { tx: c.x1, sx: s1 - trimRight }\n );\n }\n return knots;\n}\nfunction warpX(knots, tx) {\n const n = knots.length;\n if (n === 0) {\n return tx;\n }\n const first = knots[0];\n const last = knots[n - 1];\n if (tx <= first.tx) {\n return first.sx + (tx - first.tx);\n }\n if (tx >= last.tx) {\n return last.sx + (tx - last.tx);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = lo + hi >> 1;\n if (knots[mid].tx <= tx) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n const a = knots[lo];\n const b = knots[hi];\n const span = b.tx - a.tx;\n return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;\n}\n\nexport {\n referenceKnots,\n warpX\n};\n", "import {\n referenceKnots,\n warpX\n} from \"./chunk-KQFOCDFY.js\";\n\n// src/tubeMap/frame.ts\nvar MIN_TUBE_Y_SCALE = 0.05;\nvar NODE_BOX_PAD = 9;\nfunction squeeze(drawing, usableHeight) {\n const { minY, maxY } = drawing.layout.bounds;\n const h = maxY - minY;\n return drawing.columns && h > 0 ? Math.max(MIN_TUBE_Y_SCALE, Math.min(1, usableHeight / h)) : 1;\n}\nfunction tubeMapFrame(drawing, view) {\n const { scaleX, translateX, translateY } = view;\n const yScale = view.scaleY * squeeze(drawing, view.usableHeight);\n const y = (ty) => (ty - drawing.yOffset) * yScale + translateY;\n const { columns } = drawing;\n if (columns) {\n const knots = referenceKnots(columns, (bp) => bp * scaleX + translateX);\n return { x: (tx) => warpX(knots, tx), y, yScale };\n }\n return { x: (tx) => tx * scaleX + translateX, y, yScale };\n}\nfunction tubeMapNodeAt(drawing, { x, y }, sx, sy) {\n let hit = null;\n drawing.layout.nodes.forEach((node) => {\n if (node.order >= 0 && x(node.x - NODE_BOX_PAD) <= sx && sx <= x(node.x + node.pixelWidth + NODE_BOX_PAD) && y(node.y - NODE_BOX_PAD) <= sy && sy <= y(node.y + node.contentHeight + NODE_BOX_PAD)) {\n hit = node.name;\n }\n });\n return hit;\n}\n\nexport {\n tubeMapFrame,\n tubeMapNodeAt\n};\n", "import {\n FACET_PAD_PX,\n facetCells,\n facetGrid,\n} from '@jbrowse/bandage-core/facetGrid'\nimport { figureSvg } from '@jbrowse/bandage-core/figure'\nimport { figureSpecSettings } from '@jbrowse/bandage-core/figureSettings'\nimport { rowLabelBox } from '@jbrowse/bandage-core/graphLabels'\nimport {\n LEGEND_INSET_PX,\n layoutLabels,\n} from '@jbrowse/bandage-core/labelLayout'\nimport {\n boxesGenes,\n rowPitch,\n walkRowReadout,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport {\n walkRowLabels,\n walkRowsExtent,\n} from '@jbrowse/bandage-core/layout/walkRowLayout'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n FIT_PADDING,\n drawingBounds,\n fitTransform,\n} from '@jbrowse/bandage-core/pipeline'\nimport { buildGeometry } from '@jbrowse/bandage-core/renderer/GeometryBuilder'\nimport { getDpr } from '@jbrowse/bandage-core/renderer/canvas'\nimport { layoutGeometryInputs } from '@jbrowse/bandage-core/renderer/geometryInputs'\nimport { rulerBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport {\n connectorAt,\n tubeMapConnectors,\n} from '@jbrowse/bandage-core/tubeMap/connectors'\nimport {\n mismatchOnScreen,\n mismatchesLegible,\n} from '@jbrowse/bandage-core/tubeMap/draw'\nimport {\n tubeMapFrame,\n tubeMapNodeAt,\n} from '@jbrowse/bandage-core/tubeMap/frame'\nimport {\n GENE_ROW_PX,\n tubeMapGeneRows,\n} from '@jbrowse/bandage-core/tubeMap/genes'\nimport { padded } from '@jbrowse/bandage-core/viewport'\nimport { walkPosition } from '@jbrowse/bandage-core/walkKey'\nimport {\n expandTabixShorthand,\n readConfObject,\n} from '@jbrowse/core/configuration'\nimport { getSession } from '@jbrowse/core/util'\nimport { untracked } from 'mobx'\n\nimport { hostFrame } from '../host'\nimport { SECTION_HEADER_PX, sectionPlacement } from '../walkRowGroups'\nimport { withHostViews } from './hostViews'\nimport {\n HOVER_BRIGHTEN,\n MAX_CANVAS_HEIGHT,\n MIN_CANVAS_HEIGHT,\n MIN_FIT_TUBE_PX,\n PAPER_DARK,\n PAPER_LIGHT,\n SELECT_BRIGHTEN,\n VIEWPORT_PANES_BUILT,\n dependOn,\n paneViewportOf,\n uriOf,\n} from './paneBase'\n\nimport type { FacetGrid, FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type {\n GeneGaps,\n RowPitch,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\nimport type { LiftedWalk, WalkLift } from '@jbrowse/bandage-core/walkHighlight'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport function walkRowGeneKey(\n pitch: RowPitch | undefined,\n hasGenes: boolean,\n gaps: GeneGaps | undefined,\n): GeneGaps | undefined {\n if (!pitch || !hasGenes) {\n return undefined\n }\n return boxesGenes(pitch.rowPx, pitch.barPx)\n ? gaps\n : { untracked: 0, unread: 0, ...gaps, crowded: true }\n}\n\nexport const withFitViews = withHostViews\n .views(self => ({\n // `paneHeight` replaces the built-in ceiling rather than adding a second\n // clamp under it, and the floor still wins: a pane shorter than\n // MIN_CANVAS_HEIGHT leaves no room to hover a node and read its tooltip,\n // which is the reason that floor exists.\n get paneCeiling(): number {\n return Math.max(MIN_CANVAS_HEIGHT, self.paneHeight ?? MAX_CANVAS_HEIGHT)\n },\n // Walk rows pack to fill the pane, as the strip does, so every walk of a\n // cohort is on screen; rows too thin to letter put their names and\n // readouts on hover\n get walkRowPitch(): RowPitch | undefined {\n const bars = self.walkRowBars\n if (!bars) {\n return undefined\n }\n const room = self.host ? this.canvasHeight : this.paneCeiling\n const headersPx =\n (self.walkRowGroups?.sections.length ?? 0) * SECTION_HEADER_PX\n return rowPitch(\n bars.rows.length + 1,\n room - this.fitPadTopBase - FIT_PADDING - headersPx,\n )\n },\n // Where each walk row and section header sits at the rows' pitch\n get walkRowPlacement() {\n const pitch = this.walkRowPitch\n return pitch\n ? sectionPlacement(self.walkRowGroups?.sections ?? [], pitch.rowPx)\n : undefined\n },\n // What the walk-rows key says of genes: where they went unread, or one\n // note that rows this thin box none, as the walk strip's key says\n get walkRowGeneKey() {\n return walkRowGeneKey(\n this.walkRowPitch,\n !!self.walkRowGenes?.size,\n self.walkRowGeneGaps,\n )\n },\n // Walk rows label from the bars themselves, which follow the selected\n // repeat and sample filter that the layout, run once per cut, cannot\n get drawnRowLabels() {\n const place = this.walkRowPlacement\n const labels = walkRowLabels(\n self.walkRowBars,\n self.layoutResult,\n this.walkRowPitch,\n )\n return self.walkRowBars && place\n ? labels.map((l, i) => ({ ...l, y: place.rowY(i) }))\n : labels\n },\n // The row labels are pinned to the pane's left edge, so the fit starts\n // the drawing past the widest one.\n get fitPadLeft() {\n return Math.max(\n FIT_PADDING,\n ...this.drawnRowLabels.map(r => rowLabelBox(r.label, 0).x1 + 6),\n )\n },\n // Extent of the drawing in layout units, shared by the pane height and\n // zoomToFit. On a reference-bp layout x is the cut window rather than\n // how far the drawing reaches: an allele anchored far outside it is a\n // fact about the graph, not a reason to draw the window at 6% of the\n // frame. A popped bubble fits to what it drew. Walk rows reach as far as\n // the bars on screen, which a repeat pick or a sample filter narrows\n // after the layout ran.\n get layoutBounds() {\n const layout = self.layoutResult\n const bars = self.walkRowBars\n const rowsExtent =\n bars && layout?.extent\n ? walkRowsExtent(bars, this.walkRowPitch)\n : undefined\n return layout\n ? drawingBounds(layout, {\n region: self.popStack.length === 0 ? self.graphRegion : undefined,\n extent: rowsExtent && {\n ...rowsExtent,\n maxY: rowsExtent.maxY + (this.walkRowPlacement?.headersPx ?? 0),\n },\n })\n : undefined\n },\n // What a hovered row's label and readout would say, while its rows are\n // too thin to draw them\n get hoveredWalkRowText() {\n const bars = self.walkRowBars\n const name = self.hoveredWalkRow\n if (!bars || name === null || this.walkRowPitch?.readouts !== false) {\n return undefined\n }\n const isReference = bars.reference.name === name\n const row = isReference\n ? bars.reference\n : bars.rows.find(r => r.name === name)\n return row\n ? {\n label: row.label,\n readout: walkRowReadout(\n row,\n isReference ? undefined : bars.reference,\n bars.unit,\n row.call,\n ),\n }\n : undefined\n },\n // The walk row under a pane point, as its index among the reference row\n // and the rows below it, where the point is on its bar\n walkRowAt(screenX: number, screenY: number) {\n const bars = self.walkRowBars\n const pitch = this.walkRowPitch\n const place = this.walkRowPlacement\n if (!bars || !pitch || !place) {\n return undefined\n }\n const i = place.rowAt(\n (screenY - self.translateY) / self.scaleY,\n bars.rows.length + 1,\n )\n const row = [bars.reference, ...bars.rows][i]\n const y = place.rowY(i) * self.scaleY + self.translateY\n const bp = (screenX - self.translateX) / self.scaleX - bars.origin\n return row &&\n Math.abs(screenY - y) <= pitch.barPx / 2 + 2 &&\n bp >= 0 &&\n bp <= row.bp\n ? i\n : undefined\n },\n // Room over a tube map for the rows its genes need, one inside the\n // padding and one more for each further gene that overlaps it, and\n // room for the reference strip\n get fitPadTopBase() {\n const rows = tubeMapGeneRows(self.tubeMapGenes)\n return (\n FIT_PADDING +\n Math.max(0, rows - 1) * GENE_ROW_PX +\n self.referenceStripZonePx\n )\n },\n // The fit draws nothing under the legend. It leaves the legend room on\n // the side that costs the drawing less scale: beside a tall drawing,\n // which has width to spare, or above a wide flat one, which takes the\n // height instead. A drawing whose x the host places can only move down.\n // Reads get no room: their letters, and the legend row naming them, come\n // and go with the fit's scale.\n get legendRoom(): 'right' | 'top' | undefined {\n const bounds = this.layoutBounds\n const { width, height } = self.legendSize\n if (\n !bounds ||\n bounds.w <= 0 ||\n width === 0 ||\n self.facetPanels ||\n self.tubeMapReads\n ) {\n return undefined\n }\n if (self.hostPlacesX) {\n return 'top'\n }\n const base = this.fitPadTopBase\n // a track's height is its own\n const room = self.host ? this.canvasHeight : this.paneCeiling\n const across = (padRight: number) =>\n (self.paneWidth - this.fitPadLeft - padRight) / bounds.w\n const down = (padTop: number) =>\n self.pixelRows\n ? bounds.h + padTop + FIT_PADDING <= room\n ? Infinity\n : 0\n : (room - padTop - FIT_PADDING) / bounds.h\n const beside = Math.min(across(width + 2 * LEGEND_INSET_PX), down(base))\n const above = Math.min(\n across(FIT_PADDING),\n down(base + height + LEGEND_INSET_PX),\n )\n return above >= beside ? 'top' : 'right'\n },\n get fitPadTop() {\n return (\n this.fitPadTopBase +\n (this.legendRoom === 'top'\n ? self.legendSize.height + LEGEND_INSET_PX\n : 0)\n )\n },\n get fitPadRight() {\n return this.legendRoom === 'right'\n ? Math.max(FIT_PADDING, self.legendSize.width + 2 * LEGEND_INSET_PX)\n : FIT_PADDING\n },\n // A tube map on its own axis reads by panning along it, as in\n // sequenceTubeMap. Rather than shrink a long cut to a strip, the fit\n // stops where its tubes are MIN_FIT_TUBE_PX wide, or at whatever fits\n // the tallest pane, with the cut's left end on screen.\n get minFitScale() {\n const bounds = this.layoutBounds\n const layout = self.layoutResult\n const tubePx = layout?.tubeMap?.layout.tracks[0]?.width\n return bounds && bounds.h > 0 && tubePx && !layout.referenceAxis\n ? Math.min(\n MIN_FIT_TUBE_PX / tubePx,\n (this.paneCeiling - this.fitPadTop - FIT_PADDING) / bounds.h,\n )\n : 0\n },\n // The facet as a spec writes it: the bare field while nothing else is\n // written, the whole setting otherwise, and nothing while off\n get facetSpec(): string | FacetSetting | undefined {\n const { field, domain, columns } = self.facet\n return field === ''\n ? undefined\n : domain.length === 0 && columns === undefined\n ? field\n : {\n field,\n domain: [...domain],\n ...(columns === undefined ? {} : { columns }),\n }\n },\n // Which grid cell each panel takes; see facetCells\n get facetPlacement() {\n const panels = self.facetPanels\n const { field, domain } = self.facet\n return panels\n ? facetCells(\n panels.map(p => p.walks[0]!.name),\n self.hostPlacesX || field === '' ? 'walk' : field,\n domain,\n )\n : undefined\n },\n // How the facet panels tile the pane in `room` px. A track whose x the\n // linear view places stacks full-width panels so each keeps that x.\n facetGridIn(room: number): FacetGrid | undefined {\n const place = this.facetPlacement\n const bounds = this.layoutBounds\n return place && bounds && bounds.w > 0\n ? facetGrid({\n count: place.count,\n bounds,\n pixelRows: self.pixelRows,\n width: self.paneWidth,\n room,\n columns: self.hostPlacesX\n ? 1\n : (place.columns ?? self.facet.columns),\n })\n : undefined\n },\n get facetGrid() {\n return this.facetGridIn(self.host ? this.canvasHeight : this.paneCeiling)\n },\n // The pane is as tall as the drawing, rather than a fixed box the drawing\n // floats in. A row layout's rows are px, so its height is a sum; an\n // isotropic layout has no height of its own and takes its aspect ratio\n // at the width's fit. Neither reads `scale`, so the fit reads this\n // without feeding back into it.\n get canvasHeight(): number {\n const bounds = this.layoutBounds\n const usableWidth = self.paneWidth - FIT_PADDING - this.fitPadRight\n const ceiling = this.paneCeiling\n if (!bounds) {\n return ceiling\n }\n const grid = this.facetGrid\n if (grid) {\n return Math.max(MIN_CANVAS_HEIGHT, grid.total)\n }\n // never shorter than the legend, which a flat drawing would clip\n const floor = Math.max(\n MIN_CANVAS_HEIGHT,\n self.legendSize.height +\n 2 * LEGEND_INSET_PX +\n self.referenceStripZonePx,\n )\n if (self.pixelRows) {\n return Math.min(\n ceiling,\n Math.max(floor, bounds.h + this.fitPadTop + FIT_PADDING),\n )\n }\n return bounds.w > 0 && usableWidth > 0\n ? Math.min(\n ceiling,\n Math.max(\n floor,\n bounds.h * Math.max(usableWidth / bounds.w, this.minFitScale) +\n this.fitPadTop +\n FIT_PADDING,\n ),\n )\n : ceiling\n },\n // What the transform maps the drawing into: one facet panel while the\n // pane is faceted, since every panel shares it, else the pane\n get viewBox() {\n const grid = this.facetGrid\n return grid\n ? { width: grid.width, height: grid.height }\n : { width: self.paneWidth, height: this.canvasHeight }\n },\n // Where the fit puts the drawing, or undefined until there is a layout\n // and a measured canvas to fit it into\n get fittedTransform() {\n const bounds = this.layoutBounds\n const grid = this.facetGrid\n return !bounds\n ? undefined\n : grid\n ? fitTransform(bounds, grid.width, grid.height, self.pixelRows, {\n padLeft: FACET_PAD_PX,\n padTop: FACET_PAD_PX,\n padRight: FACET_PAD_PX,\n padBottom: FACET_PAD_PX,\n })\n : fitTransform(\n bounds,\n self.paneWidth,\n this.canvasHeight,\n self.pixelRows,\n {\n minScale: this.minFitScale,\n padLeft: this.fitPadLeft,\n padTop: this.fitPadTop,\n padRight: this.fitPadRight,\n },\n )\n },\n }))\n .views(self => ({\n // The window the transform shows plus a pane of overscan all round,\n // which a pan inside needs no rebuild for\n viewportToBuild() {\n return padded(paneViewportOf(self), VIEWPORT_PANES_BUILT)\n },\n // Hover and selection as draw-time colour overrides, stated whole, so\n // there is nothing to restore and nothing to go stale when a rebuild\n // renumbers the batch\n applyHighlights(b: Renderer) {\n const { hoveredNode, hoveredEdge, selectedNode } = self\n const nodes = new Map<string, number>()\n if (selectedNode !== null) {\n nodes.set(selectedNode, SELECT_BRIGHTEN)\n }\n if (hoveredNode !== null && hoveredNode !== selectedNode) {\n nodes.set(hoveredNode, HOVER_BRIGHTEN)\n }\n b.setNodeHighlights(nodes)\n b.setEdgeHighlight(hoveredEdge, HOVER_BRIGHTEN)\n },\n // Draws the uploaded batch through the pane's transform\n paint(b: Renderer) {\n // getDpr(), never a bare `devicePixelRatio`: it is capped at\n // MAX_DPR so this canvas costs what every other canvas in the app\n // costs on a 3x display (the square of the ratio, i.e. 9x the\n // pixels of 1x against the 4x everything else pays), and it is the\n // same read `syncCanvasSize` sizes the backing store with \u2014 two\n // call sites reading the global separately can disagree, and then\n // the geometry lands at a different scale from the canvas under it.\n const dpr = getDpr()\n b.updateTransform({\n scaleX: self.scaleX * dpr,\n scaleY: self.scaleY * dpr,\n translateX: self.translateX * dpr,\n translateY: self.translateY * dpr,\n // Handed over rather than read again by the backend: the\n // thicknesses in the vertex buffer are css px and are expanded\n // after this transform, so they need the same ratio the fields\n // above were already multiplied by. See TransformUniform.dpr.\n dpr,\n })\n // Clear under a reference strip: GraphCanvas lays the paper below the\n // strip, so the linear view's gridlines show through between its blocks\n b.render(\n self.referenceStripShown\n ? [0, 0, 0, 0]\n : self.darkMode\n ? PAPER_DARK\n : PAPER_LIGHT,\n )\n },\n }))\n .views(self => ({\n // The drawing's batch with `highlight`'s walks lifted, for the window\n // the transform shows. A caller's autorun rebuilds it when the window\n // settles after a pan or zoom, when a drag moves the positions, and when\n // any display option read here changes.\n buildDrawing(highlight: WalkLift | undefined, drawPaths: boolean) {\n const { graph, nodeById, layoutResult, deletionDrawing } = self\n if (!graph || !nodeById || !layoutResult || !deletionDrawing) {\n return undefined\n }\n dependOn(self.viewportDirty, self.positionsVersion)\n const viewportBounds = untracked(() => self.viewportToBuild())\n const batch = buildGeometry({\n // walk rows' overlay draws every bar, the reference's among them;\n // its nodes stay in the hit index, so hovering the bar finds them\n ...layoutGeometryInputs(layoutResult, deletionDrawing, {\n drawsRows: !!self.walkRowBars,\n }),\n graph,\n nodeById,\n colorScheme: self.effectiveColorScheme,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n drawPaths,\n nodeWidth: self.nodeWidth,\n highlight,\n // Untracked, so a zoom does not eagerly rebuild geometry \u2014 the\n // debounced viewportDirty bump drives the scale-dependent rebuild\n // (flatness, arrow visibility, viewport culling), same as pan.\n axis: untracked(() => self.axisScale),\n linearLayout: self.linearLayout,\n viewportBounds,\n // Held against the graph rather than derived here, the same way the\n // deletion drawing is and for the same reason \u2014 see `referenceRamp`.\n referenceRamp: self.referenceRamp,\n // passed so the shared edge-curve cache can tell a drag from a pan\n version: self.positionsVersion,\n })\n return { batch, viewportBounds }\n },\n get overlayLabels() {\n return layoutLabels(self)\n },\n // where the hovered node sits on a lifted walk, while one is hovered\n hoveredOn(walk: LiftedWalk) {\n const id = self.hoveredNode\n const node = id ? self.nodeById?.get(id) : undefined\n return node\n ? (walkPosition(walk, node.id, node.length) ?? 'not on this walk')\n : undefined\n },\n // The spec bandage-figure makes this drawing from with no browser, or\n // undefined for a graph it cannot read again: one cut from a gbz-base\n // track or read from a GFA url, with the genes of a GFF3 tabix track\n figureSpec() {\n const region = self.graphRegion\n const adapter = self.sourceAdapter\n const panSN = adapter?.assemblyNameToPanSN as\n Record<string, string> | undefined\n const window = region && `${region.refName}:${region.start}-${region.end}`\n const gfa = uriOf(self.sourceGfaLocation)\n const db =\n adapter?.type === 'GbzBaseSyntenyAdapter'\n ? uriOf(adapter.gbzDbLocation as FileLocation)\n : undefined\n const source = gfa\n ? { gfa, region: window }\n : db && region && window\n ? {\n gbz: {\n db,\n index: uriOf(adapter!.haplotypeIndexLocation as FileLocation),\n region: window,\n // the adapter cuts a lane by its PanSN prefix\n haplotypes: self.cutHaplotypes?.map(\n lane => panSN?.[lane] ?? lane,\n ),\n referenceSample:\n (adapter!.referenceSample as string | undefined) ||\n panSN?.[region.assemblyName] ||\n region.assemblyName,\n context: adapter!.context as number | undefined,\n snarls: self.cutsWholeWalks\n ? 'overlapping'\n : (adapter!.subgraphSnarls as string | undefined),\n },\n }\n : undefined\n if (!source) {\n return undefined\n }\n const geneTrack = self.showGenes ? self.geneTrack : undefined\n const geneConf = geneTrack\n ? getSession(self).tracks.find(t => t.trackId === geneTrack.trackId)\n : undefined\n const geneAdapter = geneConf\n ? expandTabixShorthand(\n readConfObject(geneConf, 'adapter') as Record<string, unknown>,\n 'gffGzLocation',\n )\n : undefined\n const genes =\n geneAdapter?.type === 'Gff3TabixAdapter'\n ? {\n file: uriOf(geneAdapter.gffGzLocation as FileLocation),\n index: uriOf(\n (geneAdapter.index as { location?: FileLocation } | undefined)\n ?.location,\n ),\n format: 'gff3',\n }\n : undefined\n return JSON.parse(\n JSON.stringify({\n ...source,\n genes: genes?.file && genes.index ? genes : undefined,\n referencePath: self.referencePath || undefined,\n layout: self.chosenLayoutMode,\n ...figureSpecSettings({\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n colorScheme: self.chosenColorScheme,\n nodeWidth: self.nodeWidth,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n colorDomain: self.colorDomain,\n }),\n walks: self.walkLayers.length\n ? self.walkLayers.map(l => (l.color ? l : l.walk))\n : undefined,\n facet: self.walkLayers.length > 1 ? self.facetSpec : undefined,\n walkStrip: self.walkStripShown || undefined,\n walkRowSamples: self.walkStripShown ? self.walkRowSamples : undefined,\n width: self.paneWidth,\n height: self.paneCeiling,\n }),\n ) as Record<string, unknown>\n },\n // Why the drawing cannot be written as SVG, which draws the canvas's\n // nodes, or walk rows' bars\n get figureUnavailable() {\n return !self.layoutResult\n ? 'Nothing is drawn yet'\n : self.walkRowGroups\n ? 'The SVG export cannot group walk rows yet: set Group by\u2026 to None first'\n : self.drawsNodes || self.walkRowBars\n ? undefined\n : `${layoutModeByValue(self.chosenLayoutMode).label} draws a picture of its own, which the SVG export does not`\n },\n // Why bandage-figure can't make this drawing again: it draws only\n // layouts with nodes, from a graph it can read for itself\n get figureSpecUnavailable() {\n return !self.drawsNodes\n ? `bandage-figure draws no ${layoutModeByValue(self.chosenLayoutMode).label} layout`\n : self.popStack.length\n ? 'A spec names the whole graph, so go back out of this bubble first'\n : this.figureSpec()\n ? undefined\n : 'bandage-figure reads a graph cut from a gbz-base track or a GFA url'\n },\n // The drawing as a standalone SVG, fitted, with its genes, its lifted\n // walks' keys, facet panels and the strip of walk rows; see figureSvg\n figure() {\n const { graph, layoutResult } = self\n return graph && layoutResult && !this.figureUnavailable\n ? figureSvg(graph, layoutResult, {\n width: self.paneWidth,\n height: self.paneCeiling,\n walks: self.walkLayers,\n facet: self.facetSpec,\n colorScheme: self.effectiveColorScheme,\n nodeWidth: self.nodeWidth,\n showDeletionEdges: self.showDeletionEdges,\n linearLayout: self.linearLayout,\n contigThickness: self.contigThickness,\n connectorThickness: self.connectorThickness,\n region: self.graphRegion,\n colorDomain: self.colorDomain,\n fitToDrawing: self.popStack.length > 0,\n genes: self.showGenes ? self.backboneGenes : undefined,\n walkRows: self.walkRowBars,\n walkRowPitch: self.walkRowPitch,\n rowGenes: self.walkRowGenes,\n rowGeneGaps: self.walkRowGeneGaps,\n walkStrip: self.walkStripRows && {\n rows: self.walkStripRows,\n rowGenes: self.walkRowGenes,\n rowGeneGaps: self.walkRowGeneGaps,\n },\n // the SVG carries the spec only where the spec draws this same\n // picture\n spec: this.figureSpecUnavailable ? undefined : this.figureSpec(),\n })\n : undefined\n },\n get tubeMapFrame() {\n const drawing = self.layoutResult?.tubeMap\n return drawing\n ? tubeMapFrame(drawing, {\n scaleX: self.scaleX,\n translateX: self.translateX,\n scaleY: self.scaleY,\n translateY: self.translateY,\n usableHeight: self.canvasHeight - self.fitPadTop - FIT_PADDING,\n })\n : undefined\n },\n }))\n .views(self => ({\n // the reference ruler under the tubes, unless the linear view's ruler\n // is already the axis\n get tubeMapRulerBoxes() {\n const reference = self.tubeMapReference\n return reference && !self.hostPlacesX ? rulerBoxes(reference) : undefined\n },\n // The connectors run from the top of the pane down to the tubes' top\n get connectorZoneBottom() {\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n return picture && frame ? frame.y(picture.bounds.minY) - 2 : 0\n },\n // Read off the live blocks, so the bands' tops follow every frame of a\n // pan in the linear view and their bottoms every pan of the tubes\n get tubeMapConnectors() {\n const nodes = self.tubeMapReferenceNodes\n const frame = self.tubeMapFrame\n const { host, graphRegion } = self\n const bp =\n nodes && frame && host?.initialized && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n return nodes && frame && bp\n ? tubeMapConnectors(\n nodes,\n b => b * bp.scale + bp.translateX,\n frame.x,\n self.paneWidth,\n )\n : []\n },\n }))\n .views(self => ({\n // What the tube map's legend has to explain: that on the own axis a\n // box is as wide as the log of its length, the fold its walks' ticks\n // stand for, the reads' strands, and the marks on the reads in view\n get tubeMapKeys() {\n const layout = self.layoutResult\n const reads = layout?.tubeMap?.layout.reads ?? []\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n const shown =\n picture && frame && mismatchesLegible(frame.yScale)\n ? picture.mismatches.filter(m =>\n mismatchOnScreen(m, { x: frame.x, width: self.paneWidth }),\n )\n : []\n return {\n logWidths: layout?.tubeMap !== undefined && !layout.referenceAxis,\n foldBp:\n self.tubeMapDeviations.length > 0 ? self.tubeMapFold : undefined,\n forwardReads: reads.some(r => !r.is_reverse),\n reverseReads: reads.some(r => r.is_reverse),\n mismatches: new Set(shown.map(m => m.kind)),\n }\n },\n tubeMapNodeAt(sx: number, sy: number) {\n const drawing = self.layoutResult?.tubeMap\n const frame = self.tubeMapFrame\n return (\n (drawing && frame ? tubeMapNodeAt(drawing, frame, sx, sy) : null) ??\n connectorAt(self.tubeMapConnectors, self.connectorZoneBottom, sx, sy) ??\n null\n )\n },\n }))\n", "import type { SubgraphRegion } from '../GetSubgraph'\n\n// The members of a LinearGenomeView a hosted pane reads and drives.\n// Structural, because this plugin takes no runtime dependency on the LGV\n// plugin (see hoverSync/index.tsx).\nexport interface HostBlock {\n refName: string\n assemblyName: string\n start: number\n end: number\n offsetPx: number\n reversed?: boolean\n displayedRegionIndex?: number\n}\n\nexport interface LinearHost {\n id: string\n initialized: boolean\n bpPerPx: number\n offsetPx: number\n width: number\n displayedRegions: readonly { start: number; end: number }[]\n dynamicBlocks: { contentBlocks: readonly HostBlock[] }\n coarseDynamicBlocks: readonly HostBlock[]\n horizontalScroll: (distance: number) => number\n zoomTo: (bpPerPx: number, offset?: number) => number\n navTo?: (loc: {\n refName: string\n assemblyName: string\n start: number\n end: number\n }) => void\n // whether the view's body is mounted, which an off-screen view's is not\n effectiveBodyMounted?: boolean\n hasVisibleContent?: boolean\n}\n\nexport function isLinearHost(view: unknown): view is LinearHost {\n if (typeof view !== 'object' || view === null) {\n return false\n }\n const v = view as Record<string, unknown>\n return (\n typeof v.horizontalScroll === 'function' &&\n typeof v.zoomTo === 'function' &&\n 'coarseDynamicBlocks' in v &&\n 'dynamicBlocks' in v\n )\n}\n\nfunction widest(blocks: readonly HostBlock[]) {\n return blocks.reduce<HostBlock | undefined>(\n (best, b) => (best && best.end - best.start >= b.end - b.start ? best : b),\n undefined,\n )\n}\n\nexport interface HostWindow {\n refName: string\n assemblyName: string\n start: number\n end: number\n bpPerPx: number\n // the view's width in bp, which the margin is sized by: a block at a contig\n // end is clipped, the zoom is not\n span: number\n regionStart: number\n regionEnd: number\n}\n\n// x is reference bp on an anchored layout, so the graph shows what the linear\n// view shows when one bp is as many px in both and the cut's refName sits at\n// the same screen x. Undefined when the linear view shows no block of that\n// refName, which is a re-cut's job rather than the frame's. A reversed block\n// runs bp right to left, which only the tube map's connectors can draw.\nexport function hostFrame(view: LinearHost, region: SubgraphRegion) {\n const block = widest(\n view.dynamicBlocks.contentBlocks.filter(\n b =>\n b.refName === region.refName && b.assemblyName === region.assemblyName,\n ),\n )\n const { bpPerPx } = view\n if (!block || !(bpPerPx > 0)) {\n return undefined\n }\n const left = block.offsetPx - view.offsetPx\n return block.reversed\n ? { scale: -1 / bpPerPx, translateX: left + block.end / bpPerPx }\n : { scale: 1 / bpPerPx, translateX: left - block.start / bpPerPx }\n}\n\n// Read off the LIVE blocks even when the coarse ones woke the caller: those\n// name where the window was half a second ago (SyntenyFollow/CLAUDE.md).\nexport function hostWindow(view: LinearHost): HostWindow | undefined {\n const block = widest(view.dynamicBlocks.contentBlocks)\n const displayed =\n block?.displayedRegionIndex === undefined\n ? undefined\n : view.displayedRegions[block.displayedRegionIndex]\n return block && view.bpPerPx > 0\n ? {\n refName: block.refName,\n assemblyName: block.assemblyName,\n start: block.start,\n end: block.end,\n bpPerPx: view.bpPerPx,\n span: view.bpPerPx * view.width,\n regionStart: displayed?.start ?? block.start,\n regionEnd: displayed?.end ?? block.end,\n }\n : undefined\n}\n\n// The window plus one window-width each side, clamped to the displayed\n// region, with the margins narrowed until the whole cut fits under `capBp`.\nexport function hostCut(\n window: HostWindow,\n capBp: number,\n margins = true,\n): SubgraphRegion {\n const visible = window.end - window.start\n const margin = margins\n ? Math.max(0, Math.min(window.span, (capBp - visible) / 2))\n : 0\n let start = Math.max(window.regionStart, Math.floor(window.start - margin))\n let end = Math.min(window.regionEnd, Math.ceil(window.end + margin))\n // Rounding outward can put a cut a base or two past the cap, which the load\n // refuses whole; trim it back rather than lose the cut.\n const over = end - start - capBp\n if (over > 0) {\n start += Math.floor(over / 2)\n end -= Math.ceil(over / 2)\n }\n return {\n refName: window.refName,\n assemblyName: window.assemblyName,\n start,\n end,\n }\n}\n\n// With margins, a cut holds while the window is inside it; without, only the\n// window itself does, since the drawing is the window.\nexport function cutHolds(\n cut: SubgraphRegion | undefined,\n window: HostWindow,\n margins = true,\n) {\n if (\n cut?.refName !== window.refName ||\n cut.assemblyName !== window.assemblyName\n ) {\n return false\n }\n // to the base, since a cut trimmed to its cap can end a base inside the window\n if (margins) {\n return cut.start <= window.start + 1 && window.end <= cut.end + 1\n }\n const exact = hostCut(window, Infinity, false)\n return (\n Math.abs(cut.start - exact.start) < 1 && Math.abs(cut.end - exact.end) < 1\n )\n}\n", "import {\n backboneNodes,\n backboneSpan,\n} from '@jbrowse/bandage-core/anchoredNodes'\nimport { nodeReferenceSpan } from '@jbrowse/bandage-core/referenceSpan'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport { getContainingView, getSession } from '@jbrowse/core/util'\n\nimport { withGraphViews } from './graphViews'\nimport {\n contributingAssemblies,\n nodeOwnLocation,\n resolveContributors,\n resolveLocationAssembly,\n} from '../../launchFromGraph/contributors'\nimport {\n canonicalAssemblyName,\n paddedLocation,\n withReferenceRegion,\n} from '../../launchFromGraph/launchFromGraph'\nimport { linearViewTarget } from '../../launchFromGraph/linearViewTarget'\nimport { GENE_ADAPTER_TYPES, pickGeneTrack } from '../genes/geneFeatures'\nimport { isLinearHost } from '../host'\n\nimport type { LinearHost } from '../host'\n\nexport const withLaunchViews = withGraphViews\n .views(self => ({\n // Every assembly this graph names a segment from, with the locus each one\n // contributes here. rGFA's SN tag is what makes this knowable: the graph\n // states its own contributors, so the view can offer a way out to each of\n // them without consulting an alignment.\n //\n // Gaps larger than the backbone span split a contributor's segments into\n // separate loci and the widest wins, so a sample that also contributes\n // sequence from a distant duplication is launched at the locus on screen\n // rather than at the union of the two.\n get contributingAssemblies() {\n const graph = self.graph\n const backbone = graph ? backboneNodes(graph) : []\n return graph\n ? contributingAssemblies(graph, {\n maxGap: backbone.length > 0 ? backboneSpan(backbone) : Infinity,\n })\n : []\n },\n }))\n .views(self => ({\n // A node's PanSN sample as an assembly this session can open, or\n // undefined. The graph's spelling and the assembly's need not agree:\n // HPRC writes `CHM13` where the assembly is UCSC's `hs1`. The track the\n // graph was cut from states that pairing in its `assemblyNameToPanSN`,\n // so its map is read first, then `assemblyManager`'s names and aliases.\n //\n // `has` before `get`, deliberately: `get` reports an unknown name to\n // `Core-handleUnrecognizedAssembly`, which asks every installed plugin to\n // go supply it, and this is a probe run for hundreds of haplotypes per\n // graph.\n get assemblyResolver() {\n const { assemblyManager } = getSession(self)\n const panSN = self.sourceAdapter?.assemblyNameToPanSN as\n Record<string, string> | undefined\n const byPrefix = new Map(\n Object.entries(panSN ?? {}).map(([asm, prefix]) => [prefix, asm]),\n )\n const loaded = (name: string | undefined) =>\n name !== undefined && assemblyManager.has(name)\n ? (assemblyManager.get(name)?.name ?? name)\n : undefined\n return (sample: string) => loaded(byPrefix.get(sample)) ?? loaded(sample)\n },\n // Each assembly's gene track among the session's tracks, picked as the\n // backbone's is, so a walk row can read its haplotype's own annotation.\n // One pass over the tracks, not one per row.\n get geneTracksByAssembly() {\n const byAssembly = new Map<\n string,\n { trackId: string; name: string; adapterType: string }[]\n >()\n for (const t of getSession(self).tracks) {\n const adapterType = (readConfObject(t, 'adapter') as { type: string })\n .type\n if (!GENE_ADAPTER_TYPES.has(adapterType)) {\n continue\n }\n const track = {\n trackId: t.trackId as string,\n name: readConfObject(t, 'name') as string,\n adapterType,\n }\n for (const name of readConfObject(t, 'assemblyNames') as string[]) {\n const asm = canonicalAssemblyName(getSession(self), name)\n byAssembly.set(asm, [...(byAssembly.get(asm) ?? []), track])\n }\n }\n return new Map(\n [...byAssembly].flatMap(([asm, tracks]) => {\n const picked = pickGeneTrack(tracks, '')\n return picked ? [[asm, picked] as const] : []\n }),\n )\n },\n }))\n .views(self => ({\n // The contributors a view can actually be opened on: those naming an\n // assembly this session has loaded. Every strain of an E. coli pangenome\n // demo is its own assembly, so all of them resolve; an HPRC graph names\n // hundreds of haplotypes that no session loads, so only the reference\n // does.\n get launchableAssemblies() {\n return resolveContributors(\n withReferenceRegion(self.contributingAssemblies, self.graphRegion),\n self.assemblyResolver,\n )\n },\n // Whether there is a linear view this graph may draw a highlight into \u2014\n // the paired one, or the session's only one on the reference assembly.\n // Read by the node menu, which offers the item only when it would land\n // somewhere.\n get canHighlightInLinearView() {\n const region = self.graphRegion\n return (\n region !== undefined &&\n linearViewTarget({\n views: [...getSession(self).views],\n connectedViewId: self.connectedViewId,\n assemblyName: region.assemblyName,\n }) !== undefined\n )\n },\n // Where one node can be opened: on its own assembly, and on the reference\n // the graph was cut against. Both are padded to a readable window \u2014 a\n // base-level allele is a few bp, and a linear view framed on exactly that\n // shows no context at all.\n nodeLaunchTargets(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n const own = node ? nodeOwnLocation(node) : undefined\n const ownAssembly = own\n ? resolveLocationAssembly(self.assemblyResolver, own)\n : undefined\n const region = self.graphRegion\n const nodeById = self.nodeById\n const neighbors = self.nodeNeighbors\n const span =\n region && nodeById && neighbors\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n const onReference =\n region && span\n ? {\n sample: region.assemblyName,\n haplotype: undefined,\n refName: region.refName,\n ...span,\n }\n : undefined\n return {\n own:\n own && ownAssembly\n ? { location: paddedLocation(own), assembly: ownAssembly }\n : undefined,\n reference:\n region && onReference\n ? {\n location: paddedLocation(onReference),\n assembly: region.assemblyName,\n }\n : undefined,\n // Unpadded: a mark is of the node, the same span its hover band\n // draws. The padding above is room to read a view opened on it.\n highlight:\n region && onReference\n ? { location: onReference, assembly: region.assemblyName }\n : undefined,\n }\n },\n }))\n .views(self => ({\n // The linear view this pane draws inside, when a display hosts it: x is\n // that view's window and the cut is re-made when the window leaves it.\n // A pane that is a view of its own has none.\n get host(): LinearHost | undefined {\n let view: unknown\n try {\n view = getContainingView(self)\n } catch {\n return undefined\n }\n return isLinearHost(view) ? view : undefined\n },\n }))\n", "import {\n bubbleSegmentIds,\n classifyBubble,\n formatBp\n} from \"./chunk-WOO7QYKB.js\";\nimport {\n svgPath\n} from \"./chunk-2CVHXFK7.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/bubbles/bubbleHalos.ts\nvar WHOLE_FRACTION = 0.9;\nvar NAMED_WALKS = 2;\nvar MIN_CHIPPED_BP = 1e3;\nfunction bubbleHalos(graph, bubbles, positions, walkLabel = (name) => name, repeats = []) {\n const byName = new Map(graph.nodes.map((n) => [n.name, n]));\n const halos = [];\n for (const bubble of bubbles) {\n const parts = [];\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n const nodeIds = [];\n const ends = [];\n for (const name of bubbleSegmentIds(bubble)) {\n const node = byName.get(name);\n const line = node && positions[node.id];\n if (!node || !line?.length) {\n continue;\n }\n if (isBackbone(node) && (node.stable.start < bubble.start || node.stable.start >= bubble.end)) {\n ends.push(line[Math.floor(line.length / 2)]);\n continue;\n }\n nodeIds.push(node.id);\n parts.push(svgPath(line.length === 1 ? [line[0], line[0]] : line));\n for (const p of line) {\n minX = Math.min(minX, p.x);\n maxX = Math.max(maxX, p.x);\n minY = Math.min(minY, p.y);\n }\n }\n if (nodeIds.length === 0) {\n continue;\n }\n const labelAt = { x: (minX + maxX) / 2, y: minY };\n const anchor = ends.length ? {\n x: ends.reduce((s, p) => s + p.x, 0) / ends.length,\n y: ends.reduce((s, p) => s + p.y, 0) / ends.length\n } : labelAt;\n const sharing = /* @__PURE__ */ new Map();\n for (const route of bubble.routes ?? []) {\n for (const id of new Set(route.steps)) {\n sharing.set(id, (sharing.get(id) ?? 0) + 1);\n }\n }\n const routes = [];\n for (const route of bubble.routes ?? []) {\n if (bubble.longestAlleleLength < MIN_CHIPPED_BP) {\n break;\n }\n if (route.steps.length === 0) {\n continue;\n }\n const rarest = Math.min(...route.steps.map((id) => sharing.get(id)));\n let at;\n let far = -1;\n for (const id of route.steps) {\n if (sharing.get(id) !== rarest) {\n continue;\n }\n for (const p of positions[id] ?? []) {\n const d = Math.hypot(p.x - anchor.x, p.y - anchor.y);\n if (d > far) {\n far = d;\n at = p;\n }\n }\n }\n if (at) {\n routes.push({ route, at, text: routeText(route, walkLabel) });\n }\n }\n halos.push({\n bubble,\n ...classifyBubble(bubble, repeats),\n path: parts.join(\"\"),\n labelAt,\n members: nodeIds.length,\n nodeIds,\n whole: nodeIds.length >= WHOLE_FRACTION * graph.nodes.length,\n routes\n });\n }\n return halos;\n}\nfunction routeText(route, walkLabel) {\n const names = [...new Set(route.walks.map(walkLabel))].sort();\n const shown = names.slice(0, NAMED_WALKS).join(\", \");\n const more = names.length > NAMED_WALKS ? ` +${names.length - NAMED_WALKS}` : \"\";\n return `${shown}${more} \\xB7 ${formatBp(route.bp)}`;\n}\n\nexport {\n bubbleHalos\n};\n", "import {\n SATURATED_PATH_COUNT\n} from \"./chunk-MFKORG3F.js\";\nimport {\n referenceOrder\n} from \"./chunk-HNQPEMYE.js\";\nimport {\n isBackbone\n} from \"./chunk-FYQWPEEY.js\";\n\n// src/bubbles/bubblesFromGraph.ts\nfunction bubblesFromGraph(graph) {\n if (!graph.nodes.some(isBackbone)) {\n return [];\n }\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const order = referenceOrder(graph);\n const indexOf = new Map(order.map((id, i) => [id, i]));\n const reach = new Int32Array(order.length + 1);\n const succ = /* @__PURE__ */ new Map();\n const linked = /* @__PURE__ */ new Set();\n for (const e of graph.edges) {\n const a = indexOf.get(e.from);\n const b = indexOf.get(e.to);\n if (a === void 0 || b === void 0 || a === b) {\n continue;\n }\n linked.add(`${e.from}>${e.to}`).add(`${e.to}>${e.from}`);\n const [lo, hi] = a < b ? [a, b] : [b, a];\n reach[lo + 1]++;\n reach[hi]--;\n const [from, to] = a < b ? [e.from, e.to] : [e.to, e.from];\n (succ.get(from) ?? succ.set(from, /* @__PURE__ */ new Set()).get(from)).add(to);\n }\n for (let i = 1; i < reach.length; i++) {\n reach[i] += reach[i - 1];\n }\n const backbone = graph.nodes.filter(isBackbone).sort((a, b) => a.stable.start - b.stable.start);\n const ends = /* @__PURE__ */ new Set([backbone[0].id, backbone.at(-1).id]);\n const boundaries = backbone.map((node) => [node, indexOf.get(node.id)]).filter(([node, i]) => ends.has(node.id) || reach[i] === 0).sort(([a, ia], [b, ib]) => ia - ib || a.stable.start - b.stable.start);\n const walkIndex = graph.paths?.map((p) => {\n const at = /* @__PURE__ */ new Map();\n p.nodeIds.forEach((id, i) => {\n if (!at.has(id)) {\n at.set(id, i);\n }\n });\n return at;\n });\n const bubbles = [];\n for (let i = 0; i + 1 < boundaries.length; i++) {\n const [start, i0] = boundaries[i];\n const [end, i1] = boundaries[i + 1];\n const interior = order.slice(i0 + 1, i1);\n if (interior.length === 0) {\n continue;\n }\n const best = /* @__PURE__ */ new Map([[start.id, { min: 0, max: 0, n: 1 }]]);\n for (const id of [start.id, ...interior]) {\n const cur = best.get(id);\n if (!cur) {\n continue;\n }\n for (const t of succ.get(id) ?? []) {\n const ti = indexOf.get(t);\n if (ti > i1) {\n continue;\n }\n const add = t === end.id ? 0 : byId.get(t).length;\n const prev = best.get(t);\n best.set(t, {\n min: Math.min(prev?.min ?? Infinity, cur.min + add),\n max: Math.max(prev?.max ?? -Infinity, cur.max + add),\n n: Math.min(SATURATED_PATH_COUNT, cur.n + (prev?.n ?? 0))\n });\n }\n }\n const walked = walkIndex && walkRoutes(graph, byId, walkIndex, start.id, end.id);\n const crossed = walked?.n ? walked : void 0;\n const routes = crossed ?? best.get(end.id) ?? { min: 0, max: 0, n: 0 };\n const walksLeave = walked !== void 0 && walked.left > 0;\n const refStart = start.stable.start + start.length;\n const refEnd = end.stable.start;\n const chain = [\n start.id,\n ...interior.filter((id) => isBackbone(byId.get(id))),\n end.id\n ];\n const chainBroken = chain.some(\n (id, k) => k > 0 && !linked.has(`${chain[k - 1]}>${id}`)\n );\n const partial = chainBroken || walksLeave;\n const fallback = chainBroken && !crossed;\n bubbles.push({\n refName: start.stable.refName,\n start: refStart,\n end: refEnd,\n segmentCount: interior.length + 2,\n pathCount: routes.n,\n // a real inversion test needs each walk's direction relative to the\n // reference; the first visit's strand is just whichever path anchored the\n // node\n inversion: false,\n shortestAlleleLength: fallback ? refEnd - refStart : routes.min,\n longestAlleleLength: fallback ? refEnd - refStart : routes.max,\n segments: [start, ...interior.map((id) => byId.get(id)), end].map((n) => n.name).join(\",\"),\n shortestAllele: void 0,\n longestAllele: void 0,\n partial,\n routes: crossed?.routes\n });\n }\n return bubbles;\n}\nfunction walkRoutes(graph, byId, walkIndex, startId, endId) {\n const seen = /* @__PURE__ */ new Map();\n let min = Infinity;\n let max = -Infinity;\n let left = 0;\n graph.paths.forEach((p, k) => {\n const i0 = walkIndex[k].get(startId);\n const i1 = walkIndex[k].get(endId);\n if (i0 === void 0 || i1 === void 0) {\n if (i0 !== void 0 || i1 !== void 0) {\n left++;\n }\n return;\n }\n const steps = p.nodeIds.slice(Math.min(i0, i1) + 1, Math.max(i0, i1));\n if (i1 < i0) {\n steps.reverse();\n }\n let bp = 0;\n for (const id of steps) {\n bp += byId.get(id)?.length ?? 0;\n }\n const key = steps.join(\",\");\n const route = seen.get(key) ?? { steps, bp, walks: [] };\n route.walks.push(p.name);\n seen.set(key, route);\n min = Math.min(min, bp);\n max = Math.max(max, bp);\n });\n return seen.size || left ? { min, max, n: seen.size, left, routes: [...seen.values()] } : void 0;\n}\n\nexport {\n bubblesFromGraph\n};\n", "import {\n computeColorSchemeRange,\n getNodeColor\n} from \"./chunk-RCWYY6XA.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-UMNCCYBN.js\";\n\n// src/tubeMap/nodeColors.ts\nfunction tubeMapNodeColors(graph, colorScheme, referenceRamp) {\n if (colorScheme === \"uniform\" || colorScheme === \"grey\") {\n return void 0;\n }\n const range = { ...computeColorSchemeRange(graph), referenceRamp };\n return new Map(\n graph.nodes.map((node, index) => [\n node.id,\n abgrToCssRgba(getNodeColor(node, index, colorScheme, range))\n ])\n );\n}\n\nexport {\n tubeMapNodeColors\n};\n", "import { bubbleHalos } from '@jbrowse/bandage-core/bubbles/bubbleHalos'\nimport { bubblesFromGraph } from '@jbrowse/bandage-core/bubbles/bubblesFromGraph'\nimport { resolveColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport {\n deletionDrawing,\n deletionEdges,\n} from '@jbrowse/bandage-core/deletionEdges'\nimport { genePins } from '@jbrowse/bandage-core/genes/genePins'\nimport { filterSamples, walkRows } from '@jbrowse/bandage-core/layout/walkRows'\nimport {\n layoutModeByValue,\n modeUsesLayoutEngine,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { nodeInk } from '@jbrowse/bandage-core/nodeWidths'\nimport {\n pathColorsLegible,\n pathGreyCssColor,\n pathLegend,\n walkLabelsOf,\n} from '@jbrowse/bandage-core/pathColors'\nimport {\n backboneAssembly,\n featuresOnBackbone,\n graphBackbone,\n} from '@jbrowse/bandage-core/reference'\nimport {\n buildNeighbors,\n nodeReferenceSpan,\n} from '@jbrowse/bandage-core/referenceSpan'\nimport {\n LIFT_BACKDROP_CSS,\n computeReferenceRamp,\n} from '@jbrowse/bandage-core/renderer/GeometryBuilder'\nimport { tubeMapNodeColors } from '@jbrowse/bandage-core/tubeMap/nodeColors'\nimport { axisScaleOf } from '@jbrowse/bandage-core/viewport'\nimport { NO_VALUE_COLOR } from '@jbrowse/bandage-core/walkEncoding'\nimport { facetLifts, walkLift } from '@jbrowse/bandage-core/walkHighlight'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'\nimport {\n getContainingTrack,\n getContainingView,\n getEnv,\n getSession,\n} from '@jbrowse/core/util'\n\nimport { TUBE_MAP_MODES, dependOn, geometryPainted, paneBase } from './paneBase'\nimport { trackAdapterConfig } from '../../panSNAliases/trackAdapterConfig'\nimport {\n GENE_ADAPTER_TYPES,\n geneModelsFrom,\n laneFilters,\n pickGeneTrack,\n} from '../genes/geneFeatures'\nimport {\n REPEAT_ADAPTER_TYPES,\n pickRepeatTrack,\n} from '../repeats/repeatFeatures'\nimport { withCalls } from '../repeats/walkCalls'\nimport { groupWalkRows, metadataColumns } from '../walkRowGroups'\n\nimport type {\n ColorScheme,\n ResolvedColorScheme,\n} from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AssemblyNames } from '@jbrowse/bandage-core/reference'\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\nimport type { NodeInk } from '@jbrowse/bandage-core/util/hitDetection'\nimport type { WalkLayer } from '@jbrowse/bandage-core/walkEncoding'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nexport const withGraphViews = paneBase\n .views(self => ({\n get defaultLayoutMode(): LayoutModeValue {\n return 'force'\n },\n get defaultColorScheme(): ColorScheme {\n return 'auto'\n },\n // a source declared but not yet loaded\n get hasPendingSource() {\n return false\n },\n get canRetryLoad() {\n return false\n },\n // the track the graph is cut from: the one the pane is a display of\n get sourceTrack(): AnyConfigurationModel | undefined {\n try {\n return getContainingTrack(self).configuration\n } catch {\n return undefined\n }\n },\n }))\n .views(self => ({\n get chosenLayoutMode() {\n return self.layoutMode ?? self.defaultLayoutMode\n },\n get chosenColorScheme() {\n return self.colorScheme ?? self.defaultColorScheme\n },\n }))\n .views(self => ({\n get paneWidth() {\n return getContainingView(self).width\n },\n // The graph the drawing's node ids address: a folded tube map's coarse\n // graph, the cut otherwise. Hover, details and labels read it, so a\n // merged node reports its own span and length.\n get drawnGraph() {\n return self.layoutResult?.tubeMap?.coarse?.graph ?? self.graph\n },\n }))\n .views(self => ({\n get nodeById() {\n if (self.drawnGraph) {\n const m = new Map<string, GraphNode>()\n for (const n of self.drawnGraph.nodes) {\n m.set(n.id, n)\n }\n return m\n }\n return undefined\n },\n // bp per node id, which is all the label overlay needs of a GraphNode.\n // Held here rather than rebuilt in the component: that render runs on\n // every pan, and the map is a fact about the graph (measured 6.9 ms an\n // allocation on a 30k-node cut).\n get nodeLengths() {\n const m = new Map<string, number>()\n for (const n of self.drawnGraph?.nodes ?? []) {\n m.set(n.id, n.length)\n }\n return m\n },\n get nodeCount() {\n return self.graph?.nodes.length ?? 0\n },\n get edgeCount() {\n return self.graph?.edges.length ?? 0\n },\n get pathCount() {\n return self.graph?.paths?.length ?? 0\n },\n get hasGraph() {\n return self.graph !== undefined\n },\n get geometryPainted() {\n return geometryPainted(self)\n },\n // The app-wide readiness contract (AppReadyMarker, @jbrowse/capture)\n // reads this: a declared source still fetching, or a graph whose\n // settled geometry is not on the canvas yet.\n get showLoading() {\n return (\n self.error === undefined &&\n (self.isLoading ||\n self.hasPendingSource ||\n (self.graph !== undefined && !geometryPainted(self)))\n )\n },\n // Only before anything is drawn: past that point a reload is superseded\n // by the next setting change, and stopping one midway would leave a new\n // graph under the previous graph's layout.\n get canCancelLoad() {\n return self.isLoading && !self.layoutResult\n },\n // Whether the drawing on screen is the FMMM engine's. False before there\n // is a graph, since nothing is drawn by anything yet.\n //\n // Read by the settings that only the engine looks at: the layout quality\n // and the bubble spread do nothing at all to an anchored drawing, which\n // places a node from its coordinates, and the guide says so in prose\n // precisely because the dialog did not. A control that silently does\n // nothing is worse than one that says it cannot \u2014 the same rule the\n // `drawPaths` switch already follows.\n get usesLayoutEngine() {\n return self.graph\n ? modeUsesLayoutEngine(self.chosenLayoutMode, self.graph)\n : false\n },\n // A rank-0 backbone to draw x against, whether the segments declared it\n // (rGFA) or a path walk derived it. Only a GFA with neither tags nor\n // paths has no backbone at all, and there force is the one honest layout.\n get canAnchorLayout() {\n return self.graph?.nodes.some(n => n.stable?.rank === 0) ?? false\n },\n // The paths this graph could be anchored on, for the picker. Empty for an\n // rGFA, which has no P/W records and needs none.\n get anchorPaths() {\n return self.graph?.anchorPaths ?? []\n },\n // Every walk the graph carries, named for a picker, whatever the count.\n get walkChoices() {\n const paths = self.graph?.paths\n return paths?.length ? pathLegend(paths) : []\n },\n // Whether the drawing is actually painted per path, which is not the same\n // question as whether the user asked for it: past MAX_PATH_COLORS the\n // colours say nothing and cost a stroke per path per edge. A bare getter\n // returning a resolved value, the same shape and for the same reason as\n // `effectiveColorScheme` \u2014 every consumer of a path colour reads this\n // one, so the geometry, the hit index and the key cannot disagree about\n // whether there are any. The switch in the settings dialog reads the raw\n // `drawPaths`, so the user's choice stays visible as the choice it is.\n get effectiveDrawPaths() {\n return self.drawPaths && pathColorsLegible(self.graph?.paths?.length ?? 0)\n },\n // The path x is currently drawn on, which is not necessarily the one\n // `referencePath` asked for: an unmatched name falls back rather than\n // leaving the graph unanchored, and the picker has to show what happened.\n get activeReferencePath() {\n return self.graph?.referencePath\n },\n // Undefined for a graph with neither, where the ramp spans the drawn\n // extent (computeReferenceRamp)\n get rampDomain() {\n return self.colorDomain ?? self.graphRegion\n },\n // The ramp a lane coloured by reference position reads, computed only\n // when a layer asks for one: it is a neighbour walk per node\n get walkRamp() {\n const { graph } = self\n return graph &&\n self.walkLayers.some(layer => layer.color?.field === 'reference')\n ? computeReferenceRamp(graph, this.rampDomain)\n : undefined\n },\n // Whether the chosen layout draws the graph's nodes, which a facet\n // splits and a hovered lane row's walk is lifted over\n get modeDrawsNodes() {\n return layoutModeByValue(self.chosenLayoutMode).drawsNodes\n },\n // The walks picked, or while none is, those of the lane row hovered\n get liftedWalkLayers(): WalkLayer[] {\n return self.walkLayers.length > 0 || !this.modeDrawsNodes\n ? self.walkLayers\n : self.hoveredRowWalks.map(walk => ({ walk }))\n },\n // The lifted walks the graph on screen carries, or undefined when none\n // is named or it carries none of those that were\n get walkLift() {\n const { graph } = self\n const layers = this.liftedWalkLayers\n return graph && layers.length > 0 && !self.layoutResult?.tubeMap\n ? walkLift(graph, layers, this.walkRamp)\n : undefined\n },\n // One panel per lifted walk while the pane is faceted by walk, each a\n // lift of that walk alone, on a layout whose nodes the panels can split.\n // See facetLifts.\n get facetPanels() {\n const { graph } = self\n const lift = this.walkLift\n return self.facet.field !== '' &&\n this.modeDrawsNodes &&\n graph &&\n lift &&\n self.walkLayers.length > 1 &&\n lift.walks.length > 1\n ? facetLifts(graph, lift, self.walkLayers, this.walkRamp)\n : undefined\n },\n // The lifted walks as drawn, each panel's own while faceted\n get drawnWalks() {\n return (\n this.facetPanels?.map(panel => panel.walks[0]!) ??\n this.walkLift?.walks ??\n []\n )\n },\n // A tube map draws every walk as a tube of its own\n get liftsWalks() {\n return !TUBE_MAP_MODES.has(self.chosenLayoutMode)\n },\n // The window a lane coloured by reference position spans, by name\n get walkReference() {\n const domain = this.walkLift?.referenceDomain\n return domain && { ...domain, name: self.graphRegion?.refName }\n },\n // A label per walk, which the pickers, the keys and a bubble's label all\n // read, so a walk name repeated across records reads the same everywhere\n get walkLabels() {\n return walkLabelsOf(this.walkChoices)\n },\n walkLabel(name: string) {\n return this.walkLabels.get(name) ?? name\n },\n // Whether a lifted lane paints a node charcoal, the colour a lane coloured\n // by reference position gives what is off the reference\n get liftPaintsOffReference() {\n for (const w of this.walkLift?.walks ?? []) {\n if (w.encoding.field !== 'walk') {\n for (const color of w.colors.values()) {\n if (color === NO_VALUE_COLOR) {\n return true\n }\n }\n }\n }\n return false\n },\n // what the faded rest of the drawing is not on\n get liftedWalksLabel() {\n const walks = this.walkLift?.walks ?? []\n return walks.length === 1 ? this.walkLabel(walks[0]!.name) : 'these walks'\n },\n // The scheme the renderer actually paints with, which is the raw prop\n // unless it is 'auto'. A bare getter returns a resolved value (root\n // CLAUDE.md): every consumer of a colour reads this one, and the two\n // dropdowns read `colorScheme` so \"Auto\" stays visible as the choice it\n // is.\n //\n // 'auto' asks the GRAPH, not the layout. A hue along the reference is\n // meaningful whenever the segments have reference coordinates \u2014\n // `anchoredBy` is exactly that question \u2014 and a force-directed drawing of\n // an rGFA is the case that proves it: the layout has no reference axis and\n // the ramp still says where on the reference each node came from, which is\n // the only quantity a linear track beside it can be painted with too.\n //\n // A tube map tells its paths apart by their tubes' hues, so there 'auto'\n // leaves the boxes clear and a node scheme is the user's pick. Beside\n // reads, which take the reds and the blues, the boxes stay clear\n // whatever was picked.\n get effectiveColorScheme(): ResolvedColorScheme {\n return self.layoutResult?.tubeMap &&\n (this.tubeMapReads || self.chosenColorScheme === 'auto')\n ? 'uniform'\n : resolveColorScheme(self.chosenColorScheme, self.graph)\n },\n get tubeMapReads() {\n return (self.layoutResult?.tubeMap?.layout.reads.length ?? 0) > 0\n },\n // Why no node scheme is on screen to pick, for every control that\n // offers one: lifted walks colour their own lanes and grey the rest,\n // and reads take a tube map's reds and blues\n get colorSchemeLock() {\n return this.walkLift\n ? {\n value: 'By walk',\n why: 'Each lifted walk colours its own lane: set it under the menu, Walk, Colour',\n }\n : this.tubeMapReads\n ? {\n value: 'By strand',\n why: 'Reads take the reds and blues, so the tube map leaves its nodes clear',\n }\n : undefined\n },\n get nodePositions() {\n return self.layoutResult?.nodePositions\n },\n // a length label would sit on the lanes of lifted walks\n get labelsNodeSizes() {\n return !self.layoutResult?.tubeMap && !this.walkLift\n },\n // Empty rather than undefined: every consumer maps over it, and a layout\n // with no row structure (FMMM) is a normal state, not a missing one.\n get rowLabels() {\n return self.layoutResult?.rowLabels ?? []\n },\n // Deletions the layout found inside an allele, empty for the same reason\n // rowLabels is: a layout drawn at sequence scale states none, because\n // there a node's drawn extent already IS its length. `deletions` beside\n // this one is the bare-edge kind, which every layout has.\n get alleleDeletions() {\n return self.layoutResult?.alleleDeletions ?? []\n },\n get deletionRoutes() {\n return self.layoutResult?.deletionRoutes\n },\n get stranded() {\n return self.layoutResult?.stranded\n },\n // Whether the current layout states y in screen px rather than in the same\n // units as x (LayoutResult.pixelRows). Everything that has to put the two\n // axes in one expression reads this through scaleX/scaleY.\n get pixelRows() {\n return self.layoutResult?.pixelRows ?? false\n },\n get zoomPercent() {\n return `${(self.scale * 100).toFixed(1)}%`\n },\n // True while the persisted transform is still the schema default, i.e.\n // neither a restored session nor the user has positioned this view yet,\n // so an incoming layout is free to zoom-to-fit.\n get isDefaultViewport() {\n return self.scale === 1 && self.translateX === 0 && self.translateY === 0\n },\n }))\n .views(self => ({\n get poppedFrom() {\n return self.popStack.at(-1)\n },\n // The bubbles the graph itself states, for a graph with no index: a GBZ\n // cut, a pggb file, the inside of a popped bubble.\n get derivedBubbles() {\n return self.graph ? bubblesFromGraph(self.graph) : []\n },\n }))\n .views(self => ({\n // The bubbles halos draw and pops open. Index rows win where both exist:\n // gfatools measured every allele, the layered order only bounds them.\n get bubbles() {\n return self.indexBubbles?.length ? self.indexBubbles : self.derivedBubbles\n },\n }))\n .views(self => ({\n // the haplotypes the graph on screen was cut for, where a host says\n get cutHaplotypes(): string[] | undefined {\n return undefined\n },\n // the GFA the graph on screen was read from, where a host says\n get sourceGfaLocation(): FileLocation | undefined {\n return undefined\n },\n get sourceAdapter() {\n const track = self.sourceTrack\n return track ? trackAdapterConfig(self, track) : undefined\n },\n get sourceTrackId() {\n const track = self.sourceTrack\n return track ? (readConfObject(track, 'trackId') as string) : undefined\n },\n get assemblyTrackChoices() {\n const region = self.graphRegion\n if (!region) {\n return []\n }\n return getSession(self)\n .tracks.filter(t =>\n (readConfObject(t, 'assemblyNames') as string[]).includes(\n region.assemblyName,\n ),\n )\n .map(t => ({\n trackId: t.trackId as string,\n name: readConfObject(t, 'name') as string,\n adapterType: (readConfObject(t, 'adapter') as { type: string }).type,\n }))\n },\n }))\n .views(self => ({\n get geneTrackChoices() {\n return self.assemblyTrackChoices.filter(t =>\n GENE_ADAPTER_TYPES.has(t.adapterType),\n )\n },\n // The session's feature tracks a repeat annotation could be, for the\n // picker; which one is read is pickRepeatTrack's choice.\n get repeatTrackChoices() {\n return self.assemblyTrackChoices.filter(t =>\n REPEAT_ADAPTER_TYPES.has(t.adapterType),\n )\n },\n // The arrays over the window that state a unit, for the Repeat picker.\n get repeatChoices() {\n return self.repeatArrays ?? []\n },\n }))\n .views(self => ({\n get repeatTrack() {\n return pickRepeatTrack(self.repeatTrackChoices, self.repeatTrackId)\n },\n get geneTrack() {\n return pickGeneTrack(self.geneTrackChoices, self.geneTrackId)\n },\n get selectedRepeat() {\n return self.repeatChoices.find(r => r.key === self.repeatKey)\n },\n get backbone() {\n return self.graph ? graphBackbone(self.graph) : undefined\n },\n // Each walk sliced to the window, for walk rows and the strip; a repeat\n // pick slices again by its own array\n get cutWalkRows() {\n return self.graph ? walkRows(self.graph, self.graphRegion) : undefined\n },\n // An assembly by each name a backbone may spell it with: the session's\n // name and aliases, and the PanSN prefix the source track maps each of\n // those to.\n assemblySpellings(assemblyName: string): AssemblyNames {\n const { assemblyManager } = getSession(self)\n const assembly = assemblyManager.has(assemblyName)\n ? assemblyManager.get(assemblyName)\n : undefined\n const panSN = (self.sourceAdapter?.assemblyNameToPanSN ?? {}) as Record<\n string,\n string\n >\n const names = [\n assemblyName,\n ...(assembly ? [assembly.name, ...assembly.aliases] : []),\n ]\n return {\n name: assemblyName,\n aliases: [...names, ...names.flatMap(n => panSN[n] ?? [])],\n }\n },\n // Whether x lies along the reference the track's graph came with, not a\n // walk \"Draw x along\" picked. An rGFA's backbone is fixed.\n get drawsLoadedReference() {\n const graph = self.graph\n return (\n graph?.anchoredBy === 'tags' ||\n (graph?.referencePath !== undefined &&\n graph.referencePath === self.loadedReferencePath)\n )\n },\n }))\n .views(self => ({\n // the assembly the genes were read for\n get geneAssembly() {\n const region = self.graphRegion\n return region ? self.assemblySpellings(region.assemblyName) : undefined\n },\n // the filter of the gene track's lane in the view the pane draws in\n get geneLaneFilter() {\n let view: object\n try {\n view = getContainingView(self)\n } catch {\n return undefined\n }\n const filters = laneFilters(view, self.geneTrack?.trackId)\n return filters.length\n ? new SerializableFilterChain({\n filters,\n jexl: getEnv(self).pluginManager.jexl,\n })\n : undefined\n },\n // the genes over the cut that the lane admits\n get geneFeatures() {\n const features = self.geneTrackFeatures\n const lane = this.geneLaneFilter\n return features\n ? geneModelsFrom(lane ? features.filter(f => lane.passes(f)) : features)\n : undefined\n },\n }))\n .views(self => ({\n // The genes on the drawn backbone under its own refNames. The track's\n // config puts its reference on the cut's assembly, whatever the walk's\n // name. After \"Draw x along\" another walk, the backbone takes the genes\n // only where its PanSN prefix names their assembly.\n get backboneGenes() {\n const { backbone, geneAssembly, geneFeatures } = self\n const binds =\n self.drawsLoadedReference ||\n (geneAssembly !== undefined &&\n backboneAssembly(backbone, [geneAssembly]) !== undefined)\n return backbone && geneFeatures && binds\n ? featuresOnBackbone(geneFeatures, backbone)\n : undefined\n },\n }))\n .views(self => ({\n get nodeNeighbors() {\n return self.drawnGraph ? buildNeighbors(self.drawnGraph) : undefined\n },\n get nodeInk(): NodeInk {\n return nodeInk(\n self.drawnGraph,\n self.nodeById,\n self.contigThickness,\n self.nodeWidth,\n )\n },\n // Links that skip reference sequence, i.e. the deletions this graph\n // holds. Computed once per graph rather than per geometry rebuild: it is\n // a pass over the edges and the drawing rebuilds on every pan.\n // Walk rows state what each walk skips as its own bar length, so the arcs\n // over the backbone would only say it again, across the bars.\n get allDeletions() {\n return self.graph && this.drawsNodes ? deletionEdges(self.graph) : []\n },\n // One bar per haplotype walk on its own bp axis, each with the allele\n // the picked repeat called for it, before the sample filter. Empty under\n // every other layout.\n get cohortWalkRows() {\n if (self.chosenLayoutMode !== 'walkrows' || !self.graph) {\n return undefined\n }\n const repeat = self.selectedRepeat\n const bars = repeat\n ? walkRows(self.graph, repeat, repeat.unit)\n : self.cutWalkRows\n if (!bars) {\n return undefined\n }\n const [reference, ...rows] = withCalls(\n [bars.reference, ...bars.rows],\n repeat?.calls,\n )\n return { ...bars, reference: reference!, rows }\n },\n // The samples walk rows can show, by name, and those with a walk its\n // call disagrees with, longest walk first\n get walkRowSampleChoices() {\n const rows = this.cohortWalkRows?.rows ?? []\n return {\n samples: [...new Set(rows.map(r => r.sample))].sort(),\n disagreeing: [\n ...new Set(\n rows.filter(r => r.call?.agrees === false).map(r => r.sample),\n ),\n ],\n }\n },\n // The source track's samples TSV, where its adapter names one\n get walkRowSamplesTsv(): FileLocation | undefined {\n const location = self.sourceAdapter?.samplesTsvLocation as\n FileLocation | undefined\n return location && (!('uri' in location) || location.uri)\n ? location\n : undefined\n },\n // The sample table's columns walk rows can group by\n get walkRowGroupFields() {\n return metadataColumns(self.walkRowSampleTable)\n },\n // The filtered rows in a section per value of the grouped column, or\n // undefined while ungrouped or the table lacks that column\n get walkRowGroups() {\n const bars = this.cohortWalkRows\n const table = self.walkRowSampleTable\n const groupBy = self.walkRowGroupBy\n return bars &&\n table &&\n groupBy &&\n this.walkRowGroupFields.includes(groupBy.field)\n ? groupWalkRows(\n filterSamples(bars.rows, self.walkRowSamples),\n table,\n groupBy,\n )\n : undefined\n },\n // The bars the overlay draws: the cohort's, narrowed by the sample\n // filter, and stacked section by section while grouped\n get walkRowBars() {\n const bars = this.cohortWalkRows\n return bars\n ? {\n ...bars,\n rows:\n this.walkRowGroups?.rows ??\n filterSamples(bars.rows, self.walkRowSamples),\n }\n : undefined\n },\n // Whether the canvas draws the graph's nodes. A tube map and walk rows\n // draw a picture of their own over it, so what sits on nodes (genes,\n // bubble halos, deletion arcs, the reference strip) has nowhere to go.\n // Read off what was drawn rather than the mode asked for, which falls\n // back to the force layout on a graph it cannot draw.\n get drawsNodes() {\n return !self.layoutResult?.tubeMap && !this.walkRowBars\n },\n // Exons and names on the nodes that carry them, in layout units. Reads\n // positionsVersion so a dragged node takes its exons with it.\n get genePins() {\n dependOn(self.positionsVersion)\n const positions = self.layoutResult?.nodePositions\n return self.showGenes &&\n this.drawsNodes &&\n self.graph &&\n self.backboneGenes &&\n positions\n ? genePins(self.graph, self.backboneGenes, positions)\n : []\n },\n // The bubbles as halos along their nodes.\n // Reads positionsVersion so a dragged node takes its halo with it.\n get bubbleHalos() {\n dependOn(self.positionsVersion)\n const positions = self.layoutResult?.nodePositions\n if (!self.showBubbles || !this.drawsNodes || !self.graph || !positions) {\n return []\n }\n return bubbleHalos(\n self.graph,\n self.bubbles,\n positions,\n name => self.walkLabel(name),\n self.repeatArrays,\n )\n },\n // Every node's midpoint on the reference plus the interval the hue ramps\n // over \u2014 what `reference-position` paints from, and undefined under every\n // other scheme so the walk is never run for a colouring that ignores it.\n //\n // Here for the same reason `deletions` is, only more so: deriving it is a\n // bounded neighbour walk PER NODE (referenceMidpoints), it depends on\n // nothing the transform touches, and it was being redone inside every\n // geometry rebuild \u2014 1.6 ms at 1.5k nodes, 45 ms at 30k, on a pass that\n // reruns on each debounced pan and each drag frame. `reference-position`\n // is also what `auto` resolves to on any anchored graph, so this was the\n // default path rather than an opt-in one.\n //\n // On the drawn graph, whose ids a folded tube map's boxes carry\n get referenceRamp() {\n return self.effectiveColorScheme === 'reference-position' &&\n self.drawnGraph\n ? computeReferenceRamp(self.drawnGraph, self.rampDomain)\n : undefined\n },\n // The assemblies this view is showing, which is the interface every\n // assembly-aware piece of the app looks for \u2014 `viewTitle` first among\n // them, which falls back through it and otherwise names the view\n // \"Untitled view\". Every published HPRC figure showed that.\n // `launchSubgraphView` only avoids it by writing `displayName`, so a\n // declaratively-instantiated view (a session snapshot, a figure spec) got\n // the fallback.\n //\n // A whole-file import has none: its stable names are a GFA's business and\n // need not name anything the session has loaded. Empty rather than\n // undefined, matching what an LGV with no displayed regions reports.\n get assemblyNames() {\n const region = self.graphRegion\n return region ? [region.assemblyName] : []\n },\n // Screen px per layout unit, per axis. `scale` is the x zoom and the whole\n // of what a user's wheel moves; y is a second question the layout answers\n // for itself.\n //\n // On a row layout the pitch is already in screen px (rowSpacing.ts), so\n // scaleY is 1 and stays 1: rows are a track's row height, unchanged by\n // zoom, and the backbone under them zooms the way the ruler above it does.\n // On an isotropic layout (FMMM) x and y are one simulation space and one\n // number scales both, exactly as before.\n //\n // Everything that mixes the two axes takes their ratio as `yToX`\n // (scaleY / scaleX) \u2014 see computeEdgeCurves.\n get scaleX() {\n return axisScaleOf(self.scale, self.pixelRows).scaleX\n },\n get scaleY() {\n return axisScaleOf(self.scale, self.pixelRows).scaleY\n },\n // The pair, for everything that draws or hit-tests. Handed over as one\n // value on purpose: every consumer needs both, and passing them separately\n // let a caller supply the x scale and default y, which compiles and draws\n // a wrong picture. See AxisScale.\n get axisScale() {\n return axisScaleOf(self.scale, self.pixelRows)\n },\n }))\n .views(self => ({\n get deletionDrawing() {\n return self.graph\n ? deletionDrawing(self.graph, self.allDeletions, self.showDeletionEdges)\n : undefined\n },\n // the deletions drawn, which their labels and hover name\n get deletions() {\n return this.deletionDrawing?.shown ?? []\n },\n get deletionEdgeIndexes() {\n return this.deletionDrawing?.bypassed\n },\n get hiddenEdgeIndexes() {\n return this.deletionDrawing?.hidden\n },\n // The interval the reference-position ramp runs over, for the key beside\n // the drawing, and undefined when no key should be drawn. Two tutorials\n // carry \"red to magenta is left to right of the cut window\" as a sentence\n // in prose because nothing on screen said it.\n //\n // Read off the ramp the drawing is actually painted with rather than\n // re-derived from the domain, so the key cannot come to describe a\n // different interval from the hues beside it \u2014 and so a graph that states\n // no domain, whose interval has to be measured, does not pay for a second\n // neighbour walk to say what the first one already worked out.\n get referenceRampDomain() {\n const ramp = self.referenceRamp\n return ramp\n ? { start: ramp.start, end: ramp.start + ramp.span }\n : undefined\n },\n // The ramp's two colours for nodes off it, as getNodeColor paints them:\n // charcoal where an rGFA rank puts a node off the reference, grey where\n // a node has no reference position at all. A tube map draws the window\n // alone (trimToWindow), so there only the boxes it drew count.\n get referenceRampOffKeys() {\n const ramp = self.referenceRamp\n const layout = self.layoutResult\n const drawn = layout?.tubeMap ? layout.nodePositions : undefined\n let offReference = false\n let unplaced = false\n if (ramp && self.drawnGraph) {\n for (const node of self.drawnGraph.nodes) {\n if (drawn && !drawn[node.id]) {\n continue\n }\n if (!ramp.midpoints.has(node.id)) {\n unplaced = true\n } else if (node.stable && node.stable.rank > 0) {\n offReference = true\n }\n }\n }\n return { offReference, unplaced }\n },\n // Each tube map box in its node's colour, where the scheme paints one\n get tubeMapNodeColors() {\n const graph = self.drawnGraph\n return self.layoutResult?.tubeMap && graph\n ? tubeMapNodeColors(\n graph,\n self.effectiveColorScheme,\n self.referenceRamp,\n )\n : undefined\n },\n // Beside tinted boxes the tubes step through greys, as they do beside\n // reads, so no tube shares a box's hue\n get tubeMapTubeColors() {\n const colors = self.layoutResult?.tubeMap?.pathColors\n const tubes =\n colors && this.tubeMapNodeColors\n ? colors.map((_, i) => pathGreyCssColor(i, colors.length))\n : colors\n const hovered = new Set(self.hoveredRowWalks)\n const paths = self.drawnGraph?.paths\n return tubes && paths && hovered.size > 0\n ? tubes.map((color, i) =>\n hovered.has(paths[i]?.name ?? '') ? color : LIFT_BACKDROP_CSS,\n )\n : tubes\n },\n // A node's reference interval, an allele's between its flanks\n nodeSpan(nodeId: string) {\n const { nodeById, nodeNeighbors: neighbors } = self\n return nodeById && neighbors\n ? nodeReferenceSpan({ nodeId, nodeById, neighbors })\n : undefined\n },\n }))\n .views(self => ({\n // Which haplotype each ribbon colour belongs to, in the order the file\n // states the paths \u2014 the same list and the same order the geometry keys\n // its colours off, so the key cannot name a colour that is not drawn.\n // Empty unless the ribbons are actually on: a colour key beside a drawing\n // with no colours in it is a legend for nothing.\n // The tube map colours its tubes whether or not paths are drawn on the\n // nodes, so under it the key follows the tubes, and names the colours\n // the tubes were drawn in.\n get pathLegend() {\n const paths = self.graph?.paths\n const tubeMap = self.layoutResult?.tubeMap\n const colouring = self.drawPaths || tubeMap\n return colouring && paths && pathColorsLegible(paths.length)\n ? pathLegend(paths, self.tubeMapTubeColors)\n : []\n },\n // The reference interval under the pointer: the hovered node's, or the\n // hovered bubble's\n get hoveredSpan() {\n const nodeId = self.hoveredNode\n const bubble = self.hoveredBubble\n return nodeId !== null\n ? self.nodeSpan(nodeId)\n : bubble\n ? { start: bubble.start, end: bubble.end }\n : undefined\n },\n }))\n .views(self => ({\n // The hovered span, for a connected linear view to highlight. Only a\n // graph cut from a track has one: a whole-file import has no region, and\n // its stable names need not name anything in a loaded assembly.\n get hoverHighlight() {\n const region = self.graphRegion\n const span = self.hoveredSpan\n return region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n ...span,\n }\n : undefined\n },\n }))\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getSession } from '@jbrowse/core/util'\n\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nexport interface AssemblyAliases {\n name: string\n aliases: string[]\n}\n\n// Only `sample#haplotype`, the spelling gbz-base gives a walk's prefix. A bare\n// alias is indistinguishable from an ordinary one (hg38's `GRCh38`) and would\n// replace the identity mapping that already resolves an assembly named as its\n// sample; at sample depth it would also claim both of a diploid's walks, since\n// `panSNMatchesPrefix` matches `HG002` against `HG002#1` and `HG002#2`. Three\n// parts name a contig, not a haplotype.\nconst PANSN_HAPLOTYPE = /^[^#]+#\\d+$/\n\n// The config's `assemblyNameToPanSN` with each assembly's PanSN alias added\n// beneath it: an entry wins for its assembly and for its prefix. Unchanged when\n// no alias qualifies, so such a track keeps its adapter cache key.\nexport function withPanSNAliases(\n adapterConfig: Record<string, unknown>,\n assemblies: AssemblyAliases[],\n) {\n const explicit = (adapterConfig.assemblyNameToPanSN ?? {}) as Record<\n string,\n string\n >\n const claimed = new Set(Object.values(explicit))\n const fromAliases: Record<string, string> = {}\n for (const { name, aliases } of assemblies) {\n const prefix = aliases.find(alias => PANSN_HAPLOTYPE.test(alias))\n if (prefix !== undefined && !claimed.has(prefix)) {\n fromAliases[name] = prefix\n }\n }\n return Object.keys(fromAliases).length === 0\n ? adapterConfig\n : {\n ...adapterConfig,\n assemblyNameToPanSN: { ...fromAliases, ...explicit },\n }\n}\n\n/**\n * A track's adapter config as its requests carry it. A worker has no assembly\n * manager, so a gbz-base track's lanes learn the session's PanSN aliases here.\n */\nexport function trackAdapterConfig(\n node: IAnyStateTreeNode,\n track: AnyConfigurationModel,\n) {\n const adapterConfig = readConfObject(track, 'adapter') as Record<\n string,\n unknown\n >\n return adapterConfig.type === 'GbzBaseSyntenyAdapter'\n ? withPanSNAliases(\n adapterConfig,\n getSession(node).assemblyManager.assemblyList.map(conf => ({\n name: readConfObject(conf, 'name') as string,\n aliases: (readConfObject(conf, 'aliases') ?? []) as string[],\n })),\n )\n : adapterConfig\n}\n", "// src/genes/geneFiles.ts\nvar GENE_TYPE = /(gene|gene_segment|RNA|transcript)$/i;\nvar isGene = (type) => GENE_TYPE.test(type) || type === \"CDS\" || type === \"exon\";\nfunction mergedIntervals(intervals) {\n const out = [];\n for (const iv of [...intervals].sort((a, b) => a.start - b.start)) {\n const last = out.at(-1);\n if (last && iv.start <= last.end) {\n last.end = Math.max(last.end, iv.end);\n } else {\n out.push({ ...iv });\n }\n }\n return out;\n}\nfunction strandOf(s) {\n return s === \"+\" ? 1 : s === \"-\" ? -1 : 0;\n}\nfunction unescape(value) {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\nfunction attributes(column) {\n const out = /* @__PURE__ */ new Map();\n for (const pair of column.split(\";\")) {\n const eq = pair.indexOf(\"=\");\n if (eq > 0) {\n out.set(pair.slice(0, eq).trim(), unescape(pair.slice(eq + 1).trim()));\n }\n }\n return out;\n}\nfunction gff3Row(line) {\n const cols = line.split(\"\t\");\n const start = Number(cols[3]);\n const end = Number(cols[4]);\n if (cols.length < 9 || !Number.isInteger(start) || !Number.isInteger(end)) {\n return void 0;\n }\n return {\n refName: cols[0],\n type: cols[2],\n start: start - 1,\n end,\n strand: strandOf(cols[6]),\n attrs: attributes(cols[8])\n };\n}\nfunction genesFromGff3Lines(lines) {\n const rows = [];\n for (const line of lines) {\n if (line.startsWith(\"##FASTA\")) {\n break;\n }\n const row = line.startsWith(\"#\") ? void 0 : gff3Row(line);\n if (row) {\n rows.push(row);\n }\n }\n const parentOf = /* @__PURE__ */ new Map();\n for (const { attrs } of rows) {\n const id = attrs.get(\"ID\");\n const parent = attrs.get(\"Parent\")?.split(\",\")[0];\n if (id && parent) {\n parentOf.set(id, parent);\n }\n }\n const rootOf = (row) => {\n let id = row.attrs.get(\"Parent\")?.split(\",\")[0] ?? row.attrs.get(\"ID\");\n if (!id) {\n return row.attrs.get(\"gene_id\");\n }\n const seen = /* @__PURE__ */ new Set();\n while (id && parentOf.has(id) && !seen.has(id)) {\n seen.add(id);\n id = parentOf.get(id);\n }\n return id;\n };\n const groups = /* @__PURE__ */ new Map();\n rows.forEach((row, i) => {\n const root = rootOf(row) ?? `#${i}`;\n const key = `${row.refName}\t${root}`;\n const group = groups.get(key) ?? groups.set(key, { rows: [] }).get(key);\n group.rows.push(row);\n if (!row.attrs.has(\"Parent\") && !group.top) {\n group.top = row;\n }\n });\n const genes = [];\n for (const [key, { top, rows: rows2 }] of groups) {\n if (top && !isGene(top.type)) {\n continue;\n }\n const first = top ?? rows2[0];\n const start = top?.start ?? Math.min(...rows2.map((r) => r.start));\n const end = top?.end ?? Math.max(...rows2.map((r) => r.end));\n const a = first.attrs;\n const spans = (type) => rows2.filter((r) => r.type === type).map((r) => ({ start: r.start, end: r.end }));\n const exons = spans(\"exon\");\n const coding = spans(\"CDS\");\n const transcribed = rows2.some(\n (r) => r !== top && r.type !== \"exon\" && r.type !== \"CDS\"\n );\n genes.push({\n name: a.get(\"Name\") ?? a.get(\"gene_name\") ?? a.get(\"gene\") ?? a.get(\"gene_id\") ?? key.split(\"\t\")[1],\n refName: first.refName,\n start,\n end,\n strand: first.strand,\n // A range read holds only the rows over its window, so a gene with\n // transcripts but no exon or CDS there is intronic in it. Only a gene\n // with no transcripts, as a bacterium's gene and CDS, is one exon.\n exons: exons.length ? mergedIntervals(exons) : transcribed ? mergedIntervals(coding) : [{ start, end }]\n });\n }\n return genes;\n}\nfunction mergeOverlappingByName(genes) {\n const out = [];\n const open = /* @__PURE__ */ new Map();\n for (const g of [...genes].sort((a, b) => a.start - b.start)) {\n const key = `${g.refName}\t${g.strand}\t${g.name}`;\n const last = open.get(key);\n if (last && g.start < last.end) {\n last.end = Math.max(last.end, g.end);\n last.exons = mergedIntervals([...last.exons, ...g.exons]);\n } else {\n const gene = { ...g, exons: mergedIntervals(g.exons) };\n out.push(gene);\n open.set(key, gene);\n }\n }\n return out;\n}\nfunction genesFromBed(text) {\n const rows = [];\n for (const line of text.split(\"\\n\")) {\n const cols = line.replace(/\\r$/, \"\").split(\"\t\");\n const start = Number(cols[1]);\n const end = Number(cols[2]);\n if (/^(#|track|browser)/.test(line) || cols.length < 3 || !Number.isInteger(start) || !(end > start)) {\n continue;\n }\n const refName = cols[0];\n const name = cols[3] && cols[3] !== \".\" ? cols[3] : `${refName}:${start + 1}-${end}`;\n const sizes = cols[10]?.split(\",\").filter((s) => s !== \"\").map(Number);\n const starts = cols[11]?.split(\",\").filter((s) => s !== \"\").map(Number);\n const blocks = sizes?.length && sizes.length === starts?.length ? sizes.map((size, i) => ({\n start: start + starts[i],\n end: start + starts[i] + size\n })) : [{ start, end }];\n rows.push({\n name,\n refName,\n start,\n end,\n strand: strandOf(cols[5]),\n exons: blocks\n });\n }\n return mergeOverlappingByName(rows);\n}\nfunction genesFromText(text) {\n const first = text.split(\"\\n\", 1e3).find((l) => l.trim() !== \"\" && !/^(#|track|browser)/.test(l));\n const cols = first?.split(\"\t\") ?? [];\n return /^\\d+$/.test(cols[1] ?? \"\") && /^\\d+$/.test(cols[2] ?? \"\") ? genesFromBed(text) : genesFromGff3Lines(text.split(/\\r?\\n/));\n}\n\nexport {\n mergedIntervals,\n genesFromGff3Lines,\n mergeOverlappingByName,\n genesFromBed,\n genesFromText\n};\n", "import { mergeOverlappingByName } from '@jbrowse/bandage-core/genes/geneFiles'\nimport { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { Feature } from '@jbrowse/core/util'\n\n// The adapters whose tracks hold gene models, in the order the session's\n// tracks are searched when no track is named.\nexport const GENE_ADAPTER_TYPES = new Set([\n 'Gff3TabixAdapter',\n 'Gff3Adapter',\n 'BedTabixAdapter',\n 'BedAdapter',\n 'GtfTabixAdapter',\n 'GtfAdapter',\n 'BigBedAdapter',\n 'NCListAdapter',\n])\n\nconst GENE_TRACK_HINT = /gene|refseq|gencode|ensembl|annotation/i\n\n// A BED track is as often peaks or repeats as genes, so one counts only where\n// its name says it is annotation\nconst BED_ADAPTER_TYPES = new Set(['BedTabixAdapter', 'BedAdapter'])\n\n// Which of the session's tracks to read genes from: the named one, else the\n// first gene-bearing track on the assembly whose name says it is annotation,\n// else the first non-BED gene-bearing track.\nexport function pickGeneTrack<\n T extends { trackId: string; name?: string; adapterType: string },\n>(tracks: T[], named: string) {\n if (named) {\n return tracks.find(t => t.trackId === named)\n }\n const candidates = tracks.filter(t => GENE_ADAPTER_TYPES.has(t.adapterType))\n return (\n candidates.find(t =>\n GENE_TRACK_HINT.test(`${t.trackId} ${t.name ?? ''}`),\n ) ?? candidates.find(t => !BED_ADAPTER_TYPES.has(t.adapterType))\n )\n}\n\ninterface LaneView {\n tracks?: readonly {\n configuration: AnyConfigurationModel\n displays: readonly { configuration: AnyConfigurationModel }[]\n }[]\n}\n\n// The `filter` of the gene track's lane in the view the graph is drawn in, so\n// the chips name what the lane draws. None where the view shows no such lane,\n// or has no tracks, as a graph genome view of its own.\nexport function laneFilters(view: object, trackId: string | undefined) {\n const lane = (view as LaneView).tracks?.find(\n t => readConfObject(t.configuration, 'trackId') === trackId,\n )?.displays[0]\n return lane\n ? ((readConfObject(lane.configuration, 'filter') as string[] | undefined) ??\n [])\n : []\n}\n\n// Records spanning a whole sequence, the types the GFF3 adapter declines to\n// widen a fetch for. RefSeq opens every molecule with a `region` named\n// ANONYMOUS.\nconst WHOLE_SEQUENCE_TYPES = new Set([\n 'chromosome',\n 'region',\n 'contig',\n 'supercontig',\n 'scaffold',\n])\n\ntype FeatureLike = Feature | Record<string, unknown>\n\nfunction field(f: FeatureLike, name: string): unknown {\n return typeof (f as Feature).get === 'function'\n ? (f as Feature).get(name)\n : (f as Record<string, unknown>)[name]\n}\n\n// JBrowse's BED parser splits a coding BED12 block into CDS and UTR parts and\n// keeps `exon` for non-coding ones, so all of them are exon\nconst EXON_PARTS = new Set([\n 'exon',\n 'CDS',\n 'five_prime_UTR',\n 'three_prime_UTR',\n 'UTR',\n])\n\nfunction exonsOf(f: FeatureLike, into: { start: number; end: number }[]) {\n const type = field(f, 'type')\n if (typeof type === 'string' && EXON_PARTS.has(type)) {\n into.push({\n start: field(f, 'start') as number,\n end: field(f, 'end') as number,\n })\n }\n const children = field(f, 'subfeatures') as FeatureLike[] | undefined\n for (const child of children ?? []) {\n exonsOf(child, into)\n }\n}\n\nfunction merged(intervals: { start: number; end: number }[]) {\n const sorted = [...intervals].sort((a, b) => a.start - b.start)\n const out: { start: number; end: number }[] = []\n for (const iv of sorted) {\n const last = out.at(-1)\n if (last && iv.start <= last.end) {\n last.end = Math.max(last.end, iv.end)\n } else {\n out.push({ ...iv })\n }\n }\n return out\n}\n\n// Genes from a track's features: every top-level feature but a whole-sequence\n// record, named by the first of gene_name, name, gene and gene_id it carries,\n// with the exons found anywhere under it merged. A feature with no exons is one exon,\n// its whole span. A BED track gives one feature per transcript, so a name's\n// overlapping features merge, while its copies down the contig stay apart.\n// UCSC's ncbiRefSeq.gff gene records carry their symbol only as gene_id. A\n// feature with none of those names is left out: its raw ID, RefSeq's\n// `id-NC_000913.3:1978503..1979270`, only restates where it is.\nexport function geneModelsFrom(features: FeatureLike[]): GeneModel[] {\n const genes: GeneModel[] = []\n for (const f of features) {\n const name =\n (field(f, 'gene_name') as string | undefined) ??\n (field(f, 'name') as string | undefined) ??\n (field(f, 'gene') as string | undefined) ??\n (field(f, 'gene_id') as string | undefined)\n const start = field(f, 'start') as number\n const end = field(f, 'end') as number\n if (\n !name ||\n !(end > start) ||\n WHOLE_SEQUENCE_TYPES.has(field(f, 'type') as string)\n ) {\n continue\n }\n const exons: { start: number; end: number }[] = []\n exonsOf(f, exons)\n genes.push({\n name,\n refName: field(f, 'refName') as string,\n start,\n end,\n strand: (field(f, 'strand') as number | undefined) ?? 0,\n exons: exons.length ? merged(exons) : [{ start, end }],\n })\n }\n return mergeOverlappingByName(genes)\n}\n", "import type { Feature } from '@jbrowse/core/util'\n\nexport interface RepeatCall {\n bp: number\n // TRGT's `SD`. Zero means the allele is a copy of the one the reads did\n // support, so its length states nothing about a second haplotype; absent\n // where the genotyper writes no such field.\n spanningReads?: number\n // the PanSN haplotype a phased genotype puts this allele on\n haplotype?: number\n}\n\n// A tandem repeat array as the walk rows need it: its span on the reference,\n// which is what the bars measure between, and its unit length, which is what\n// they tile by. Read off whatever repeat annotation the session has, since the\n// tools all state the same two facts under different names: VCF 4.5's\n// `<CNV:TR>` allele gives `RUL` and `RUS` (one entry per repeat sequence,\n// grouped by `RN`), UCSC simpleRepeat and TRF give `period` and the consensus\n// `sequence`, TRGT gives `MOTIFS` and `TRID`, ExpansionHunter `RU` and `REPID`,\n// HipSTR and GangSTR `PERIOD`, vamos its `motifs`. A VCF record's INFO is\n// searched as well as its top level, and a list's first entry is the unit the\n// bars tile by: for a compound array that is the first repeat sequence, which\n// is the expanding one at every such locus in the common catalogues.\nexport interface RepeatArray {\n key: string\n name: string\n refName: string\n start: number\n end: number\n unit: number\n motif?: string\n // Each sample's genotyped alleles, from a genotyper's per-sample `AL`\n // (TRGT) or a genotype over VCF 4.5 <CNV:TR> alleles; absent from a\n // catalogue.\n calls?: Record<string, RepeatCall[]>\n}\n\nexport const REPEAT_ADAPTER_TYPES = new Set([\n 'BedAdapter',\n 'BedTabixAdapter',\n 'BigBedAdapter',\n 'VcfAdapter',\n 'VcfTabixAdapter',\n])\n\nconst REPEAT_TRACK_HINT =\n /repeat|tandem|\\bstr\\b|vntr|trf|trgt|vamos|expansion|microsat/i\n\nexport function pickRepeatTrack<\n T extends { trackId: string; name?: string; adapterType: string },\n>(tracks: T[], named: string) {\n if (named) {\n return tracks.find(t => t.trackId === named)\n }\n const candidates = tracks.filter(t => REPEAT_ADAPTER_TYPES.has(t.adapterType))\n return candidates.find(t =>\n REPEAT_TRACK_HINT.test(`${t.trackId} ${t.name ?? ''}`),\n )\n}\n\ntype FeatureLike = Feature | Record<string, unknown>\n\nfunction own(f: FeatureLike, name: string): unknown {\n return typeof (f as Feature).get === 'function'\n ? (f as Feature).get(name)\n : (f as Record<string, unknown>)[name]\n}\n\n// A TRGT repeat catalogue is a BED whose name column packs the record:\n// `ID=HTT;MOTIFS=CAG,CCG;STRUC=(CAG)nCAACAG(CCG)n`. Read as fields when it\n// has that shape.\nconst PACKED_NAME = /^\\w+=[^;]*(;\\w+=[^;]*)*$/\n\nfunction packedName(f: FeatureLike) {\n const name = own(f, 'name')\n if (typeof name !== 'string' || !PACKED_NAME.test(name)) {\n return undefined\n }\n return Object.fromEntries(\n name.split(';').map(pair => {\n const i = pair.indexOf('=')\n return [pair.slice(0, i), pair.slice(i + 1)]\n }),\n )\n}\n\n// A field at the feature's top level, in a VCF record's INFO, or in a packed\n// name column, in that order.\nfunction field(f: FeatureLike, name: string): unknown {\n const top = own(f, name)\n if (top !== undefined) {\n return top\n }\n const info = own(f, 'INFO') as Record<string, unknown> | undefined\n return info?.[name] ?? packedName(f)?.[name]\n}\n\nconst MOTIF_FIELDS = [\n 'RUS',\n 'MOTIFS',\n 'RU',\n 'motifs',\n 'motif',\n 'sequence',\n 'consensus',\n]\nconst PERIOD_FIELDS = [\n 'RUL',\n 'period',\n 'PERIOD',\n 'consensusSize',\n 'unit',\n 'unitLength',\n]\nconst NAME_FIELDS = ['TRID', 'REPID', 'VARID', 'ID', 'name', 'id']\n\n// The first entry of a list-valued field, whether it arrived parsed or as\n// the comma-joined text a VCF INFO or a BED column holds; VCF's missing \".\"\n// counts as absent.\nfunction first(f: FeatureLike, names: string[]) {\n for (const name of names) {\n const value = field(f, name)\n const one = String((Array.isArray(value) ? value[0] : value) ?? '')\n .split(',')[0]!\n .trim()\n if (one !== '' && one !== '.') {\n return one\n }\n }\n return undefined\n}\n\nconst IUPAC = /^[ACGTURYSWKMBDHVN]+$/i\n\n// The unit in bp: a stated period, else the length of the first motif.\nexport function repeatUnitOf(f: FeatureLike) {\n const period = Number(first(f, PERIOD_FIELDS))\n if (Number.isFinite(period) && period > 0) {\n return Math.round(period)\n }\n const motif = first(f, MOTIF_FIELDS)\n return motif && IUPAC.test(motif) ? motif.length : undefined\n}\n\n// A per-sample list field, parsed or as the comma-joined text a VCF column\n// holds. A missing entry stays missing: read as 0, an absent `SD` would make\n// every allele of every genotyper that writes no such field unspanned.\nfunction numbers(value: unknown) {\n const raw: unknown[] = Array.isArray(value)\n ? value\n : String(value ?? '').split(',')\n return raw.map(one => {\n const n =\n one === '' || one === null || one === undefined ? NaN : Number(one)\n return Number.isFinite(n) ? n : undefined\n })\n}\n\nfunction strings(value: unknown) {\n const raw: unknown[] = Array.isArray(value)\n ? value\n : String(value ?? '').split(',')\n return raw.map(one => {\n const text = String(one ?? '').trim()\n return text === '' || text === '.' ? undefined : text\n })\n}\n\nconst TANDEM_REPEAT = '<CNV:TR>'\n\n// Each ALT allele's length, off VCF 4.5's flattened list-of-lists: RN says how\n// many RUS/RUL/RUC/RB entries each allele takes, and the allele's bases are\n// its runs' RB, or unit length times count where RB is missing. An allele that\n// is not <CNV:TR>, or has a run stating neither, has none.\nfunction tandemAlleleBp(f: FeatureLike) {\n const alts = strings(own(f, 'ALT'))\n if (!alts.includes(TANDEM_REPEAT)) {\n return undefined\n }\n const rn = numbers(field(f, 'RN'))\n const rus = strings(field(f, 'RUS'))\n const rul = numbers(field(f, 'RUL'))\n const ruc = numbers(field(f, 'RUC'))\n const rb = numbers(field(f, 'RB'))\n let k = 0\n return alts.map((alt, i) => {\n const n = rn[i] ?? (alt === TANDEM_REPEAT ? 1 : 0)\n let bp = 0\n let known = 0\n for (let j = 0; j < n; j++, k++) {\n const motif = rus[k]\n const unitLength =\n rul[k] ?? (motif && IUPAC.test(motif) ? motif.length : undefined)\n const count = ruc[k]\n const runBp =\n rb[k] ??\n (unitLength && count !== undefined\n ? Math.round(unitLength * count)\n : undefined)\n if (runBp !== undefined) {\n bp += runBp\n known++\n }\n }\n return alt === TANDEM_REPEAT && n > 0 && known === n ? bp : undefined\n })\n}\n\n// A sample's alleles through its genotype: 0 is the reference's, an index\n// past it the ALT allele's. A phased genotype's k-th allele is PanSN\n// haplotype k, the order vg deconstruct writes an assembly's haplotypes in.\nfunction genotyped(\n gt: string | undefined,\n alleleBp: (number | undefined)[],\n referenceBp: number,\n) {\n const phased = gt?.includes('|')\n return (gt ?? '').split(/[/|]/).flatMap((index, k): RepeatCall[] => {\n const i = Number(index)\n const bp = i > 0 ? alleleBp[i - 1] : referenceBp\n if (!Number.isInteger(i) || bp === undefined) {\n return []\n }\n return [{ bp, ...(phased ? { haplotype: k + 1 } : {}) }]\n })\n}\n\nfunction callsOf(\n f: FeatureLike,\n alleleBp: (number | undefined)[] | undefined,\n referenceBp: number,\n) {\n const samples = own(f, 'samples') as\n Record<string, Record<string, unknown>> | undefined\n const called: Record<string, RepeatCall[]> = {}\n for (const [sample, fields] of Object.entries(samples ?? {})) {\n const reads = numbers(fields.SD)\n const lengths = numbers(fields.AL).flatMap((bp, i) =>\n bp !== undefined && bp > 0\n ? [reads[i] === undefined ? { bp } : { bp, spanningReads: reads[i] }]\n : [],\n )\n const calls =\n lengths.length > 0 || !alleleBp\n ? lengths\n : genotyped(strings(fields.GT)[0], alleleBp, referenceBp)\n if (calls.length > 0) {\n called[sample] = calls\n }\n }\n return Object.keys(called).length > 0 ? called : undefined\n}\n\n// A <CNV:TR> record's POS is the base before the array and SVLEN the\n// reference allele's length, while a VCF feature starts at that padding base.\nfunction spanOf(f: FeatureLike, tandem: boolean) {\n const start = field(f, 'start') as number\n const end = field(f, 'end') as number\n const svlen = numbers(field(f, 'SVLEN'))[0]\n return tandem && svlen !== undefined\n ? { start: start + 1, end: start + 1 + svlen }\n : { start, end }\n}\n\nexport function repeatArraysFrom(features: FeatureLike[]): RepeatArray[] {\n const arrays: RepeatArray[] = []\n for (const f of features) {\n const alleleBp = tandemAlleleBp(f)\n const { start, end } = spanOf(f, alleleBp !== undefined)\n const unit = repeatUnitOf(f)\n if (!(end > start) || unit === undefined) {\n continue\n }\n const refName = field(f, 'refName') as string\n const motif = first(f, MOTIF_FIELDS)\n const stated = first(f, NAME_FIELDS)\n arrays.push({\n key: `${refName}:${start}-${end}`,\n name:\n (stated && !PACKED_NAME.test(stated) ? stated : undefined) ??\n (motif && motif.length <= 12\n ? `(${motif})n`\n : `${refName}:${(start + 1).toLocaleString()}-${end.toLocaleString()}`),\n refName,\n start,\n end,\n unit,\n motif,\n calls: callsOf(f, alleleBp, end - start),\n })\n }\n return arrays.sort((a, b) => a.start - b.start)\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport { locLabel, locString } from './contributors'\nimport { linearViewTarget } from './linearViewTarget'\n\nimport type { Contributor, GraphLocation } from './contributors'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface TrackScanSession {\n tracks: AnyConfigurationModel[]\n assemblies: AnyConfigurationModel[]\n // optional, as a hand-built session in a test has none\n assemblyManager?: {\n has: (name: string) => boolean\n get: (name: string) => { name: string } | undefined\n }\n}\n\n// A track may name an assembly by an alias, and contributors are resolved to\n// canonical names. `has` before `get`, as assemblyResolver does: `get` asks\n// every plugin to go supply a name it does not know.\nexport function canonicalAssemblyName(session: TrackScanSession, name: string) {\n const manager = session.assemblyManager\n return manager?.has(name) ? (manager.get(name)?.name ?? name) : name\n}\n\nexport interface GraphLaunchSession extends TrackScanSession {\n addView: (type: string, snapshot?: Record<string, unknown>) => { id: string }\n // The session's own loader for a view whose state model is registered\n // lazily (JBrowse 4's LinearSyntenyView); absent on an older core, where\n // addView is enough\n launchView?: (\n type: string,\n snapshot?: Record<string, unknown>,\n ) => Promise<{ id: string }>\n assemblyNames: string[]\n views: unknown[]\n // optional, as a hand-built session in a test has none\n notifyError?: (message: string, error?: unknown) => void\n // a highlight every linear view on its assembly draws\n addHighlight?: (highlight: {\n refName: string\n start: number\n end: number\n assemblyName: string\n }) => void\n}\n\n// A launch is a promise nothing waits on. Let go, a refusal moved nothing and\n// said nothing; this is where it is told to the user instead.\nfunction reportFailure(\n session: GraphLaunchSession,\n what: string,\n launch: Promise<unknown>,\n) {\n launch.catch((error: unknown) => {\n console.error(`[GraphGenomeView] ${what}`, error)\n session.notifyError?.(`${what}: ${error}`, error)\n })\n}\n\n// A node is often shorter than a line of text \u2014 a base-level allele can be a\n// handful of bp \u2014 and a linear view opened on exactly that span shows the span\n// and no context at all. Padding to a minimum window puts the node in the middle\n// of something readable.\nconst MIN_LAUNCH_SPAN_BP = 1000\n\nexport function paddedLocation(\n loc: GraphLocation,\n minSpan = MIN_LAUNCH_SPAN_BP,\n): GraphLocation {\n const pad = Math.max(0, Math.ceil((minSpan - (loc.end - loc.start)) / 2))\n return { ...loc, start: Math.max(0, loc.start - pad), end: loc.end + pad }\n}\n\n// Restate the rank-0 contributor in the terms of the region the graph was cut\n// from. Two separate corrections, both required:\n//\n// - the *assembly*. A backbone segment's SN is the graph's own spelling of the\n// reference, which need not be the name of any loaded assembly: the HPRC\n// graph says `GRCh38#0#chr6` in a session whose assembly is `hg38`. Taking\n// the PanSN sample there resolves to nothing and the graph offers no way out\n// at all. The cut region is authoritative \u2014 the adapter resolved that\n// assembly to that stable sequence to cut the subgraph in the first place.\n// The backbone's `haplotype` (`GRCh38#0`) goes with it, since\n// resolveLocationAssembly tries that before the sample.\n// - the *locus*. The cut region is what the user framed in the linear view, and\n// it is the span every other panel of a synteny launch is compared against;\n// the union of backbone segments differs from it whenever the window ends\n// inside a bubble.\n//\n// A subgraph is cut on one reference, so there is at most one rank-0\n// contributor. Must run before contributors are resolved against the session's\n// assemblies, or the reference is filtered out by the name this replaces.\nexport function withReferenceRegion(\n contributors: Contributor[],\n region:\n | { refName: string; assemblyName: string; start: number; end: number }\n | undefined,\n): Contributor[] {\n return region\n ? contributors.map(c =>\n c.rank === 0\n ? {\n ...c,\n sample: region.assemblyName,\n haplotype: undefined,\n refName: region.refName,\n start: region.start,\n end: region.end,\n }\n : c,\n )\n : contributors\n}\n\n// Show a location in a linear view: move the one already on screen if there is\n// one to move, open a pane only if there isn't.\n//\n// This is the difference between \"flip to the linear view\" and \"accumulate\n// panes\". The pangenome sessions this ships in are a linear view above a graph,\n// and there the answer to \"where is this node?\" should be that the linear view\n// scrolls to it \u2014 see linearViewTarget for which view counts as the one to move.\n//\n// `tracks` is only applied to a view being created; a view already open keeps\n// whatever the user has turned on. Returns the id of the view that ended up\n// showing the location, so the graph can pair with it for the hover sync.\nexport function showInLinearView({\n session,\n location,\n assembly,\n connectedViewId,\n tracks = [],\n}: {\n session: GraphLaunchSession\n location: GraphLocation\n assembly: string\n connectedViewId?: string\n tracks?: string[]\n}) {\n const existing = linearViewTarget({\n views: session.views,\n connectedViewId,\n assemblyName: assembly,\n })\n let viewId: string\n if (existing) {\n reportFailure(\n session,\n `Could not show ${assembly} ${locLabel(location)}`,\n Promise.resolve(existing.navToLocString(locString(location), assembly)),\n )\n viewId = existing.id\n } else {\n viewId = session.addView('LinearGenomeView', {\n displayName: `${assembly} \u2014 ${locLabel(location)}`,\n init: { assembly, loc: locString(location), tracks },\n }).id\n }\n return viewId\n}\n\n// Mark where a node sits on the reference, in the linear view already on\n// screen, instead of scrolling that view to it. Review: \"need to be able to\n// just highlight lineargenomeview coords\".\n//\n// The other half of the pair above, and the half that survives being let go of:\n// hover sync draws a band for as long as the pointer is over the node, where a\n// highlight is written into the session's list and stays until it is removed.\n// It also keeps the reader's frame \u2014 the interesting comparison at a pangenome\n// locus is usually the whole window, not the 200 bp the node occupies.\n//\n// Nothing to mark when no linear view on that assembly is ours to move (see\n// linearViewTarget); the caller offers the item only when there is.\nexport function highlightInLinearView({\n session,\n location,\n assembly,\n connectedViewId,\n}: {\n session: GraphLaunchSession\n location: GraphLocation\n assembly: string\n connectedViewId?: string\n}) {\n const target = linearViewTarget({\n views: session.views,\n connectedViewId,\n assemblyName: assembly,\n })\n if (target) {\n session.addHighlight?.({\n refName: location.refName,\n start: location.start,\n end: location.end,\n assemblyName: assembly,\n })\n }\n return target !== undefined\n}\n\n// Which assemblies a track config says it covers, for deciding whether a panel\n// can draw it at all. A trackId naming nothing in the session reads as covering\n// nothing, so a stale id drops the lane rather than adding one the panel would\n// fail to load.\nfunction assemblyNamesOfTrack(\n session: GraphLaunchSession,\n trackId: string | undefined,\n) {\n if (trackId === undefined) {\n return []\n }\n const track = session.tracks.find(\n t => readConfObject(t, 'trackId') === trackId,\n )\n const names: unknown = track ? readConfObject(track, 'assemblyNames') : []\n return Array.isArray(names)\n ? names\n .filter(n => typeof n === 'string')\n .map(n => canonicalAssemblyName(session, n))\n : []\n}\n\n// One panel per contributing assembly, each framed on the locus that assembly\n// contributes here, with the graph's own reference panel on top.\n//\n// The panel loci come from the graph rather than from the synteny track: rGFA\n// states where each contributor's sequence sits on its own coordinates, so the\n// launch needs no mate discovery, no PAF lookup and no dialog. That is the whole\n// point of launching from the graph instead of from a linear view.\n//\n// Panels carry THE GRAPH'S OWN TRACK and nothing else, which is a narrower rule\n// than the single-view launch's (see launchTracks, which scans the session for\n// the assembly's annotation). Tried that here: a gene track per panel takes\n// about 160px of a row that is otherwise a ruler, so on five strains the\n// annotation is most of the viewport and the ribbons \u2014 the thing the launch\n// exists to draw \u2014 are squeezed into the gaps, and `collapseEmptyRows` is here\n// to prevent exactly that.\n//\n// The graph's own track does not have that shape. It goes only in the panels\n// whose assembly its config declares, which is where the graph HAS coordinates:\n// the HPRC segments track names two, so both its panels get one lane, while the\n// E. coli one names K12 alone and a five-strain launch adds a single lane rather\n// than five. And it is the lane that makes the band readable, since the ribbons\n// otherwise connect two bare rulers and the reader has nothing to match across\n// them.\nexport function launchSyntenyView({\n session,\n contributors,\n trackId,\n graphTrackId,\n}: {\n session: GraphLaunchSession\n contributors: Contributor[]\n trackId?: string\n graphTrackId?: string\n}) {\n const graphTrackAssemblies = assemblyNamesOfTrack(session, graphTrackId)\n // The panels the chosen track aligns, in the order given. A pairwise track is\n // offered beside an all-vs-all, two assemblies being a synteny view, and over\n // every contributor it sat on each level and could draw on one at most. A\n // track that states no assemblies keeps them all.\n const aligned = assemblyNamesOfTrack(session, trackId)\n const covered = contributors.filter(c => aligned.includes(c.sample))\n const panels = covered.length >= 2 ? covered : contributors\n const snapshot = {\n init: {\n views: panels.map(c => ({\n assembly: c.sample,\n loc: locString(c),\n ...(graphTrackId !== undefined &&\n graphTrackAssemblies.includes(c.sample)\n ? { tracks: [graphTrackId] }\n : {}),\n })),\n // One entry per LEVEL, not one for the track. `init.tracks` is 2D \u2014 the\n // gap between views[i] and views[i+1] \u2014 and a flat `[trackId]` is read as\n // the level-0 shorthand, so on a five-strain launch only the top band got\n // the alignment and the four below it opened as bare rulers. The same\n // all-vs-all track fills every level: it carries all the pairs.\n tracks: trackId ? panels.slice(1).map(() => [trackId]) : [],\n collapseEmptyRows: true,\n },\n }\n // launchView where the session has it: a synteny view's state model is\n // loaded on demand and addView throws until it is\n if (session.launchView) {\n reportFailure(\n session,\n 'Could not open the synteny view',\n session.launchView('LinearSyntenyView', snapshot),\n )\n } else {\n session.addView('LinearSyntenyView', snapshot)\n }\n}\n", "// `session.views`, `session.hovered` and a display's members are read\n// structurally, their types being the host's rather than this plugin's\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n", "import { isRecord } from '../isRecord'\n\nexport interface NavigableLinearView {\n id: string\n assemblyNames: string[]\n navToLocString: (locString: string, assemblyName?: string) => unknown\n}\n\n// Reads `session.views` structurally, the same way graphViewHighlights does: the\n// members needed here are declared by LinearGenomeView, not by the\n// AbstractViewModel the session array is typed as.\nfunction isLinearView(view: unknown): view is NavigableLinearView {\n return (\n isRecord(view) &&\n view.type === 'LinearGenomeView' &&\n typeof view.id === 'string' &&\n typeof view.navToLocString === 'function' &&\n Array.isArray(view.assemblyNames)\n )\n}\n\n// The view a graph was launched from is not always in `session.views`: a row of\n// a LinearSyntenyView, LinearComparativeView or BreakpointSplitView sits in\n// that view's own `views[]`, so the candidates are the session's views plus one\n// level of rows.\nexport function withRows(views: unknown[]) {\n return views.flatMap(view =>\n isRecord(view) && Array.isArray(view.views)\n ? [view, ...view.views]\n : [view],\n )\n}\n\n// The linear view a \"show me this\" from the graph should move, rather than\n// opening a pane beside it. Three cases, in order:\n//\n// - the view this graph is paired with (`connectedViewId`), which is either\n// the view the graph was launched from or the one it later opened itself.\n// Explicit, so it wins.\n// - failing that, the only linear view in the session showing this assembly.\n// The pangenome sessions this view ships in are a linear view above a graph\n// with no pairing recorded, and there \"the linear view\" is unambiguous \u2014 the\n// same reasoning hoverSync's isConnected already applies to highlights.\n// - two or more candidates and no pairing: nothing. Guessing which of the\n// user's views to scroll is worse than opening one that is ours to move.\n//\n// Assembly-gated throughout: a linear view on a different assembly cannot show\n// this location at all.\nexport function linearViewTarget({\n views,\n connectedViewId,\n assemblyName,\n}: {\n views: unknown[]\n connectedViewId: string | undefined\n assemblyName: string\n}) {\n const candidates = withRows(views)\n .filter(view => isLinearView(view))\n .filter(view => view.assemblyNames.includes(assemblyName))\n const connected = candidates.find(view => view.id === connectedViewId)\n return connected ?? (candidates.length === 1 ? candidates[0] : undefined)\n}\n", "import {\n placeRowGenes,\n rowSpan,\n} from '@jbrowse/bandage-core/layout/walkRowDraw'\nimport { filterSamples } from '@jbrowse/bandage-core/layout/walkRows'\nimport {\n cutsWholeWalks as wholeWalksRule,\n stripMarks,\n walkStripApplies,\n walkStripFrame,\n} from '@jbrowse/bandage-core/layout/walkStrip'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { nodeAnchor } from '@jbrowse/bandage-core/referenceStrip'\n\nimport { withLaunchViews } from './launchViews'\nimport { WALK_GENE_ROWS } from './paneBase'\nimport { resolveLocationAssembly } from '../../launchFromGraph/contributors'\n\nimport type { SubgraphRegion } from '../../GetSubgraph'\n\nexport const withWalkRowViews = withLaunchViews\n .views(self => ({\n // Whether the strip of walk rows sits under the drawing: asked for, on a\n // standalone view whose layout draws nodes, for a graph with walks, and\n // not while a bubble is popped\n get walkStripShown() {\n return walkStripApplies({\n walkStrip: self.walkStrip,\n mode: { drawsNodes: self.modeDrawsNodes },\n drawsPicture: !!self.layoutResult?.tubeMap || !!self.walkRowBars,\n popped: self.popStack.length > 0,\n walks: self.graph?.paths?.length ?? 0,\n host: !!self.host,\n })\n },\n // The strip's rows: the cut's, with the sample filter and no repeat\n // pick, which the Repeat menu only offers in walk rows\n get walkStripRows() {\n const bars = this.walkStripShown ? self.cutWalkRows : undefined\n return bars\n ? { ...bars, rows: filterSamples(bars.rows, self.walkRowSamples) }\n : undefined\n },\n get walkStripFrame() {\n const bars = this.walkStripRows\n if (!bars) {\n return undefined\n }\n return walkStripFrame(bars, { width: self.paneWidth })\n },\n // Whether a cut must follow every snarl a walk leaves the window by, so\n // walks come back whole: walk rows measure them, and so does the strip\n get cutsWholeWalks() {\n return wholeWalksRule(layoutModeByValue(self.chosenLayoutMode), {\n walkStrip: self.walkStrip,\n host: !!self.host,\n })\n },\n // Where each walk passes the hovered node, or the selected one\n get walkStripMarks() {\n const bars = this.walkStripRows\n const id = self.hoveredNode ?? self.selectedNode\n const node = id === null ? undefined : self.nodeById?.get(id)\n return bars && node && self.graph\n ? stripMarks(self.graph, [bars.reference, ...bars.rows], node)\n : []\n },\n // Where the drawing has the node a strip point lights, for the ring\n // that finds it in a hairball\n get walkStripLocator() {\n const id = self.stripHover ? self.hoveredNode : null\n return id === null\n ? undefined\n : nodeAnchor(self.nodePositions?.[id], p => ({\n x: p.x * self.scaleX + self.translateX,\n y: p.y * self.scaleY + self.translateY,\n }))\n },\n }))\n .views(self => ({\n // The gene reads walk rows need, as the layout or the strip: for each row whose haplotype\n // (`HG00097#1`) names an assembly with a gene track, that track over the\n // span of its own contig the row's bar covers. The first WALK_GENE_ROWS\n // such rows are read, and the rest counted for the key.\n get walkGeneReads() {\n const bars = self.walkRowBars ?? self.walkStripRows\n if (!bars || !self.showGenes) {\n return undefined\n }\n const reads: {\n row: string\n trackId: string\n region: SubgraphRegion\n }[] = []\n let untrackedRows = 0\n let unplaced = 0\n for (const row of bars.rows) {\n if (!row.axis) {\n unplaced++\n continue\n }\n const assemblyName = resolveLocationAssembly(self.assemblyResolver, {\n sample: row.sample,\n haplotype:\n row.haplotype === undefined\n ? undefined\n : `${row.sample}#${row.haplotype}`,\n })\n const track = assemblyName\n ? self.geneTracksByAssembly.get(assemblyName)\n : undefined\n if (!assemblyName || !track) {\n untrackedRows++\n continue\n }\n reads.push({\n row: row.name,\n trackId: track.trackId,\n region: {\n assemblyName,\n refName: row.axis.contig,\n ...rowSpan(row.axis, row.bp),\n },\n })\n }\n return {\n reads: reads.slice(0, WALK_GENE_ROWS),\n gaps: {\n untracked: untrackedRows,\n unplaced,\n unread: Math.max(0, reads.length - WALK_GENE_ROWS),\n },\n }\n },\n get walkRowGeneGaps() {\n return this.walkGeneReads?.gaps\n },\n // Where a walk row's bar lies in its own assembly, for a linear view to\n // open: the span of its contig the bar covers, on the session assembly\n // its haplotype names (the cut's own assembly for the reference row).\n // The label names the haplotype when no assembly is loaded for it.\n walkRowLaunchTarget(index: number, bars = self.walkRowBars) {\n const row = bars ? [bars.reference, ...bars.rows][index] : undefined\n if (!row?.axis) {\n return undefined\n }\n const haplotype =\n row.haplotype === undefined\n ? undefined\n : `${row.sample}#${row.haplotype}`\n const assembly =\n index === 0\n ? self.graphRegion?.assemblyName\n : resolveLocationAssembly(self.assemblyResolver, {\n sample: row.sample,\n haplotype,\n })\n return {\n label: row.label,\n assembly,\n location: {\n sample: row.sample,\n haplotype,\n refName: row.axis.contig,\n ...rowSpan(row.axis, row.bp),\n },\n }\n },\n // Each row's genes as offsets along its bar: the reference row's from\n // the backbone's gene track, every other row's from its own assembly\n get walkRowGenes() {\n const bars = self.walkRowBars ?? self.walkStripRows\n if (!bars || !self.showGenes) {\n return undefined\n }\n const byRow = new Map(self.walkGeneFeatures ?? [])\n if (self.geneFeatures) {\n byRow.set(bars.reference.name, self.geneFeatures)\n }\n return byRow.size\n ? placeRowGenes([bars.reference, ...bars.rows], byRow)\n : undefined\n },\n }))\n", "import { sameBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n REFERENCE_STRIP_ZONE_PX,\n nodeAnchor,\n referenceStripBlocks,\n stripBlockAt,\n stripOverhang,\n} from '@jbrowse/bandage-core/referenceStrip'\nimport { referenceBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport { referenceNodes } from '@jbrowse/bandage-core/tubeMap/connectors'\nimport { deviationMarks } from '@jbrowse/bandage-core/tubeMap/deviations'\nimport { tubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport { tubeMapGenes } from '@jbrowse/bandage-core/tubeMap/genes'\n\nimport { hostFrame } from '../host'\nimport { PAPER_DARK, PAPER_LIGHT, paperCss } from './paneBase'\nimport { withWalkRowViews } from './walkRowViews'\n\nexport const withHostViews = withWalkRowViews\n .views(self => ({\n // Whether the drawing's x is reference bp a host can place. Walk rows\n // put the backbone at its bp too, but their bars are lengths, so the\n // mode's `cutMargins` is what says the drawing is a picture.\n get xIsReferenceBp() {\n return (\n self.layoutResult?.referenceAxis === true &&\n layoutModeByValue(self.chosenLayoutMode).cutMargins\n )\n },\n }))\n .views(self => ({\n // Whether the host places x. Only a layout whose x is reference bp can\n // take the window's transform; force, ordered and walk rows draw in\n // their own coordinates inside the track, and a popped bubble is a\n // picture of its own.\n get hostPlacesX() {\n const { host, graphRegion: region } = self\n return (\n host !== undefined &&\n host.initialized &&\n region !== undefined &&\n self.xIsReferenceBp &&\n self.popStack.length === 0 &&\n !host.dynamicBlocks.contentBlocks.some(\n b => b.refName === region.refName && b.reversed,\n )\n )\n },\n }))\n .views(self => ({\n get hostFrame() {\n const { host, graphRegion } = self\n return self.hostPlacesX && host && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n },\n get tubeMapPicture() {\n const drawing = self.layoutResult?.tubeMap\n return drawing ? tubeMapPicture(drawing) : undefined\n },\n get tubeMapReference() {\n const drawing = self.layoutResult?.tubeMap\n return drawing && self.drawnGraph\n ? referenceBoxes(self.drawnGraph, drawing.layout)\n : undefined\n },\n // the folded variants, as ticks on the tubes of the walks carrying them\n get tubeMapDeviations() {\n const coarse = self.layoutResult?.tubeMap?.coarse\n const layout = self.layoutResult?.tubeMap?.layout\n return coarse && layout\n ? deviationMarks(coarse.graph, layout, coarse.deviations)\n : []\n },\n // the reference boxes a linear view's connectors tie to its bp, which\n // the reference axis already puts under that bp\n get tubeMapReferenceNodes() {\n const layout = self.layoutResult\n return layout?.tubeMap && !layout.referenceAxis && self.drawnGraph\n ? referenceNodes(self.drawnGraph, layout.tubeMap.layout)\n : undefined\n },\n }))\n .views(self => ({\n // A linear view has the genes in a track of their own, at their bp\n get tubeMapGenes() {\n const reference = self.tubeMapReference\n return self.showGenes && !self.host && reference && self.backboneGenes\n ? tubeMapGenes(reference, self.backboneGenes)\n : []\n },\n // A drawing of nodes in its own coordinates inside a linear view, whose\n // reference segments the strip can put back at their bp\n get referenceStripApplies() {\n return (\n !!self.host?.initialized &&\n !!self.layoutResult &&\n self.drawsNodes &&\n !self.hostPlacesX &&\n !self.facetPanels\n )\n },\n }))\n .views(self => ({\n get referenceStripBlocks() {\n const { graph } = self\n return self.showReferenceStrip && self.referenceStripApplies && graph\n ? referenceStripBlocks(graph, {\n colorScheme: self.effectiveColorScheme,\n referenceRamp: self.referenceRamp,\n walks: self.walkLift?.walks,\n })\n : []\n },\n // Read off the live blocks, so the strip follows every frame of a pan\n // in the linear view\n get referenceStripFrame() {\n const { host, graphRegion } = self\n return host?.initialized && graphRegion\n ? hostFrame(host, graphRegion)\n : undefined\n },\n }))\n .views(self => ({\n get referenceStripShown() {\n return (\n self.referenceStripBlocks.length > 0 &&\n self.referenceStripFrame !== undefined\n )\n },\n // Whether the graph draws reference past the window's edges. A boolean\n // rather than the bp, which moves on every frame of a pan and would\n // resize the legend with it.\n get referenceStripOverhangs() {\n const frame = self.referenceStripFrame\n if (!frame || self.referenceStripBlocks.length === 0) {\n return false\n }\n const { left, right } = stripOverhang(\n self.referenceStripBlocks,\n frame,\n self.paneWidth,\n )\n return left > 0 || right > 0\n },\n get referenceStripFaded() {\n return self.referenceStripBlocks.some(b => b.faded)\n },\n }))\n .views(self => ({\n // The lit span on the strip, and where the graph drew what it is of:\n // the hovered node, the hovered bubble's name, or the selected node\n get referenceStripLit() {\n if (!self.referenceStripShown) {\n return undefined\n }\n const toScreen = (p: { x: number; y: number }) => ({\n x: p.x * self.scaleX + self.translateX,\n y: p.y * self.scaleY + self.translateY,\n })\n const bubble = self.hoveredNode === null ? self.hoveredBubble : null\n if (bubble) {\n const halo = self.bubbleHalos.find(h => sameBubble(h.bubble, bubble))\n return {\n start: bubble.start,\n end: bubble.end,\n anchor: halo ? toScreen(halo.labelAt) : undefined,\n }\n }\n const nodeId = self.hoveredNode ?? self.selectedNode\n const span = nodeId === null ? undefined : self.nodeSpan(nodeId)\n return span && nodeId !== null\n ? {\n ...span,\n anchor: nodeAnchor(self.nodePositions?.[nodeId], toScreen),\n }\n : undefined\n },\n referenceStripNodeAt(sx: number, sy: number) {\n const frame = self.referenceStripFrame\n return self.referenceStripShown && frame\n ? stripBlockAt(self.referenceStripBlocks, frame, sx, sy)\n : undefined\n },\n get paperCss() {\n return paperCss(self.darkMode ? PAPER_DARK : PAPER_LIGHT)\n },\n // the strip, and the gap the fit leaves under it\n get referenceStripZonePx() {\n return self.referenceStripShown ? REFERENCE_STRIP_ZONE_PX : 0\n },\n }))\n", "import { isBackbone } from '@jbrowse/bandage-core/anchoredNodes'\n\nimport { isRecord } from '../isRecord'\n\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\n\n// What a LinearGenomeView writes to `session.hovered` on every mousemove (see\n// LinearGenomeViewContainer): the bp under the cursor, plus the feature under it\n// if the topmost track had one. Nothing names the source VIEW, so a graph view\n// filters by whether the position falls in the region it was cut from \u2014 but the\n// position does name the source ASSEMBLY, and that turns out to be the half\n// that matters.\nexport interface LgvHover {\n refName: string\n // The 0-based base under the pointer, the convention `stable.start` and the\n // cut region are in. Not the LGV's own `coord`, which is 1-based for display.\n coord: number\n // The assembly the hovered view is showing. `hoverPosition` is a\n // `PxToBpResult`, i.e. the displayed region the pointer landed in spread flat,\n // so this is that region's own `assemblyName`.\n //\n // Read because refName alone does not identify a locus in a session holding\n // several assemblies, which is every session these graphs are launched in. A\n // PanSN name reduces to a bare contig \u2014 the E. coli pangenome loads five\n // strains each with one refName `chr`, and HPRC's hg38 and a GenArk haplotype\n // both call it `chr6` \u2014 so a synteny stack's rows all answer to the same\n // name at unrelated coordinates. Without this the hover on ANY row lit up a\n // node in the graph, and the node then published its own reference interval\n // back into every linear view.\n //\n // Optional because the channel is typed `unknown` and read structurally: a\n // hover that states no assembly is taken at its word rather than dropped.\n assemblyName?: string\n featureName?: string\n}\n\ninterface FeatureLike {\n get: (key: string) => unknown\n}\n\nfunction isFeatureLike(value: unknown): value is FeatureLike {\n return isRecord(value) && typeof value.get === 'function'\n}\n\n// A display hovers either a Feature, read with `get`, or a plain hit item with\n// a `name` of its own, which is what the canvas feature display hands over.\n// Reading only the first left the exact segment match dead on that display.\nfunction hoveredName(feature: unknown) {\n const name = isFeatureLike(feature)\n ? feature.get('name')\n : isRecord(feature)\n ? feature.name\n : undefined\n return typeof name === 'string' ? name : undefined\n}\n\n// `hovered` is typed `unknown` on the session by design \u2014 it is a shared channel\n// every view writes its own shape to \u2014 so this reads the LGV's shape out of it\n// structurally rather than asserting a type onto it.\nexport function readLgvHover(hovered: unknown): LgvHover | undefined {\n let result: LgvHover | undefined\n if (isRecord(hovered) && isRecord(hovered.hoverPosition)) {\n const { refName, coord, coord0, assemblyName } = hovered.hoverPosition\n if (typeof refName === 'string' && typeof coord === 'number') {\n result = {\n refName,\n // `coord` is 1-based; a host that states the 0-based `coord0` is\n // taken at its word. Read as 0-based, the last base of every node lit\n // the next one, and a 1 bp node could not be reached at all.\n coord: typeof coord0 === 'number' ? coord0 : coord - 1,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n featureName: hoveredName(hovered.hoverFeature),\n }\n }\n }\n return result\n}\n\n// Whether a hover is one this graph can answer: the same assembly, the same\n// stable sequence, and inside the window the cut was made for.\n//\n// The assembly is checked FIRST and is the whole reason this is not just a\n// coordinate test. See LgvHover.assemblyName: a graph cut from K12 and a\n// synteny row on Sakai both call their sequence `chr`, so on refName and\n// coordinate alone every row of the stack matched and the graph highlighted a\n// K12 node at Sakai's offset. A hover that names no assembly still passes,\n// which is what a hand-written channel writer and the older LGVs get.\nexport function hoverInRegion(\n hover: LgvHover,\n region: { refName: string; assemblyName: string; start: number; end: number },\n) {\n return (\n (hover.assemblyName === undefined ||\n hover.assemblyName === region.assemblyName) &&\n hover.refName === region.refName &&\n hover.coord >= region.start &&\n hover.coord < region.end\n )\n}\n\n// The graph node a linear-view hover points at.\n//\n// The feature under the cursor is the exact answer when the graph's own segments\n// track is what's hovered: an RgfaTabixAdapter feature's name is the segment id,\n// which is `GraphNode.name` (`GraphNode.id` carries a strand suffix, so the\n// match has to be on name). Any other track \u2014 genes, bubbles \u2014 supplies only a\n// coordinate, which still identifies the backbone segment covering it: the\n// backbone tiles the reference exactly once, whether rGFA's rank 0 declared it\n// or a reference path's own steps did.\nexport function nodeForLgvHover({\n hover,\n nodes,\n}: {\n hover: LgvHover\n nodes: GraphNode[]\n}) {\n let byName: string | undefined\n let byCoord: string | undefined\n for (const node of nodes) {\n if (node.name === hover.featureName) {\n byName = node.id\n } else if (\n byCoord === undefined &&\n isBackbone(node) &&\n hover.coord >= node.stable.start &&\n hover.coord < node.stable.start + node.length\n ) {\n byCoord = node.id\n }\n }\n // An exact segment match wins over the coordinate it happens to sit at.\n return byName ?? byCoord ?? null\n}\n", "import { panSNSample } from '@jbrowse/bandage-core/pansn'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\n\n// A per-sample lane names its rows its own way: a phased callset `HG00097 HP0`,\n// counting haplotypes from 0, a MAF `HG00097.1`, counting from 1 as PanSN does,\n// and anything else by the bare sample\nconst PHASED_ROW = /^(.+) HP(\\d+)$/\nconst DOTTED_ROW = /^(.+)\\.(\\d+)$/\n\n// A bare sample can end in `.2` too, an accession for one, so each reading is\n// tried in turn\nfunction readings(row: string) {\n const phased = PHASED_ROW.exec(row)\n const dotted = DOTTED_ROW.exec(row)\n return [\n ...(phased\n ? [{ sample: phased[1]!, haplotype: String(Number(phased[2]) + 1) }]\n : []),\n ...(dotted ? [{ sample: dotted[1]!, haplotype: dotted[2] }] : []),\n { sample: row, haplotype: undefined },\n ]\n}\n\nfunction haplotypeOf(pathName: string) {\n return pathOrigin(pathName).name.split('#')[1]\n}\n\n// The walks a hovered lane row stands for: the one of its haplotype, or every\n// walk of a bare sample. A cut often holds one haplotype of a sample, so a row\n// naming the other matches nothing rather than the one it holds.\nexport function walksForRow(row: string, paths: readonly { name: string }[]) {\n const names = paths.map(p => p.name)\n for (const { sample, haplotype } of readings(row)) {\n const walks = names.filter(\n name =>\n panSNSample(pathOrigin(name).name) === sample &&\n (haplotype === undefined || haplotypeOf(name) === haplotype),\n )\n if (walks.length > 0) {\n return walks\n }\n }\n return []\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { TrackScanSession } from './launchFromGraph'\n\nconst ANNOTATION_TRACK_TYPE = 'FeatureTrack'\n\n// What to turn on in a linear view the graph opens on `assemblyName`.\n//\n// A launch used to carry the graph's own track and nothing else, and that track\n// is configured for the reference alone \u2014 so `Launch view` \u2192 `CFT073 chr:\u2026`\n// landed on `No tracks active`, which answers \"where is this strain's sequence?\"\n// with an empty pane. What the session does hold for a contributing assembly is\n// that assembly's own annotation, and on a pangenome config that is one track\n// per strain (`CFT073_genes`), which is exactly what makes the landing readable.\n//\n// Annotation tracks only, not everything configured for the assembly. A launch\n// is a jump to a locus, and an alignments or coverage track turned on behind the\n// user's back fetches data nobody asked for; a FeatureTrack at a 50 kb window is\n// a tabix range query.\n//\n// `first` is the graph's own track when the launch is on the reference, so the\n// segments the graph drew sit at the top of the view rather than wherever config\n// order puts them.\nexport function launchTracks({\n session,\n assemblyName,\n first,\n}: {\n session: TrackScanSession\n assemblyName: string\n first?: string\n}) {\n const found: string[] = []\n for (const track of session.tracks) {\n const type: unknown = readConfObject(track, 'type')\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n type === ANNOTATION_TRACK_TYPE &&\n Array.isArray(assemblyNames) &&\n assemblyNames.includes(assemblyName) &&\n typeof trackId === 'string' &&\n trackId !== first\n ) {\n found.push(trackId)\n }\n }\n return first ? [first, ...found] : found\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getTrackName } from '@jbrowse/core/util/tracks'\nimport { getEnv, isStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nimport { canonicalAssemblyName } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface LaunchableSyntenyTrack {\n trackId: string\n name: string\n // how many of the requested assemblies this track covers, so a whole-set\n // all-vs-all sorts above a pairwise alignment covering two of them\n coverage: number\n}\n\nconst SYNTENY_TRACK_TYPE = 'SyntenyTrack'\nconst SYNTENY_ADAPTER_CATEGORY = 'Synteny adapters'\n\n// A SyntenyTrack, or any track reading a synteny adapter (a GraphTrack over a\n// gbz-base database). Core's isSyntenyTrack makes the same test on newer hosts.\nfunction isSyntenyTrack(track: AnyConfigurationModel) {\n if (readConfObject(track, 'type') === SYNTENY_TRACK_TYPE) {\n return true\n }\n const adapterType: unknown = track.adapter?.type\n if (typeof adapterType !== 'string' || !isStateTreeNode(track)) {\n return false\n }\n const { pluginManager } = getEnv<{ pluginManager?: PluginManager }>(track)\n return (\n !!pluginManager?.hasAdapterType(adapterType) &&\n pluginManager.getAdapterType(adapterType).adapterMetadata?.category ===\n SYNTENY_ADAPTER_CATEGORY\n )\n}\n\n// Synteny datasets in the session that align at least two of `assemblyNames`.\n//\n// Two is the floor because that is the floor for a synteny view; more is better,\n// and an all-vs-all covering every contributing assembly is what makes the\n// multi-panel launch worth offering at all.\nexport function launchableSyntenyTracks(\n session: TrackScanSession,\n assemblyNames: string[],\n) {\n const wanted = new Set(assemblyNames)\n const found: LaunchableSyntenyTrack[] = []\n for (const track of session.tracks) {\n const trackAssemblies: unknown = readConfObject(track, 'assemblyNames')\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n isSyntenyTrack(track) &&\n typeof trackId === 'string' &&\n Array.isArray(trackAssemblies)\n ) {\n const coverage = trackAssemblies.filter(\n name =>\n typeof name === 'string' &&\n wanted.has(canonicalAssemblyName(session, name)),\n ).length\n if (coverage >= 2) {\n found.push({ trackId, name: getTrackName(track, session), coverage })\n }\n }\n }\n return found.sort((a, b) => b.coverage - a.coverage)\n}\n", "// Hands `text` to the browser as a file to save\nexport function downloadText(\n text: string,\n name: string,\n type = 'image/svg+xml',\n) {\n const url = URL.createObjectURL(new Blob([text], { type }))\n const a = document.createElement('a')\n a.href = url\n a.download = name\n a.click()\n setTimeout(() => {\n URL.revokeObjectURL(url)\n }, 0)\n}\n", "import { withLaunchActions } from './pane/launchActions'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport {\n DEFAULT_MAX_GRAPH_NODES,\n MAX_GRAPH_REGION_BP,\n formatSpanBp,\n} from './pane/paneBase'\n\n// The pane every graph drawing is: a view of its own, or a display inside a\n// linear view. Built in stages under pane/, each extending the one before.\nexport function GraphPaneMixin() {\n return withLaunchActions\n}\n\nexport type GraphPaneModel = Instance<typeof withLaunchActions>\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(item => typeof item === 'string')\n}\n\n// The assemblies the track names after its reference, which is what core's\n// MultiWaySyntenyDisplay opens a lane-declaring source on.\nexport function trackLanes(track: AnyConfigurationModel) {\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n const lanes = isStringArray(assemblyNames) ? assemblyNames.slice(1) : []\n return lanes.length > 0 ? lanes : undefined\n}\n\n// A graph is cut on the first assembly its track names, the rule\n// GbzBaseSyntenyAdapter states for its anchor. Every other assembly the track\n// names holds its sequence as rank>0 alleles off that reference's backbone, so\n// a window on one has no reference coordinates to frame the cut by.\nexport function graphReferenceAssembly(track: AnyConfigurationModel) {\n const assemblyNames: unknown = readConfObject(track, 'assemblyNames')\n return isStringArray(assemblyNames) ? assemblyNames[0] : undefined\n}\n\nexport function offReferenceProblem(\n referenceAssembly: string | undefined,\n assemblyName: string,\n) {\n return referenceAssembly === undefined || referenceAssembly === assemblyName\n ? undefined\n : `The graph is cut on its reference, ${referenceAssembly}: open it from a view of ${referenceAssembly}`\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport {\n TrackType,\n createBaseTrackConfig,\n createBaseTrackModel,\n} from '@jbrowse/core/pluggableElementTypes'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\n// core's synteny displays, copied to ask for headerLanes so only gbz-base\n// offers lanes or opens in a synteny, dotplot or circular view\nexport const SYNTENY_DISPLAYS = [\n 'MultiWaySyntenyDisplay',\n 'LinearSyntenyDisplay',\n 'DotplotDisplay',\n 'ChordSyntenyDisplay',\n]\n\nfunction displaysInOrder(pluginManager: PluginManager): DisplayType[] {\n const displays = pluginManager.getElementTypesInGroup(\n 'display',\n ) as DisplayType[]\n const named = (name: string) => displays.find(d => d.name === name)\n const needsLanes = (display: DisplayType | undefined) =>\n display &&\n Object.assign(Object.create(display) as DisplayType, {\n adapterCapabilities: ['headerLanes'],\n })\n return [\n named('LinearGraphDisplay'),\n named('LinearBasicDisplay'),\n ...SYNTENY_DISPLAYS.map(name => needsLanes(named(name))),\n ].filter((d): d is DisplayType => d !== undefined)\n}\n\nexport default function GraphTrackF(pluginManager: PluginManager) {\n pluginManager.addTrackType(() => {\n const configSchema = ConfigurationSchema(\n 'GraphTrack',\n {},\n {\n baseConfiguration: createBaseTrackConfig(pluginManager),\n explicitIdentifier: 'trackId',\n },\n )\n const track = new TrackType({\n name: 'GraphTrack',\n displayName: 'Pangenome graph track',\n configSchema,\n stateModel: createBaseTrackModel(\n pluginManager,\n 'GraphTrack',\n configSchema,\n ),\n })\n for (const display of displaysInOrder(pluginManager)) {\n track.addDisplayType(display)\n }\n return track\n })\n}\n", "import type modelFactory from './GraphGenomeView/viewModel'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type { SnapshotIn } from '@jbrowse/mobx-state-tree'\n\n// GraphGenomeView has no assembly/track resolution \u2014 every field is a plain\n// persisted view prop, so the launch spec forwards straight onto the view\n// snapshot. `afterAttach` loads `gfaLocation`, or cuts the\n// `loadedTrackId`/`loadedRegion` pair once, when the view is created.\n//\n// **Taken off the model rather than listed by hand**, which is the whole point.\n// This named four props (`gfaLocation`, `colorScheme`, `linearLayout`,\n// `drawPaths`) while the extension point spreads whatever it is handed \u2014 so the\n// runtime accepted every prop and the DECLARED contract accepted a third of\n// them. The docs' own figure specs launch with thirteen: `loadedTrackId`,\n// `loadedRegion`, `layoutMode`, `colorDomain`, `paneHeight`, `referencePath`,\n// `layoutQuality`, `maxRegionBp` and `bubbleSpread` among them, none of which\n// this said were allowed. It carries a `#extensionPoint` tag, so the published\n// API docs said so too.\n//\n// Derived, so adding a view prop widens the launch with it. `type` is the\n// dispatch key rather than a setting \u2014 loadSessionSpec strips it before calling\n// this \u2014 and is the one field a caller may not supply.\nexport type LaunchGraphGenomeViewArgs = Partial<\n Omit<SnapshotIn<ReturnType<typeof modelFactory>>, 'type'>\n> & {\n session: AbstractSessionModel\n}\n\ndeclare module '@jbrowse/core/PluginManager' {\n interface ExtensionPointRegistry {\n 'LaunchView-GraphGenomeView': {\n args: LaunchGraphGenomeViewArgs\n result: LaunchGraphGenomeViewArgs\n }\n }\n}\n\nexport default function LaunchGraphGenomeViewF(pluginManager: PluginManager) {\n /** #extensionPoint LaunchView-GraphGenomeView | async | Programmatically launch a graph genome view */\n pluginManager.addToExtensionPoint('LaunchView-GraphGenomeView', args => {\n const { session, ...spec } = args\n session.addView('GraphGenomeView', spec)\n return args\n })\n}\n", "import { lazy } from 'react'\n\nimport DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\nimport { configSchemaFactory } from './configSchema'\nimport { stateModelFactory } from './model'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function LinearGraphDisplayF(pluginManager: PluginManager) {\n pluginManager.addDisplayType(() => {\n const configSchema = configSchemaFactory()\n return Object.assign(\n new DisplayType({\n name: 'LinearGraphDisplay',\n displayName: 'Graph',\n configSchema,\n stateModel: stateModelFactory(configSchema),\n // FeatureTrack and SyntenyTrack for the configs and share links that\n // name the graph display on one, which 4.0.7 and before required\n trackType: ['GraphTrack', 'FeatureTrack', 'SyntenyTrack'],\n viewType: 'LinearGenomeView',\n ReactComponent: lazy(() => import('./components/LinearGraphDisplay')),\n }),\n { adapterCapabilities: ['getSubgraph'] },\n )\n })\n}\n", "import { COLOR_SCHEME_VALUES } from '@jbrowse/bandage-core/colorSchemes'\nimport { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { trackHeightConfigSchemaFields } from '@jbrowse/display-kit/trackHeightConfigSchemaFields'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config LinearGraphDisplay\n * The graph drawn as a track of the linear genome view. A layout whose x is\n * reference bp draws under the view's coordinates and re-cuts as the view\n * moves; force, ordered and walk rows draw in their own coordinates, fitted to\n * the track.\n */\nexport function configSchemaFactory() {\n return ConfigurationSchema(\n 'LinearGraphDisplay',\n {\n /**\n * #slot\n * the layout the track opens in\n */\n layoutMode: {\n type: 'stringEnum',\n model: types.enumeration('LayoutMode', LAYOUT_MODE_VALUES),\n defaultValue: 'auto',\n },\n /**\n * #slot\n */\n colorScheme: {\n type: 'stringEnum',\n model: types.enumeration('ColorScheme', COLOR_SCHEME_VALUES),\n defaultValue: 'auto',\n },\n ...trackHeightConfigSchemaFields({\n defaultHeight: 300,\n height: 'the height of the track the graph is drawn in',\n }),\n },\n { explicitlyTyped: true, explicitIdentifier: 'displayId' },\n )\n}\n\nexport type LinearGraphDisplayConfigModel = ReturnType<\n typeof configSchemaFactory\n>\nexport type LinearGraphDisplayConfig = Instance<LinearGraphDisplayConfigModel>\n", "import { lazy } from 'react'\n\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationReference, getConf } from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\nimport TrackHeightMixin from '@jbrowse/display-kit/TrackHeightMixin'\nimport {\n addDisposer,\n getSnapshot,\n isAlive,\n types,\n} from '@jbrowse/mobx-state-tree'\nimport {\n computeActivityPhase,\n computeDisplayStatusPhase,\n} from '@jbrowse/render-core/displayPhase'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport { reaction } from 'mobx'\n\nimport { cutHolds, hostCut, hostWindow } from '../GraphGenomeView/host'\nimport {\n GraphPaneMixin,\n MAX_GRAPH_REGION_BP,\n formatSpanBp,\n} from '../GraphGenomeView/model'\nimport {\n graphReferenceAssembly,\n offReferenceProblem,\n trackLanes,\n} from '../graphTrackConfig'\nimport { denseCovers, isNodeLimitError } from './denseWindow'\nimport { trackAdapterConfig } from '../panSNAliases/trackAdapterConfig'\n\nimport type { LinearGraphDisplayConfigModel } from './configSchema'\nimport type { DenseWindow } from './denseWindow'\nimport type { SubgraphRegion, SubgraphTier } from '../GetSubgraph'\nimport type { HostWindow } from '../GraphGenomeView/host'\nimport type { LaunchGraphGenomeViewArgs } from '../LaunchGraphGenomeView'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\nimport type { DisplayStatusPhase } from '@jbrowse/render-core/displayPhase'\n\ntype GraphViewSpec = Omit<LaunchGraphGenomeViewArgs, 'session'>\n\nconst GraphTrackSettingsDialog = lazy(\n () => import('./components/GraphTrackSettingsDialog'),\n)\n\nexport function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {\n return (\n types\n .compose(\n 'LinearGraphDisplay',\n BaseDisplay,\n TrackHeightMixin(),\n GraphPaneMixin(),\n types.model({\n type: types.literal('LinearGraphDisplay'),\n configuration: ConfigurationReference(configSchema),\n // A 4.0 entry's nested state, which preProcessSnapshot folds flat and\n // so never holds. Declared so a session spec stating it is not\n // reported as an unknown key.\n pane: types.maybe(types.frozen()),\n // The retired haplotype overview's row choice and order, which a 5.x\n // session may carry and preProcessSnapshot drops, declared for the\n // same reason\n overviewRowsChoice: types.maybe(types.frozen()),\n overviewRowOrder: types.maybe(types.frozen()),\n // the window the graph on screen was asked for, so a restored\n // session cuts it again\n cutRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // whether that cut came from the track's coarse pair\n // (RgfaTabixAdapter), on which no bp cap applies\n coarseCut: types.optional(types.boolean, false),\n // The bp ceiling on a fine cut, a proxy for node count that only\n // holds at fine granularity; `maxGraphNodes` counts what came back.\n maxRegionBp: types.optional(types.number, MAX_GRAPH_REGION_BP),\n // How far the cut follows links past the region's own segments. At\n // 0 a detour that leaves the backbone before the window and rejoins\n // after it arrives as a fragment, since its interior is indexed only\n // under its own sequence, so one bubble draws as two unrelated\n // insertions. A hop follows alleles only, so it never walks the\n // backbone out of the window.\n subgraphContext: types.optional(types.number, 1),\n // the haplotypes a GBZ cut is for; unset is the lanes the track names\n subgraphHaplotypes: types.maybe(types.frozen<string[]>()),\n }),\n )\n // A 4.0 session nests the graph's state under `pane`; a 5.x one may\n // carry the retired overview's row choice\n .preProcessSnapshot(snapshot => {\n const {\n pane,\n overviewRowsChoice: _rows,\n overviewRowOrder: _order,\n ...rest\n } = snapshot as {\n pane?: { type?: string }\n overviewRowsChoice?: unknown\n overviewRowOrder?: unknown\n }\n if (!pane) {\n return rest as typeof snapshot\n }\n const { type: _type, ...props } = pane\n return { ...props, ...rest } as typeof snapshot\n })\n .volatile(() => ({\n recuts: 0,\n // the host window the settle clock last woke on\n settledWindow: undefined as HostWindow | undefined,\n dense: undefined as DenseWindow | undefined,\n }))\n .views(self => ({\n get adapterConfig() {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n get defaultLayoutMode(): LayoutModeValue {\n return getConf(self, 'layoutMode')\n },\n get defaultColorScheme(): ColorScheme {\n return getConf(self, 'colorScheme')\n },\n // The linear view leaves its highlight bands off this track while false\n get drawsGenomicCoordinates() {\n return self.layoutResult === undefined || self.hostPlacesX\n },\n get canvasHeight() {\n return self.height\n },\n get canRetryLoad() {\n return self.cutRegion !== undefined\n },\n get cutHaplotypes() {\n return this.chosenHaplotypes\n },\n get chosenHaplotypes() {\n return (\n self.subgraphHaplotypes ??\n trackLanes(self.parentTrack.configuration)\n )\n },\n // the linear view's zoom past which the track's coarse pair is cut, or\n // undefined for a track with none\n get coarseAboveBpPerPx() {\n const coarse = self.adapterConfig.coarse as\n { aboveBpPerPx?: unknown } | undefined\n const above = coarse?.aboveBpPerPx\n return typeof above === 'number' ? above : undefined\n },\n }))\n .views(self => ({\n tierAt(bpPerPx: number): SubgraphTier {\n const above = self.coarseAboveBpPerPx\n return above !== undefined && bpPerPx > above ? 'coarse' : 'fine'\n },\n capFor(tier: SubgraphTier) {\n return tier === 'coarse' ? Infinity : self.maxRegionBp\n },\n get cutTier(): SubgraphTier {\n return self.coarseCut && self.coarseAboveBpPerPx !== undefined\n ? 'coarse'\n : 'fine'\n },\n }))\n .views(self => ({\n get settledCapBp() {\n const seen = self.settledWindow\n return seen ? self.capFor(self.tierAt(seen.bpPerPx)) : Infinity\n },\n }))\n .views(self => ({\n get regionTooLarge() {\n const seen = self.settledWindow\n return seen !== undefined && seen.end - seen.start > self.settledCapBp\n },\n get regionTooLargeReason() {\n const seen = self.settledWindow\n return seen\n ? `Region too large for a graph cut (${formatSpanBp(seen.end - seen.start)}, max ${formatSpanBp(self.settledCapBp)})`\n : ''\n },\n get zoomCanReleaseGate() {\n return true\n },\n get fetchCanceled() {\n return self.loadCanceled\n },\n }))\n .views(self => ({\n // A backend that failed is an error the canvas reports with its retry;\n // the status chrome has no renderError phase of its own. A cut refused\n // over its node limit is an error marked regionTooLarge, which core's\n // error bar shows as a zoom-in notice instead.\n get displayPhase(): DisplayStatusPhase {\n return computeDisplayStatusPhase(\n {\n regionTooLarge: self.regionTooLarge,\n error: self.error ?? self.renderError,\n },\n () =>\n computeActivityPhase(\n {\n isMinimized: self.isMinimized,\n fetchInert: false,\n viewportEmpty:\n self.host?.initialized === true &&\n self.host.hasVisibleContent === false,\n isLoading: self.isLoading || !self.hasGraph,\n fetchCanceled: self.loadCanceled,\n awaitingDependentData: false,\n rendersCanvas: true,\n canvasDrawn: self.painted && self.geometryPainted,\n },\n () => true,\n () => self.host?.effectiveBodyMounted ?? true,\n ),\n )\n },\n }))\n .actions(self => ({\n // The setters describe the next cut; the caller re-cuts.\n setSubgraphContext(hops: number) {\n self.subgraphContext = hops\n },\n setSubgraphHaplotypes(haplotypes: string[] | undefined) {\n self.subgraphHaplotypes = haplotypes\n self.dense = undefined\n },\n setDense(window: DenseWindow | undefined) {\n self.dense = window\n },\n setMaxRegionBp(bp: number) {\n self.maxRegionBp = bp\n },\n // Cut `cutRegion` again with the current options. A hop past a coarse\n // cut reaches nothing new: every bubble node's two links are indexed\n // under the backbone either side of it.\n cut() {\n const region = self.cutRegion\n if (!region) {\n return\n }\n const problem = offReferenceProblem(\n graphReferenceAssembly(self.parentTrack.configuration),\n region.assemblyName,\n )\n if (problem) {\n self.clearGraph()\n self.setError(new Error(problem))\n return\n }\n const coarse = self.cutTier === 'coarse'\n return self.cutSubgraph(self.adapterConfig, region, {\n hops: coarse ? 0 : self.subgraphContext,\n haplotypes: self.chosenHaplotypes,\n tier: coarse ? 'coarse' : undefined,\n ...(layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ? { snarls: 'overlapping' as const }\n : {}),\n })\n },\n }))\n .actions(self => ({\n recutAt(seen: HostWindow) {\n const tier = self.tierAt(seen.bpPerPx)\n self.coarseCut = tier === 'coarse'\n self.cutRegion = hostCut(\n seen,\n self.capFor(tier),\n layoutModeByValue(self.chosenLayoutMode).cutMargins,\n )\n self.recuts++\n return self.cut()\n },\n }))\n .actions(self => ({\n // The settle clock. A window the cut still holds fetches nothing; one\n // past its edge re-cuts, on the tier the zoom asks for, with margins\n // when the host places x and the window alone when the layout draws\n // its own picture of it. A canceled cut is re-made by the next move,\n // and a window a refused cut covers keeps its notice without asking\n // again. Returns whether it re-cut.\n settleOn(seen: HostWindow): boolean {\n self.settledWindow = seen\n const margins = layoutModeByValue(self.chosenLayoutMode).cutMargins\n if (\n self.regionTooLarge ||\n denseCovers(self.dense, seen) ||\n (!self.loadCanceled &&\n self.tierAt(seen.bpPerPx) === self.cutTier &&\n cutHolds(self.cutRegion, seen, margins))\n ) {\n return false\n }\n // The error is the latest cut's, since a cut clears it as it\n // starts and an outrun cut sets nothing\n void Promise.resolve(self.recutAt(seen)).then(() => {\n if (isAlive(self) && isNodeLimitError(self.error)) {\n this.refuseDenseCut(seen)\n }\n })\n return true\n },\n // A cut refused for its node count holds nothing, so a window\n // narrower than this one cuts again\n refuseDenseCut(seen: HostWindow) {\n self.setDense(seen)\n self.cutRegion = undefined\n this.settleOn(self.settledWindow ?? seen)\n },\n switchLayout(mode: LayoutModeValue) {\n const from = layoutModeByValue(self.chosenLayoutMode)\n self.setLayoutMode(mode)\n const to = layoutModeByValue(mode)\n const seen = self.host ? hostWindow(self.host) : undefined\n if (\n seen &&\n !self.regionTooLarge &&\n (to.cutMargins !== from.cutMargins ||\n to.wholeWalks !== from.wholeWalks)\n ) {\n return self.recutAt(seen)\n }\n return self.recomputeLayout()\n },\n retryLoad() {\n void self.cut()\n },\n reload() {\n void self.cut()\n },\n cancelFetchByUser() {\n self.stopLoad()\n },\n }))\n .actions(self => ({\n forceLoad() {\n const seen = self.settledWindow\n if (seen) {\n self.setMaxRegionBp(Math.ceil(seen.end - seen.start))\n self.settleOn(seen)\n }\n },\n // The host's two clocks. The frame clock moves x with every frame of\n // the linear view and fetches nothing; the settle clock wakes on its\n // debounced blocks.\n afterAttach() {\n if (self.cutRegion && !self.graph) {\n void self.cut()\n }\n addDisposer(\n self,\n reaction(\n () => self.hostPlacesX,\n places => {\n if (!places) {\n self.releaseHost()\n }\n },\n { name: 'GraphHostPlacesX' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostFrame,\n frame => {\n if (frame) {\n self.hostTransform(frame.scale, frame.translateX)\n }\n },\n {\n equals: (a, b) =>\n a?.scale === b?.scale && a?.translateX === b?.translateX,\n fireImmediately: true,\n name: 'GraphHostFrame',\n },\n ),\n )\n // A track clips what runs past its height, so side-by-side panels\n // grow it to what they need as a pane of their own. Only a change in\n // the panels does this, so a track shrunk afterwards stays shrunk.\n addDisposer(\n self,\n reaction(\n () => `${self.facet.field} ${self.facetPlacement?.count}`,\n () => {\n const needs = self.facetGridIn(self.paneCeiling)?.total ?? 0\n if ((self.facetGrid?.total ?? 0) > self.height) {\n self.setHeight(Math.max(self.height, Math.ceil(needs)))\n }\n },\n { name: 'GraphFacetHeight' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.host?.coarseDynamicBlocks,\n blocks => {\n const { host } = self\n const seen = blocks && host ? hostWindow(host) : undefined\n if (seen) {\n self.settleOn(seen)\n }\n },\n { fireImmediately: true, name: 'GraphHostSettle' },\n ),\n )\n },\n }))\n .views(self => ({\n // The window on screen as a view of its own, drawn as the track draws\n // it: the cut less the margins it holds for panning. A window forced\n // past the cap carries its own span as the cap.\n get graphViewSpec() {\n const seen = self.host ? hostWindow(self.host) : undefined\n const trackId = self.sourceTrackId\n if (\n !seen ||\n !trackId ||\n !self.hasGraph ||\n self.coarseCut ||\n self.regionTooLarge\n ) {\n return undefined\n }\n const start = Math.floor(seen.start)\n const end = Math.ceil(seen.end)\n return {\n loadedTrackId: trackId,\n loadedRegion: {\n refName: seen.refName,\n assemblyName: seen.assemblyName,\n start,\n end,\n },\n subgraphContext: self.subgraphContext,\n subgraphHaplotypes: self.chosenHaplotypes,\n maxRegionBp: Math.max(self.maxRegionBp, end - start),\n layoutMode: self.chosenLayoutMode,\n colorScheme: self.chosenColorScheme,\n referencePath: self.referencePath,\n geneTrackId: self.geneTrackId,\n showGenes: self.showGenes,\n showBubbles: self.showBubbles,\n showDeletionEdges: self.showDeletionEdges,\n walkLayers: self.walkLayers,\n facet: getSnapshot(self.facet),\n } satisfies GraphViewSpec\n },\n }))\n .actions(self => ({\n openGraphView() {\n const spec = self.graphViewSpec\n if (spec) {\n getSession(self).addView('GraphGenomeView', spec)\n }\n },\n }))\n .views(self => ({\n // Which haplotypes a GBZ cut is for: every one in the graph, the\n // assemblies the track names, or a list typed in Settings\n haplotypeMenuItems(): MenuItem[] {\n if (self.adapterConfig.type !== 'GbzBaseSyntenyAdapter') {\n return []\n }\n const lanes = trackLanes(self.parentTrack.configuration)\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n void self.cut()\n }\n return [\n {\n label: 'Haplotypes',\n subMenu: [\n {\n type: 'radio',\n label: 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(lanes\n ? [\n {\n type: 'radio' as const,\n label: `The track's ${lanes.length} assemblies`,\n checked: chosen === undefined,\n onClick: () => {\n recut(undefined)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Chosen in Settings...',\n checked: (chosen?.length ?? 0) > 0,\n onClick: () => {\n this.openSettings()\n },\n },\n ],\n },\n ]\n },\n openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, open: true, onClose },\n ])\n },\n trackMenuItems(): MenuItem[] {\n const launches = self.launchMenuItems()\n pushLaunchViewMenuItem(launches, {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n disabled: !self.graphViewSpec,\n disabledHelpText: 'Zoom in until the track cuts a graph',\n onClick: () => {\n self.openGraphView()\n },\n })\n return [\n ...this.haplotypeMenuItems(),\n ...self.graphMenuItems(),\n {\n label: 'Settings',\n icon: SettingsIcon,\n onClick: () => {\n this.openSettings()\n },\n },\n ...launches,\n ]\n },\n }))\n )\n}\n\nexport type LinearGraphDisplayStateModel = ReturnType<typeof stateModelFactory>\nexport type LinearGraphDisplayModel = Instance<LinearGraphDisplayStateModel>\n// what the track's own settings read, which the menus that open them cannot\n// name without naming themselves\nexport type LinearGraphCutModel = Omit<\n LinearGraphDisplayModel,\n 'trackMenuItems' | 'haplotypeMenuItems' | 'openSettings'\n>\n", "import type { HostWindow } from '../GraphGenomeView/host'\n\n// A cut refused for its node count: the GBZ adapter's own error, marked\n// regionTooLarge so core shows it as a zoom-in notice, or gbz-base's when it\n// reaches the display unwrapped\nexport function isNodeLimitError(error: unknown) {\n return (\n error instanceof Error &&\n (error.name === 'NodeLimitError' ||\n (error as { regionTooLarge?: unknown }).regionTooLarge === true ||\n /reads more than nodeLimit|^Subgraph size limit of \\d+ nodes exceeded/.test(\n error.message,\n ))\n )\n}\n\n// Where a cut came back over its node limit. The graph is as dense as that\n// only near it, so it stands for windows as wide or wider on the same contig\n// within one window-width of it.\nexport interface DenseWindow {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport function denseCovers(dense: DenseWindow | undefined, seen: HostWindow) {\n if (\n dense?.refName !== seen.refName ||\n dense.assemblyName !== seen.assemblyName\n ) {\n return false\n }\n const span = dense.end - dense.start\n return (\n seen.end - seen.start >= span &&\n seen.end > dense.start - span &&\n seen.start < dense.end + span\n )\n}\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema, { normalizeSnapshot } from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function MinigraphBubbleAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'MinigraphBubbleAdapter',\n displayName: 'Minigraph bubble BED adapter',\n normalizeSnapshot,\n configSchema,\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./MinigraphBubbleAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config MinigraphBubbleAdapter\n * #trackType FeatureTrack\n * #fileFormat graph | Minigraph bubble BED | `gfatools bubble` output; HPRC publishes one ready-made, so no preprocessing at all\n * the tabix-indexed BED `gfatools bubble` writes for a minigraph graph: one row\n * per bubble, on the reference's own coordinates. Unlike\n * [RgfaTabixAdapter](/docs/config/rgfatabixadapter) this needs no index build of\n * your own, because HPRC publishes this file beside its minigraph graph.\n *\n * It shows *where* the graph varies and by how much, not the graph itself.\n *\n * #example\n * ```js\n * {\n * type: 'MinigraphBubbleAdapter',\n * uri: 'https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.bubbles.bed.gz',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n bubblesLocation: { uri, baseUri },\n index: {\n indexType: csi ? 'CSI' : 'TBI',\n location: { uri: `${uri}.${csi ? 'csi' : 'tbi'}`, baseUri },\n },\n }\n : snap\n}\n\nconst MinigraphBubbleAdapter = ConfigurationSchema(\n 'MinigraphBubbleAdapter',\n {\n /**\n * #slot\n */\n bubblesLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.bb.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n index: ConfigurationSchema('MinigraphBubbleIndex', {\n /**\n * #slot index.indexType\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot index.location\n */\n location: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.bb.bed.gz.tbi',\n locationType: 'UriLocation',\n },\n },\n }),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix, for when they\n * differ. `gfatools bubble` names each row after the graph's stable\n * sequence, so a Minigraph-Cactus graph yields `GRCh38#0#chr6` and an\n * `hg38` assembly needs `{ hg38: 'GRCh38' }`; HPRC's published v1.0\n * minigraph bubbles are bare (`chr6`) and need nothing.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"MinigraphBubbleAdapter\", \"uri\": \"graph.bb.bed.gz\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type MinigraphBubbleAdapterConfig = Instance<\n typeof MinigraphBubbleAdapter\n>\n\nexport default MinigraphBubbleAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema, { normalizeSnapshot } from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function RgfaTabixAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'RgfaTabixAdapter',\n displayName: 'Indexed rGFA adapter',\n normalizeSnapshot,\n configSchema,\n // what a graph display needs of its track's adapter\n adapterCapabilities: ['getSubgraph'],\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./RgfaTabixAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config RgfaTabixAdapter\n * #trackType GraphTrack\n * #fileFormat graph | Indexed rGFA | Built by `scripts/build_rgfa_tabix.sh`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED projections of an rGFA (minigraph). rGFA tags every\n * segment with `SN`/`SO`/`SR`, so both files record coordinates the graph\n * already states rather than inventing any. Plain GFA (pggb, odgi,\n * Minigraph-Cactus) has no such tags and is not supported.\n *\n * The `uri` shorthand takes the prefix the build script was given and resolves\n * `<uri>.segs.bed.gz`, `<uri>.links.bed.gz` and their `.tbi` indexes. `coarse`\n * takes the same shorthand for a second pair at one node per bubble, built by\n * `build_bubble_tier.sh` in jbrowse-components, plus the zoom past which a\n * graph view following a linear view cuts it.\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * uri: 'https://example.com/hprc.rgfa',\n * coarse: { uri: 'https://example.com/hprc.tier10000', aboveBpPerPx: 1000 },\n * }\n * ```\n */\n\nfunction tbi(uri: string, baseUri: unknown, csi: unknown) {\n return {\n indexType: csi ? 'CSI' : 'TBI',\n location: { uri: `${uri}.${csi ? 'csi' : 'tbi'}`, baseUri },\n }\n}\n\nfunction prefixLocations(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n segmentsLocation: { uri: `${uri}.segs.bed.gz`, baseUri },\n segmentsIndex: tbi(`${uri}.segs.bed.gz`, baseUri, csi),\n linksLocation: { uri: `${uri}.links.bed.gz`, baseUri },\n linksIndex: tbi(`${uri}.links.bed.gz`, baseUri, csi),\n }\n : snap\n}\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri } = snap\n return prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, ...coarse }) }\n : snap,\n )\n}\n\nconst indexSchema = (name: string, defaultUri: string) =>\n ConfigurationSchema(name, {\n /**\n * #slot\n */\n indexType: {\n model: types.enumeration('IndexType', ['TBI', 'CSI']),\n type: 'stringEnum',\n defaultValue: 'TBI',\n },\n /**\n * #slot\n */\n location: {\n type: 'fileLocation',\n defaultValue: { uri: defaultUri, locationType: 'UriLocation' },\n },\n })\n\nconst RgfaTabixCoarseTier = ConfigurationSchema('RgfaTabixCoarseTier', {\n /**\n * #slot\n * The linear view's bp per px past which a graph following it cuts this\n * pair. Unset means the track has no coarse tier. There is no default,\n * because the zoom a fine cut stays drawable to depends on the graph's\n * density: a minigraph graph averages ~7 kb per segment, a base-level pggb\n * graph ~17 bp.\n */\n aboveBpPerPx: { type: 'maybeNumber' },\n /**\n * #slot\n */\n segmentsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.tier.segs.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n segmentsIndex: indexSchema(\n 'RgfaCoarseSegmentsIndex',\n '/path/to/graph.tier.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n */\n linksLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.tier.links.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n linksIndex: indexSchema(\n 'RgfaCoarseLinksIndex',\n '/path/to/graph.tier.links.bed.gz.tbi',\n ),\n})\n\nconst RgfaTabixAdapter = ConfigurationSchema(\n 'RgfaTabixAdapter',\n {\n /**\n * #slot\n * one row per segment: `stableName start end segmentId rank`, as emitted by\n * `gfatools gfa2bed -m`\n */\n segmentsLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.segs.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n segmentsIndex: indexSchema(\n 'RgfaSegmentsIndex',\n '/path/to/graph.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n * one row per link per endpoint, each carrying both endpoints in full so a\n * neighbour on another stable sequence needs no segment-id lookup\n */\n linksLocation: {\n type: 'fileLocation',\n defaultValue: {\n uri: '/path/to/graph.links.bed.gz',\n locationType: 'UriLocation',\n },\n },\n /**\n * #slot\n */\n linksIndex: indexSchema(\n 'RgfaLinksIndex',\n '/path/to/graph.links.bed.gz.tbi',\n ),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix in the graph, for\n * when they differ. Defaults to identity: the assembly name is assumed to be\n * the PanSN sample name, and a graph whose stable names are bare (minigraph\n * writes `chr1`) needs nothing here at all.\n *\n * Minigraph-Cactus writes PanSN stable names, so HPRC's release-2 graph\n * calls the reference `GRCh38#0#chr1` and an `hg38` assembly needs\n * `{ hg38: 'GRCh38' }`. The prefix is what disambiguates: that same graph\n * also contains `CHM13#0#chr1`, so matching on the contig alone would\n * silently resolve to the wrong sample.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * The same graph at one node per bubble, which a graph view following a\n * linear view cuts once that view is zoomed out past `aboveBpPerPx`, and\n * which no bp cap applies to. `{ uri, aboveBpPerPx }`, where `uri` is a\n * prefix as the adapter's own is.\n */\n coarse: RgfaTabixCoarseTier,\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"uri\": \"graph.rgfa\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type RgfaTabixAdapterConfig = Instance<typeof RgfaTabixAdapter>\n\nexport default RgfaTabixAdapter\n", "import {\n buildAdapterConfig,\n isSegmentsLocation,\n locationName,\n} from '../GraphAddTrackWorkflow/buildTrackConfig'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { FileLocation } from '@jbrowse/core/util'\nimport type {\n AdapterGuesser,\n TrackTypeGuesser,\n} from '@jbrowse/core/util/tracks'\n\ninterface TrackConfigSnapshot {\n displays?: { type?: string; [key: string]: unknown }[]\n [key: string]: unknown\n}\n\nconst GRAPH_ADAPTERS = new Set(['RgfaTabixAdapter', 'GbzBaseSyntenyAdapter'])\n\nexport function isGbzLocation(loc: FileLocation) {\n return locationName(loc).toLowerCase().endsWith('.gbz.db')\n}\n\n// A gbz-base adapter cuts on the first assembly it names. A track added\n// through Add track names that assembly on the track alone.\nexport function withGbzAnchor(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n { type?: string; assemblyNames?: unknown[] } | undefined\n return adapter?.type === 'GbzBaseSyntenyAdapter' &&\n !adapter.assemblyNames?.length &&\n Array.isArray(snap.assemblyNames) &&\n snap.assemblyNames.length > 0\n ? { ...snap, adapter: { ...adapter, assemblyNames: snap.assemblyNames } }\n : snap\n}\n\nexport function guessGraphAdapter(\n file: FileLocation,\n index?: FileLocation,\n adapterHint?: string,\n) {\n if (\n (!adapterHint || adapterHint === 'GbzBaseSyntenyAdapter') &&\n isGbzLocation(file)\n ) {\n return {\n type: 'GbzBaseSyntenyAdapter',\n gbzDbLocation: file,\n ...(index ? { haplotypeIndexLocation: index } : {}),\n }\n }\n if (\n (!adapterHint || adapterHint === 'RgfaTabixAdapter') &&\n isSegmentsLocation(file)\n ) {\n return buildAdapterConfig({\n choice: 'RgfaTabixAdapter',\n loc: file,\n indexLoc: index,\n assembly: '',\n sample: '',\n })\n }\n return undefined\n}\n\nexport default function GraphTrackDefaultsF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-preProcessTrackConfig', withGbzAnchor)\n pluginManager.addToExtensionPoint(\n 'Core-guessAdapterForLocation',\n (next: AdapterGuesser): AdapterGuesser =>\n (file, index, adapterHint) =>\n guessGraphAdapter(file, index, adapterHint) ??\n next(file, index, adapterHint),\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessTrackTypeForLocation',\n (next: TrackTypeGuesser): TrackTypeGuesser =>\n (adapterName, file) =>\n GRAPH_ADAPTERS.has(adapterName)\n ? 'GraphTrack'\n : next(adapterName, file),\n )\n}\n", "import { getSession } from '@jbrowse/core/util'\nimport { alpha } from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\nimport { graphViewHighlights } from './graphViewHighlights'\n\nimport type { HighlightRegion } from './graphViewHighlights'\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst useStyles = makeStyles()(theme => ({\n highlight: {\n height: '100%',\n position: 'absolute',\n background: alpha(theme.palette.primary.main, 0.25),\n borderLeft: `2px solid ${theme.palette.primary.main}`,\n borderRight: `2px solid ${theme.palette.primary.main}`,\n pointerEvents: 'none',\n zIndex: 10,\n },\n}))\n\n// One band over the linear view for a hovered graph node. `getHighlightCoords`\n// is the LGV's own projection \u2014 it canonicalizes the refName and floors the\n// width to 3 px, so a pure insertion (a zero-length reference span) still shows\n// as a mark rather than vanishing.\nconst Highlight = observer(function Highlight({\n model,\n region,\n}: {\n model: LinearGenomeViewModel\n region: HighlightRegion\n}) {\n const { classes } = useStyles()\n const coords = model.getHighlightCoords(region)\n return coords ? (\n <div\n data-testid=\"graph-node-highlight\"\n className={classes.highlight}\n style={{ left: coords.left, width: coords.width }}\n />\n ) : null\n})\n\nconst GraphNodeHighlight = observer(function GraphNodeHighlight({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { views } = getSession(model)\n return (\n <>\n {graphViewHighlights([...views], model.id, model.assemblyNames).map(\n ({ key, region }) => (\n <Highlight key={`graph-hover-${key}`} model={model} region={region} />\n ),\n )}\n </>\n )\n})\n\nexport default GraphNodeHighlight\n", "import { isRecord } from '../isRecord'\nimport { withRows } from '../launchFromGraph/linearViewTarget'\n\nexport interface HighlightRegion {\n refName: string\n start: number\n end: number\n assemblyName?: string\n}\n\nexport interface GraphViewHighlight {\n key: string\n region: HighlightRegion\n}\n\nfunction readRegion(value: unknown): HighlightRegion | undefined {\n let region: HighlightRegion | undefined\n if (isRecord(value)) {\n const { refName, start, end, assemblyName } = value\n if (\n typeof refName === 'string' &&\n typeof start === 'number' &&\n typeof end === 'number'\n ) {\n region = {\n refName,\n start,\n end,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n }\n }\n }\n return region\n}\n\n// Whether a graph view's highlights belong on a given linear view.\n// `connectedViewId` is written by the launch menu, so a launched pair is\n// explicit. A graph view without one \u2014 a hand-written session snapshot, or\n// `Add > Graph genome view` followed by a subgraph load \u2014 matches any linear\n// view, because the alternative is silently drawing nothing.\n//\n// So does one whose linear view has been closed. Held to an id nothing answers\n// to, it matched no view and its hover drew nowhere for the rest of the\n// session, the view it next opened included.\nfunction isConnected(\n view: Record<string, unknown>,\n linearViewId: string,\n liveViewIds: ReadonlySet<unknown>,\n) {\n const connectedViewId = view.connectedViewId\n return (\n connectedViewId === undefined ||\n connectedViewId === linearViewId ||\n !liveViewIds.has(connectedViewId)\n )\n}\n\n// ...and whether the view can mean anything by it. `getHighlightCoords`\n// canonicalizes a refName against the region's OWN assembly and then lays it\n// out against this view's displayed regions, without ever asking whether the\n// two are the same assembly \u2014 so a band handed to the wrong view is drawn, at\n// coordinates that belong to somebody else's genome.\n//\n// That is not hypothetical for an unpaired graph, which by the rule above\n// matches every linear view in the session. A synteny stack's rows are LGVs on\n// different assemblies, and a PanSN name reduces to a bare contig: the five\n// E. coli strains each have one refName `chr`, so a graph cut from K12 painted\n// its K12 interval across Sakai's row and CFT073's at their own offsets. With\n// the assembly checked the reference row keeps the band and the rest correctly\n// draw nothing.\n//\n// A region stating no assembly still passes \u2014 `readRegion` leaves it optional,\n// and the fallback is the behaviour every existing snapshot has.\nfunction isOnAssembly(\n region: HighlightRegion,\n assemblyNames: string[] | undefined,\n) {\n return (\n region.assemblyName === undefined ||\n assemblyNames === undefined ||\n assemblyNames.includes(region.assemblyName)\n )\n}\n\n// The graph displays in a linear view's own tracks, connected to it by where\n// they sit.\nfunction trackGraphs(view: Record<string, unknown>) {\n const tracks = Array.isArray(view.tracks) ? view.tracks : []\n return tracks.flatMap((track: unknown) =>\n isRecord(track) && Array.isArray(track.displays)\n ? track.displays.filter(\n (display: unknown) =>\n isRecord(display) && display.type === 'LinearGraphDisplay',\n )\n : [],\n ) as Record<string, unknown>[]\n}\n\n// The highlights a linear view should draw for the graph views connected to it.\n// Reads `session.views` structurally: the members it needs are declared by\n// GraphGenomeView, not by the AbstractViewModel the session array is typed as.\nexport function graphViewHighlights(\n views: unknown[],\n linearViewId: string,\n // the drawing view's own assemblies, so a band is only drawn where its\n // coordinates mean something \u2014 see isOnAssembly\n linearAssemblyNames?: string[],\n): GraphViewHighlight[] {\n const highlights: GraphViewHighlight[] = []\n const candidates = withRows(views)\n const liveViewIds = new Set(\n candidates.map(view => (isRecord(view) ? view.id : undefined)),\n )\n for (const view of candidates) {\n if (isRecord(view) && view.id === linearViewId) {\n for (const display of trackGraphs(view)) {\n const region = readRegion(display.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof display.id === 'string' ? display.id : 'graph-track',\n region,\n })\n }\n }\n }\n if (\n isRecord(view) &&\n view.type === 'GraphGenomeView' &&\n isConnected(view, linearViewId, liveViewIds)\n ) {\n const region = readRegion(view.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof view.id === 'string' ? view.id : 'graph',\n region,\n })\n }\n }\n }\n return highlights\n}\n", "import GraphNodeHighlight from './GraphNodeHighlight'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The graph-to-linear half of the hover sync. The reverse half needs no mount\n// point: an LGV already publishes its hover to `session.hovered`, and the graph\n// view's own autorun reads it (see GraphGenomeView/model.ts).\n//\n// Mounted through the extension point rather than imported by the LGV, so this\n// plugin never imports @jbrowse/plugin-linear-genome-view at runtime: it is not\n// one of JBrowse's shared globals, so a value import would bundle a second copy\n// of that whole plugin.\nconst POINT = 'LinearGenomeView-TracksContainerComponent'\n\nexport default function GraphHoverSyncF(pluginManager: PluginManager) {\n pluginManager.contributeToExtensionPoint(POINT, ({ model }) => (\n <GraphNodeHighlight key=\"graphgenomeview-hover-highlight\" model={model} />\n ))\n}\n", "import { DisplayType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { trackAdapterConfig } from './trackAdapterConfig'\nimport { SYNTENY_DISPLAYS } from '../GraphTrack/index'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\n// Core's synteny displays send `adapterConfig` with every request, the lane\n// listing's included, so overriding the getter reaches them all\nfunction withTrackAdapterConfig(model: IAnyModelType) {\n return model.views(self => ({\n get adapterConfig(): Record<string, unknown> {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n }))\n}\n\nexport default function PanSNAliasesF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-extendPluggableElement', element => {\n if (\n element instanceof DisplayType &&\n SYNTENY_DISPLAYS.includes(element.name)\n ) {\n element.extendStateModel(withTrackAdapterConfig)\n }\n return element\n })\n}\n", "// The name JBrowse knows this plugin by, which a config's `plugins` entry\n// states beside its `esmUrl`.\nexport const PLUGIN_NAME = 'GraphGenomeView'\n", "export const version = '6.3.0'\n"],
5
+ "mappings": "o5DAAA,IAAAA,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,sBAAsB,ICAtD,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,EAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,6BAA6B,ICA7D,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,qCAAqC,ICArE,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oCAAoC,ICApE,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4CAA4C,ICA5E,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,2CAA2C,ICA3E,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4EAA4E,ICA5G,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oDAAoD,ICApF,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,uCAAuC,ICAvE,IAAAC,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,mCAAmC,ICAnE,IAAAC,GAAmB,UACnBC,GAAsC,UCEtC,IAAAC,GAA4B,UACrBC,MAAQ,kBAAc,IAAc,GAAAC,KAAK,SAAU,CACxD,GAAI,MACJ,GAAI,OACJ,EAAG,KACL,EAAG,GAAG,KAAgB,GAAAA,KAAK,SAAU,CACnC,GAAI,OACJ,GAAI,KACJ,EAAG,GACL,EAAG,GAAG,KAAgB,GAAAA,KAAK,SAAU,CACnC,GAAI,OACJ,GAAI,MACJ,EAAG,KACL,EAAG,GAAG,CAAC,EAAG,aAAa,EChBvB,IAAAC,GAAwB,UCCxB,IAAAC,GAAoC,SACpCC,GAAsB,UAgChBC,MAAwB,wBAC5B,wBACA,CAWE,cAAe,CACb,KAAM,cACN,aAAc,CAAC,CACjB,EAMA,cAAe,CACb,KAAM,eACN,aAAc,CACZ,IAAK,wBACL,aAAc,aAChB,CACF,EASA,uBAAwB,CACtB,KAAM,eACN,aAAc,CACZ,IAAK,GACL,aAAc,aAChB,CACF,EAQA,cAAe,CACb,KAAM,eACN,aAAc,CACZ,IAAK,GACL,aAAc,aAChB,CACF,EAMA,cAAY,wBAAoB,oBAAqB,CAInD,UAAW,CACT,MAAO,SAAM,YAAY,YAAa,CAAC,MAAO,KAAK,CAAC,EACpD,KAAM,aACN,aAAc,KAChB,EAIA,SAAU,CACR,KAAM,eACN,aAAc,CAAE,IAAK,GAAI,aAAc,aAAc,CACvD,CACF,CAAC,EASD,mBAAoB,CAClB,KAAM,eACN,aAAc,CACZ,IAAK,GACL,aAAc,aAChB,CACF,EAaA,eAAgB,CACd,KAAM,aACN,MAAO,SAAM,YAAY,cAAe,CACtC,OACA,YACA,aACF,CAAC,EACD,aAAcC,GAAiB,MACjC,EAQA,gBAAiB,CACf,KAAM,SACN,aAAc,EAChB,EASA,oBAAqB,CACnB,KAAM,SACN,aAAc,CAAC,CACjB,EAWA,QAAS,CACP,KAAM,SACN,aAAcA,GAAiB,QAC/B,SAAU,EACZ,EAMA,UAAW,CACT,KAAM,SACN,aAAcA,GAAiB,MAC/B,SAAU,EACZ,CACF,EACA,CACE,gBAAiB,GAiBjB,mBAAoBC,GAAQ,CAC1B,GAAM,CAAE,IAAAC,EAAK,QAAAC,EAAS,MAAAC,CAAM,EAAIH,EAChC,MAAO,CACL,GAAGA,EACH,GAAIC,EAAM,CAAE,cAAe,CAAE,IAAAA,EAAK,QAAAC,CAAQ,CAAE,EAAI,CAAC,EACjD,GAAI,OAAOC,GAAU,SACjB,CACE,cAAe,CAAE,IAAKA,EAAO,QAAAD,CAAQ,EACrC,GAAIC,EAAM,SAAS,KAAK,EACpB,CAAE,WAAY,CAAE,SAAU,CAAE,IAAK,GAAGA,CAAK,OAAQ,QAAAD,CAAQ,CAAE,CAAE,EAC7D,CAAC,CACP,EACA,CAAC,CACP,CACF,CACF,CACF,EAIOE,GAAQN,GDvOA,SAARO,GAAwCC,EAA8B,CAC3EA,EAAc,eACZ,IACE,IAAI,GAAAC,QAAY,CACd,KAAM,wBACN,YAAa,6BACb,aAAAC,GASA,oBAAqB,CACnB,cACA,cACA,oBACA,iBACF,EACA,gBAAiB,CACf,SAAU,kBACZ,EACA,gBAAiB,IACf,OAAO,4CAA4B,EAAE,KAAKC,GAAKA,EAAE,OAAO,CAC5D,CAAC,CACL,CACF,CElCA,IAAAC,GAA2B,UAC3BC,GAA8B,UA8B9B,SAASC,GAAeC,EAA0C,CAChE,MACE,aAAcA,GACd,OAAQA,EAAyB,UAAa,UAElD,CAEA,IAAMC,GAAWC,GACf,OAAOA,GAAa,UACpBA,IAAa,MACb,OAAO,QAAQA,CAAQ,EAAE,KACvB,CAAC,CAACC,EAAKC,CAAK,IACV,CAAC,MAAO,YAAa,QAAQ,EAAE,SAASD,CAAG,GAC3C,OAAOC,GAAU,UACjBA,IAAU,EACd,EAIK,SAASC,GAAWC,EAAwC,CACjE,OACG,OAAOA,EAAc,OAAU,UAAYA,EAAc,QAAU,IACpEL,GAAQK,EAAc,aAAa,CAEvC,CAEA,IAAqBC,GAArB,cAA2C,gBAA+B,CAA1E,kCACE,UAAO,gBAEP,MAAM,QAAQC,EAAuC,CACnD,GAAM,CAAE,cAAAF,EAAe,UAAAG,EAAW,UAAAC,EAAW,OAAAC,CAAO,EAAIH,EAClD,CAAE,YAAAI,CAAY,EAAI,QAAM,eAC5B,KAAK,cACLF,EACAJ,CACF,EACA,OAAOP,GAAea,CAAW,EAC7BA,EAAY,SAASH,EAAW,CAAE,OAAAE,CAAO,CAAC,EAC1C,CAAE,QAAS,CAAC,EAAG,MAAO,CAAE,CAC9B,CACF,ECvEA,IAAAE,GAA2B,UAC3BC,GAA8C,UA4D9C,SAASC,GAAkBC,EAA6C,CACtE,MACE,gBAAiBA,GACjB,OAAQA,EAA4B,aAAgB,UAExD,CAYA,IAAqBC,GAArB,cAAyC,gCAA6C,CAAtF,kCACE,UAAO,cAMP,MAAM,QAAQC,EAAqC,CAIjD,GAAM,CAAE,cAAAC,EAAe,OAAAC,EAAQ,UAAAC,EAAW,KAAAC,EAAM,OAAAC,CAAO,EAAIL,EAErD,CAAE,YAAAM,CAAY,EAAI,QAAM,eAC5B,KAAK,cACLH,EACAF,CACF,EACA,OAAIJ,GAAkBS,CAAW,EACxBA,EAAY,YAAYJ,EAAQ,CAAE,GAAGE,EAAM,OAAAC,CAAO,CAAC,GAI5D,QAAQ,KACN,iBAAiBC,EAAY,YAAY,IAAI,iCAC/C,EACO,GACT,CACF,EC1GA,IAAAC,GAAqB,UAErBC,GAAqC,UACrCC,GAAsB,UAIhBC,MAAsB,SAAK,IAAM,OAAO,uCAAoB,CAAC,EAEpD,SAARC,GAAwCC,EAA8B,CAC3EA,EAAc,wBACZ,IACE,IAAI,wBAAqB,CACvB,KAAM,wBACN,YAAa,4BACb,eAAgBF,GAChB,WAAY,SAAM,MAAM,CAAC,CAAC,CAC5B,CAAC,CACL,CACF,CClBA,IAAIG,GACJ,SAASC,IAAc,CACrB,OAAAD,KAAW,OAAO,8CAA8B,EAAE,KAAME,GAAQA,EAAI,QAAQ,CAAC,EAAE,MAAO,GAAM,CAC1F,MAAAF,GAAS,OACH,CACR,CAAC,EACMA,EACT,CCPA,IAAAG,GAA8B,UAqBTC,GAArB,cAAgD,gBAAoC,CAApF,kCACE,UAAO,qBAEP,MAAM,QAAQC,EAA4C,CACxD,GAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,eAAAC,CAAe,EAAIH,EAE3CG,IAAiB,uBAAuB,EACxC,IAAMC,EAAS,MAAMC,GAAY,EAEjCF,IAAiB,kBAAkB,EACnC,IAAMG,EAAY,YAAY,IAAI,EAC5BC,EAASH,EAAO,cAAcH,EAAOC,CAAO,EAC5CM,EAAW,YAAY,IAAI,EAAIF,EAErC,MAAO,CAAE,OAAAC,EAAQ,SAAAC,CAAS,CAC5B,CACF,ECtCA,IAAAC,GAAqB,UAErBC,GAAqB,UACrBC,GAAiC,UCFjC,IAAAC,GAA8B,UAC9BC,GAA2B,UAC3BC,EAAmC,UACnCC,GAAyB,UCAzB,IAAAC,GAAuC,UACvCC,GAA2B,UCL3B,IAAAC,GAAqB,UCWrB,IAAIC,GAAW,GACf,SAASC,GAAeC,EAAOC,EAAS,CACtC,GAAM,CAAE,KAAAC,CAAK,EAAID,EACXE,EAAQ,IAAI,IAChBF,EAAQ,MAAM,IAAKG,GAAS,CAACA,EAAK,GAAIC,GAAgBH,EAAME,EAAK,MAAM,CAAC,CAAC,CAC3E,EACME,EAAWC,GAAOJ,EAAM,IAAII,CAAE,GAAKL,EAAK,kBACxCM,EAAWR,EAAM,MAAM,OAAOS,CAAU,EAAE,KAAK,CAACC,EAAGC,IAAMD,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EACxFC,EAAwB,IAAI,IAC9BC,EAAI,EACR,QAAWT,KAAQI,EACjBI,EAAM,IAAIR,EAAK,GAAI,CAAE,EAAAS,EAAG,EAAG,CAAE,CAAC,EAC9BA,GAAKP,EAAQF,EAAK,EAAE,EAAIF,EAAK,WAE/B,IAAMY,EAAWC,GAAef,CAAK,EAC/BgB,EAAQ,IAAI,IAAIR,EAAS,IAAKJ,GAAS,CAACA,EAAK,GAAI,CAAC,CAAC,CAAC,EACpDa,EAAQT,EAAS,IAAKJ,GAASA,EAAK,EAAE,EAC5C,QAAWG,KAAMU,EAAO,CACtB,IAAMC,EAAKN,EAAM,IAAIL,CAAE,EACjBY,EAAOH,EAAM,IAAIT,CAAE,EAAI,EAC7B,QAAWa,KAAaN,EAAS,IAAIP,CAAE,GAAK,CAAC,EACvCS,EAAM,IAAII,CAAS,IAGvBJ,EAAM,IAAII,EAAWD,CAAI,EACzBP,EAAM,IAAIQ,EAAW,CAAE,EAAGF,EAAG,EAAIZ,EAAQC,CAAE,EAAI,EAAG,EAAGT,GAAWqB,CAAK,CAAC,EACtEF,EAAM,KAAKG,CAAS,EAExB,CACA,IAAIC,EAAY,EAChB,QAAWjB,KAAQJ,EAAM,MAClBY,EAAM,IAAIR,EAAK,EAAE,GACpBQ,EAAM,IAAIR,EAAK,GAAI,CACjB,EAAGiB,IAAcR,EAAIb,EAAM,MAAM,OACjC,EAAGF,GAAW,CAChB,CAAC,EAGL,OAAOc,CACT,CACA,SAASU,GAAYtB,EAAOC,EAAS,CACnC,IAAMW,EAAQb,GAAeC,EAAOC,CAAO,EAC3C,OAAOA,EAAQ,MAAM,IAAKG,IAAU,CAAE,GAAGA,EAAM,GAAGQ,EAAM,IAAIR,EAAK,EAAE,CAAE,EAAE,CACzE,CCjDA,SAASmB,GAAkBC,EAAOC,EAAW,CAC3C,IAAMC,EAAWF,EAAM,MAAM,OAC1BG,GAASC,EAAWD,CAAI,IAAMF,EAAUE,EAAK,EAAE,GAAG,QAAU,GAAK,CACpE,EACA,GAAID,EAAS,OAAS,EACpB,OAAOD,EAET,IAAMI,EAASH,EAAS,IAAKC,GAAS,CACpC,IAAMG,EAAWL,EAAUE,EAAK,EAAE,EAC5BI,EAAMD,EAAS,KAAK,MAAMA,EAAS,OAAS,CAAC,CAAC,EACpD,MAAO,CACL,EAAGC,EAAI,EACP,EAAGA,EAAI,EACP,EAAGJ,EAAK,OAAO,MAAQA,EAAK,OAAS,EACrC,EAAGA,EAAK,MACV,CACF,CAAC,EACKK,EAASH,EAAO,OAAO,CAACI,EAAKC,IAAMD,EAAMC,EAAE,EAAG,CAAC,EAC/CC,EAAKN,EAAO,OAAO,CAACI,EAAKC,IAAMD,EAAMC,EAAE,EAAIA,EAAE,EAAG,CAAC,EAAIF,EACrDI,EAAKP,EAAO,OAAO,CAACI,EAAKC,IAAMD,EAAMC,EAAE,EAAIA,EAAE,EAAG,CAAC,EAAIF,EACrDK,EAAKR,EAAO,OAAO,CAACI,EAAKC,IAAMD,EAAMC,EAAE,EAAIA,EAAE,EAAG,CAAC,EAAIF,EACvDM,EAAM,EACNC,EAAM,EACV,QAAWL,KAAKL,EACdS,GAAOJ,EAAE,GAAKA,EAAE,EAAIC,IAAOD,EAAE,EAAIG,GACjCE,GAAOL,EAAE,GAAKA,EAAE,EAAIE,IAAOF,EAAE,EAAIG,GAEnC,IAAMG,EAAQ,CAAC,KAAK,MAAMD,EAAKD,CAAG,EAC5BG,EAAI,KAAK,IAAID,CAAK,EAClBE,EAAI,KAAK,IAAIF,CAAK,EAClBG,EAAM,CAAC,EACb,OAAW,CAACC,EAAId,CAAQ,IAAK,OAAO,QAAQL,CAAS,EACnDkB,EAAIC,CAAE,EAAId,EAAS,IAAKI,GAAM,CAC5B,IAAMW,EAAIX,EAAE,EAAIC,EACVW,EAAIZ,EAAE,EAAIE,EAChB,MAAO,CAAE,EAAGD,EAAKM,EAAII,EAAIH,EAAII,EAAG,EAAGV,EAAKM,EAAIG,EAAIJ,EAAIK,CAAE,CACxD,CAAC,EAEH,IAAIC,EAAQ,EACRC,EAAQ,EACZ,QAAWrB,KAAQH,EAAM,MACvB,GAAI,CAAAI,EAAWD,CAAI,EAGnB,QAAWO,KAAKS,EAAIhB,EAAK,EAAE,GAAK,CAAC,EAC3BO,EAAE,EAAIE,EACRW,IAEAC,IAIN,GAAIA,EAAQD,EACV,QAAWjB,KAAY,OAAO,OAAOa,CAAG,EACtC,QAAWT,KAAKJ,EACdI,EAAE,EAAI,EAAIE,EAAKF,EAAE,EAIvB,OAAOS,CACT,CChEA,SAASM,GAASC,EAAKC,EAAM,CAC3B,IAAMC,EAAUF,EAAI,QAAQ,GAAG,EACzBG,EAAUH,EAAI,QAAQ,IAAKE,EAAU,CAAC,EAC5C,GAAIA,IAAY,IAAMC,IAAY,GAAI,CACpC,IAAMC,EAAOJ,EAAI,MAAM,EAAGE,CAAO,EAC3BG,EAAOL,EAAI,MAAME,EAAU,EAAGC,CAAO,EACrCG,EAAMN,EAAI,MAAMG,EAAU,CAAC,EAC7BE,IAAS,KAAOA,IAAS,IAC3BJ,EAAKG,CAAI,EAAI,CAACE,EACLD,IAAS,MAClBJ,EAAKG,CAAI,EAAIE,EAEjB,CACF,CACA,SAASC,GAAUC,EAAQ,CACzB,IAAMP,EAAO,CAAC,EACd,QAAWQ,KAASD,EAClBT,GAASU,EAAOR,CAAI,EAEtB,OAAOA,CACT,CACA,SAASS,GAAiBC,EAAM,CAC9B,GAAM,CAAE,GAAAC,EAAI,GAAAC,EAAI,GAAAC,CAAG,EAAIH,EAAK,KAC5B,OAAO,OAAOC,GAAO,UAAY,OAAOC,GAAO,UAAY,OAAOC,GAAO,SAAW,CAAE,QAASF,EAAI,MAAOC,EAAI,KAAMC,CAAG,EAAI,MAC7H,CACA,IAAIC,GAAK,GACLC,GAAK,GACT,SAASC,GAAcC,EAAM,CAC3B,IAAMC,EAAW,CAAC,EACdC,EAAS,IACTC,EAAQ,EACZ,SAASC,EAAKC,EAAK,CACbA,EAAMF,GACRF,EAAS,KAAK,CAAE,GAAID,EAAK,MAAMG,EAAOE,CAAG,EAAG,OAAAH,CAAO,CAAC,CAExD,CACA,QAASI,EAAI,EAAGA,EAAIN,EAAK,OAAQM,IAAK,CACpC,IAAMC,EAAKP,EAAK,WAAWM,CAAC,GACxBC,IAAOV,IAAMU,IAAOT,MACtBM,EAAKE,CAAC,EACNJ,EAASK,IAAOV,GAAK,IAAM,IAC3BM,EAAQG,EAAI,EAEhB,CACA,OAAAF,EAAKJ,EAAK,MAAM,EACTC,CACT,CACA,SAASO,GAASC,EAAM,CACtB,IAAMC,EAAQ,CACZ,MAAO,CAAC,EACR,MAAO,CAAC,EACR,MAAO,CAAC,EACR,MAAO,CAAC,EACR,OAAQ,CAAC,EACT,GAAI,EACN,EACA,QAAWC,KAAWF,EAAK,MAAM;AAAA,CAAI,EAAG,CACtC,IAAMG,EAAOD,EAAQ,SAAS,IAAI,EAAIA,EAAQ,MAAM,EAAG,EAAE,EAAIA,EAC7D,GAAIC,EAAK,WAAW,GAAG,EAAG,CACxB,GAAM,CAAC,CAAE,GAAGC,CAAI,EAAID,EAAK,MAAM,GAAG,EAClCF,EAAM,OAAO,KAAKrB,GAAUwB,CAAI,CAAC,CACnC,SAAWD,EAAK,WAAW,GAAG,EAAG,CAC/B,GAAM,CAAC,CAAE1B,EAAM,GAAG2B,CAAI,EAAID,EAAK,MAAM,GAAG,EACpCE,EACAC,EACAC,EACAC,EAAO,GACLC,EAAQL,EAAK,CAAC,GAAK,IACrB,QAAQ,KAAKK,CAAK,GACpBJ,EAAM,CAACI,EACPH,EAAMF,EAAK,CAAC,GAAK,IACjBG,EAAYH,EAAK,MAAM,CAAC,IAExBI,EAAO,GACPF,EAAMG,EACNJ,EAAMC,IAAQ,IAAM,EAAIA,EAAI,OAC5BC,EAAYH,EAAK,MAAM,CAAC,GAE1B,IAAM9B,EAAOM,GAAU2B,CAAS,EAC5BC,GAAQ,OAAQlC,IAClB+B,EAAM,CAAC/B,EAAK,IAEd2B,EAAM,MAAM,KAAK,CAAE,GAAIxB,EAAM,OAAQ4B,EAAK,SAAUC,EAAK,KAAAhC,CAAK,CAAC,CACjE,SAAW6B,EAAK,WAAW,GAAG,EAAG,CAC/B,GAAM,CAAC,CAAE,CAAEO,EAAQC,EAAQ,CAAE,CAAE,CAAE,CAAEC,EAAO,GAAGR,CAAI,EAAID,EAAK,MAAM,GAAG,EAC/DO,GAAUC,GACZV,EAAM,MAAM,KAAK,CACf,OAAQS,EAAO,MAAM,EAAG,EAAE,EAC1B,OAAQC,EAAO,MAAM,EAAG,EAAE,EAC1B,QAASD,EAAO,GAAG,EAAE,EACrB,QAASC,EAAO,GAAG,EAAE,EACrB,MAAOC,GAAS,IAChB,KAAMhC,GAAUwB,CAAI,CACtB,CAAC,CAEL,SAAWD,EAAK,WAAW,GAAG,EAAG,CAC/B,GAAM,CAAC,CAAEO,EAAQG,EAASF,EAAQG,EAASF,EAAO,GAAGR,CAAI,EAAID,EAAK,MAAM,GAAG,EACvEO,GAAUC,GAAUG,GACtBb,EAAM,MAAM,KAAK,CACf,OAAAS,EACA,OAAAC,EACA,QAAAE,EACA,QAAAC,EACA,MAAOF,GAAS,IAChB,KAAMhC,GAAUwB,CAAI,CACtB,CAAC,CAEL,SAAWD,EAAK,WAAW,GAAG,EAAG,CAC/B,GAAM,CAAC,CAAEY,EAAQC,EAAKC,EAAQvB,EAAOE,EAAKL,EAAM,GAAGa,CAAI,EAAID,EAAK,MAAM,GAAG,EACrEY,GAAUC,GAAOC,GAAUvB,GAASE,GAAOL,GAC7CU,EAAM,MAAM,KAAK,CACf,OAAAc,EACA,UAAW,CAACC,EACZ,OAAAC,EACA,MAAOvB,IAAU,IAAM,GAAK,CAACA,EAC7B,IAAKE,IAAQ,IAAM,GAAK,CAACA,EACzB,SAAUN,GAAcC,CAAI,EAC5B,KAAMX,GAAUwB,CAAI,CACtB,CAAC,CAEL,SAAWD,EAAK,WAAW,GAAG,EAAG,CAC/B,GAAM,CAAC,CAAE1B,EAAMyC,EAAM,GAAGd,CAAI,EAAID,EAAK,MAAM,GAAG,EAC1C1B,GAAQyC,GACVjB,EAAM,MAAM,KAAK,CAAE,KAAAxB,EAAM,KAAAyC,EAAM,KAAAd,CAAK,CAAC,CAEzC,CACF,CACA,OAAOH,CACT,CCxHA,SAASkB,GAAeC,EAAU,CAChC,IAAMC,EAA4B,IAAI,IAChCC,EAA6B,IAAI,IACvC,SAASC,EAAMC,EAAIC,EAAQ,CACpBJ,EAAU,IAAIG,CAAE,GACnBH,EAAU,IAAIG,EAAIC,CAAM,CAE5B,CACA,SAASC,EAASF,EAAIC,EAAQ,CAC5BF,EAAMC,EAAIC,CAAM,EAChBH,EAAW,IAAIE,GAAKF,EAAW,IAAIE,CAAE,GAAK,GAAK,CAAC,CAClD,CACA,QAAWG,KAAQP,EAAS,MAC1BG,EAAMI,EAAK,OAAQA,EAAK,UAAY,IAAM,IAAM,GAAG,EACnDJ,EAAMI,EAAK,OAAQA,EAAK,UAAY,IAAM,IAAM,GAAG,EAErD,QAAWC,KAAWR,EAAS,MAC7B,QAAWS,KAAWD,EAAQ,KAAK,MAAM,GAAG,EAC1CF,EAASG,EAAQ,MAAM,EAAG,EAAE,EAAGA,EAAQ,SAAS,GAAG,EAAI,IAAM,GAAG,EAGpE,QAAWC,KAAQV,EAAS,MAC1B,QAAWW,KAAOD,EAAK,SACrBJ,EAASK,EAAI,GAAIA,EAAI,SAAW,IAAM,IAAM,GAAG,EAGnD,MAAO,CAAE,UAAAV,EAAW,WAAAC,CAAW,CACjC,CACA,IAAIU,GAAaC,GAAMA,EAAE,QAAU,GAAK,EAAIA,EAAE,MAC9C,SAASC,GAAgBd,EAAU,CACjC,MAAO,CACL,GAAGA,EAAS,MAAM,IAAKe,IAAO,CAC5B,GAAGC,EAAWD,EAAE,IAAI,EACpB,MAAOA,EAAE,KAAK,MAAM,GAAG,EAAE,IAAKN,IAAa,CACzC,GAAIA,EAAQ,MAAM,EAAG,EAAE,EACvB,OAAQA,EAAQ,SAAS,GAAG,EAAI,IAAM,GACxC,EAAE,CACJ,EAAE,EACF,GAAGT,EAAS,MAAM,IAAKa,IAAO,CAC5B,KAAM,GAAGA,EAAE,MAAM,IAAIA,EAAE,SAAS,IAAIA,EAAE,MAAM,GAC5C,MAAOD,GAAUC,CAAC,EAClB,MAAOA,EAAE,SAAS,IAAKI,IAAO,CAC5B,GAAIA,EAAE,GACN,OAAQA,EAAE,SAAW,IAAM,IAAM,GACnC,EAAE,CACJ,EAAE,CACJ,CACF,CACA,SAASC,GAAeC,EAAS,CAC/B,IAAMC,EAAKD,EAAQ,KAAK,GACxB,GAAI,OAAOC,GAAO,SAChB,OAEF,IAAMC,EAAUD,EAAG,MAAM,GAAG,EAAE,IAAKH,GAAMA,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,EACjE,OAAOI,EAAQ,OAAS,EAAIA,EAAU,MACxC,CACA,IAAIC,GAAYC,GAAM,OAAOA,GAAM,UAAYA,EAAI,EAAIA,EAAI,OAC3D,SAASC,GAAY,CAAE,KAAAC,EAAM,OAAAC,CAAO,EAAG,CACrC,IAAMC,EAAQL,GAASG,EAAK,EAAE,GAAKH,GAASG,EAAK,EAAE,GAAKH,GAASG,EAAK,EAAE,EACxE,OAAOH,GAASG,EAAK,EAAE,GAAKH,GAASG,EAAK,EAAE,IAAME,IAAU,QAAUD,EAAS,EAAIC,EAAQD,EAAS,OACtG,CACA,SAASE,GAAST,EAASd,EAAQwB,EAAO,CACxC,MAAO,CACL,GAAI,GAAGV,EAAQ,EAAE,GAAGd,CAAM,GAC1B,KAAMc,EAAQ,GACd,OAAQA,EAAQ,OAChB,MAAAU,EACA,OAAQC,GAAiBX,CAAO,EAChC,QAASD,GAAeC,CAAO,CACjC,CACF,CACA,SAASY,GAAkB/B,EAAUgC,EAAO,eAAgB,CAC1D,IAAMC,EAAQ,CAAC,EACTC,EAAQ,CAAC,EACT,CAAE,UAAAjC,EAAW,WAAAC,CAAW,EAAIH,GAAeC,CAAQ,EACnDmC,EAAUC,GAAc,GAAGA,CAAS,GAAGnC,EAAU,IAAImC,CAAS,GAAK,GAAG,GAC5E,QAAWjB,KAAWnB,EAAS,MAAO,CACpC,IAAM6B,EAAQL,GAAYL,CAAO,GAAK,KAAK,IAAIjB,EAAW,IAAIiB,EAAQ,EAAE,GAAK,EAAG,CAAC,EACjFc,EAAM,KAAKL,GAAST,EAASlB,EAAU,IAAIkB,EAAQ,EAAE,GAAK,IAAKU,CAAK,CAAC,CACvE,CACA,QAAWtB,KAAQP,EAAS,MAC1BkC,EAAM,KAAK,CACT,KAAMC,EAAO5B,EAAK,MAAM,EACxB,GAAI4B,EAAO5B,EAAK,MAAM,EACtB,WAAYA,EAAK,UAAY,IAAM,IAAM,IACzC,SAAUA,EAAK,UAAY,IAAM,IAAM,GACzC,CAAC,EAEH,IAAM8B,EAAQ,CAAC,EACTC,EAAiC,IAAI,IACrCC,EAAU,CAACC,EAAG,IAAM,CAACA,EAAG,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,EACjD,SAASC,EAAgBC,EAASC,EAAO,CACvC,QAASC,EAAI,EAAGA,EAAIF,EAAQ,OAAS,EAAGE,IAAK,CAC3C,IAAMC,EAAMN,EAAQG,EAAQE,CAAC,EAAGF,EAAQE,EAAI,CAAC,CAAC,EACzCN,EAAe,IAAIO,CAAG,GACzBP,EAAe,IAAIO,EAAqB,IAAI,GAAK,EAEnDP,EAAe,IAAIO,CAAG,EAAE,IAAIF,CAAK,CACnC,CACF,CACA,QAAWnC,KAAWR,EAAS,MAAO,CACpC,IAAM0C,EAAUlC,EAAQ,KAAK,MAAM,GAAG,EAAE,IAAKC,GAAY0B,EAAO1B,EAAQ,MAAM,EAAG,EAAE,CAAC,CAAC,EACrF4B,EAAM,KAAK,CACT,KAAM7B,EAAQ,KACd,QAAAkC,EACA,MAAO1B,EAAWR,EAAQ,IAAI,EAAE,KAClC,CAAC,EACDiC,EAAgBC,EAASlC,EAAQ,IAAI,CACvC,CACA,QAAWE,KAAQV,EAAS,MAAO,CACjC,IAAM0C,EAAUhC,EAAK,SAAS,IAAKC,GAAQwB,EAAOxB,EAAI,EAAE,CAAC,EACnDgC,EAAQ,GAAGjC,EAAK,MAAM,IAAIA,EAAK,SAAS,IAAIA,EAAK,MAAM,GAC7D2B,EAAM,KAAK,CACT,KAAMM,EACN,QAAAD,EACA,MAAO9B,GAAUF,CAAI,EACrB,OAAQA,EAAK,OACb,UAAWA,EAAK,UAChB,OAAQA,EAAK,MACf,CAAC,EACD+B,EAAgBC,EAASC,CAAK,CAChC,CACA,QAAWG,KAAQZ,EAAO,CACxB,IAAMa,EAAUT,EAAe,IAAIC,EAAQO,EAAK,KAAMA,EAAK,EAAE,CAAC,EAC1DC,GAAWA,EAAQ,KAAO,IAC5BD,EAAK,QAAU,CAAC,GAAGC,CAAO,EAE9B,CACA,IAAMC,EAAU,IAAI,IAAIhD,EAAS,MAAM,IAAKiD,GAAM,CAACA,EAAE,GAAIA,EAAE,MAAM,CAAC,CAAC,EAC7DC,EAAYlD,EAAS,MAAM,OAAS,GAAKA,EAAS,MAAM,OAAS,EAAImD,GAAYrC,GAAgBd,CAAQ,EAAII,GAAO4C,EAAQ,IAAI5C,CAAE,GAAK,CAAC,EAAI,OAClJ,MAAO,CACL,KAAA4B,EACA,MAAAC,EACA,MAAAC,EACA,MAAOG,EAAM,OAAS,EAAIA,EAAQ,OAClC,YAAaa,GAAW,YACxB,WAAYA,GAAW,WAGvB,WAAYjB,EAAM,KAAMgB,GAAMA,EAAE,MAAM,EAAI,OAAS,MACrD,CACF,CCrJA,IAAIG,GAAW,cACXC,GAAiB,GACrB,SAASC,GAAmBC,EAAOC,EAAWC,EAA0B,IAAI,IAAO,CACjF,IAAMC,EAAS,IAAI,IACjBF,EAAU,IAAKG,GAAM,CAACA,EAAE,UAAW,GAAGP,EAAQ,GAAGO,EAAE,SAAS,EAAE,CAAC,CACjE,EACMC,EAAQ,CAAC,EACf,OAAAL,EAAM,MAAM,QAAQ,CAACM,EAAMC,IAAO,CAChC,IAAMC,EAAKL,EAAO,IAAII,CAAE,EACxB,GAAI,CAAAL,EAAQ,IAAIK,CAAE,EAGlB,GAAIC,IAAO,OACTH,EAAM,KAAKC,CAAI,MACV,CACL,GAAM,CAAE,WAAAG,EAAY,SAAAC,CAAS,EAAIJ,EACjCD,EAAM,KACJ,CAAE,KAAMC,EAAK,KAAM,GAAIE,EAAI,GAAGC,EAAa,CAAE,WAAAA,CAAW,EAAI,CAAC,CAAE,EAC/D,CAAE,KAAMD,EAAI,GAAIF,EAAK,GAAI,GAAGI,EAAW,CAAE,SAAAA,CAAS,EAAI,CAAC,CAAE,CAC3D,CACF,CACF,CAAC,EACM,CACL,MAAO,CACL,GAAGV,EACH,MAAO,CACL,GAAGA,EAAM,MACT,GAAG,CAAC,GAAGG,EAAO,OAAO,CAAC,EAAE,IAAKK,IAAQ,CACnC,GAAAA,EACA,KAAMA,EACN,OAAQ,EACR,MAAO,CACT,EAAE,CACJ,EACA,MAAAH,CACF,EACA,OAAAF,EACA,IAAK,IAAI,IAAIA,EAAO,OAAO,CAAC,CAC9B,CACF,CACA,SAASQ,GAAWX,EAAOC,EAAWE,EAAQS,EAASC,EAAM,CAC3D,IAAMC,EAAU,IAAI,IAAId,EAAM,MAAM,IAAKe,GAAM,CAACA,EAAE,GAAIA,EAAE,MAAM,CAAC,CAAC,EAChE,OAAOd,EAAU,IAAKG,GAAM,CAC1B,IAAMY,EAAUZ,EAAE,SAAS,OACzB,CAACa,EAAKC,IAAQD,GAAOH,EAAQ,IAAII,CAAG,GAAK,GACzC,CACF,EACMC,EAAQ,KAAK,IACjBN,EAAK,kBACLD,EAAQI,CAAO,EAAIlB,EACrB,EACMU,EAAKL,EAAO,IAAIC,EAAE,SAAS,EACjC,MAAO,CACL,GAAAI,EACA,KAAMA,EACN,OAAQ,KAAK,MAAMW,EAAQ,IAAMN,EAAK,qBAAqB,EAC3D,MAAO,CACT,CACF,CAAC,CACH,CACA,SAASO,GAAWC,EAAWlB,EAAQ,CACrC,IAAMmB,EAAgB,CAAE,GAAGD,CAAU,EAC/BE,EAAiB,CAAC,EACxB,OAAW,CAACC,EAAWhB,CAAE,IAAKL,EAAQ,CACpC,IAAMsB,EAAQH,EAAcd,CAAE,EAC9B,OAAOc,EAAcd,CAAE,EACnBiB,GAAO,SACTF,EAAeC,CAAS,EAAIC,EAEhC,CACA,MAAO,CAAE,cAAAH,EAAe,eAAAC,CAAe,CACzC,CC/BA,SAASG,GAAUC,EAAMC,EAAMC,EAAO,CAAC,EAAG,CACxC,IAAMC,EAAQC,GACZC,GAAkBC,GAASN,CAAI,EAAGC,CAAI,EACtCC,EAAK,aACP,EACA,GAAIC,EAAM,MAAM,SAAW,EACzB,MAAM,IAAI,MAAM,wBAAwBF,CAAI,EAAE,EAEhD,GAAIC,EAAK,WAAa,QAAUC,EAAM,MAAM,OAASD,EAAK,SACxD,MAAM,IAAI,MACR,4BAA4BC,EAAM,MAAM,OAAO,eAAe,CAAC,iBAAiBD,EAAK,SAAS,eAAe,CAAC,sEAChH,EAEF,OAAOC,CACT,CACA,IAAII,GAAkB,CACpB,OAAQ,OACR,QAAS,EACT,aAAc,GACd,aAAc,OACd,QAAS,EACT,oBAAqB,EACrB,kBAAmB,EACrB,EACA,SAASC,GAAiBC,EAAI,CAAC,EAAG,CAChC,MAAO,CACL,OAAQA,EAAE,QAAUF,GAAgB,OACpC,QAASE,EAAE,SAAWF,GAAgB,QACtC,aAAcE,EAAE,cAAgBF,GAAgB,aAChD,aAAcE,EAAE,cAAgBF,GAAgB,aAChD,QAASE,EAAE,SAAWF,GAAgB,QACtC,oBAAqBE,EAAE,qBAAuBF,GAAgB,oBAC9D,kBAAmBE,EAAE,mBAAqBF,GAAgB,iBAC5D,CACF,CACA,IAAIG,GAAuB,GAC3B,SAASC,GAAcR,EAAOS,EAASC,EAAU,CAC/C,IAAMC,EAAWX,EAAM,MAAM,KAAKY,CAAU,EACtCC,EAAS,CACb,GAAGJ,EACH,KAAM,CACJ,GAAGA,EAAQ,KACX,WAAYA,EAAQ,KAAK,YAAcC,EAAS,SAAW,EAC7D,CACF,EACA,MAAO,CACL,MAAO,CACL,MAAOC,EAAWG,GAAYd,EAAOa,CAAM,EAAIA,EAAO,MACtD,MAAOb,EAAM,KACf,EACA,QAAS,CACP,QAASU,EAAS,QAClB,aAAcA,EAAS,aACvB,GAAGG,EAAO,KACV,oBAAqBN,IAAwBG,EAAS,qBAAuB,GAC7E,GAAGC,EAAW,CAAE,iBAAkB,EAAM,EAAI,CAAC,EAC7C,OAAQD,EAAS,QAAU,MAC7B,CACF,CACF,CACA,SAASK,GAAUf,EAAOU,EAAU,CAClC,IAAMC,EAAWX,EAAM,MAAM,KAAKY,CAAU,EAC5C,MAAO,GAAGF,EAAS,QAAU,MAAM,IAAIA,EAAS,OAAO,IAAIA,EAAS,YAAY,IAAIA,EAAS,YAAY,IAAIA,EAAS,SAAW,CAAC,IAAIA,EAAS,qBAAuB,CAAC,IAAIA,EAAS,oBAAsB,EAAK,IAAIC,CAAQ,IAAIX,EAAM,eAAiB,EAAE,EAC1P,CACA,eAAegB,GAAYhB,EAAOU,EAAUO,EAAQ,CAClD,IAAMC,EAASC,GAAUT,EAAS,YAAY,EACxCU,EAAQC,GAAcrB,CAAK,EAC3BsB,EAAUZ,EAAS,oBAAsB,GAAQa,GAAkBvB,EAAOoB,CAAK,EAAoB,IAAI,IACvGI,EAAYJ,EAAM,OAAQK,GAAM,CAACH,EAAQ,IAAIG,EAAE,SAAS,CAAC,EACzDC,EAASC,GAAmB3B,EAAOwB,EAAWF,CAAO,EACrDM,EAASC,GAAUH,EAAO,MAAOA,EAAO,GAAG,EAC3CI,EAAO,CACX,GAAGF,EAAO,MACV,MAAOA,EAAO,MAAM,MAAM,OAAQG,GAAM,CAACL,EAAO,IAAI,IAAIK,EAAE,EAAE,CAAC,CAC/D,EACMC,EAAgBC,GAAcH,EAAMZ,CAAM,EAC1C,CAAE,OAAAgB,EAAQ,SAAAC,CAAS,EAAI,MAAMlB,EACjCT,GACEoB,EAAO,MACP,CACE,GAAGI,EACH,MAAO,CACL,GAAGA,EAAc,MACjB,GAAGI,GACDpC,EACAwB,EACAE,EAAO,OACPW,GAAcP,EAAMZ,CAAM,EAC1Bc,EAAc,IAChB,CACF,CACF,EACAtB,CACF,CACF,EACMD,EAAUwB,GAAcjC,EAAOkB,CAAM,EACrCoB,EAAQ,IAAI,IAChB7B,EAAQ,MAAM,IAAKsB,GAAM,CAACA,EAAE,GAAIQ,GAAgB9B,EAAQ,KAAMsB,EAAE,MAAM,CAAC,CAAC,CAC1E,EACMS,EAAYC,GAChBP,EAAO,cACPN,EAAO,KACNc,GAAOJ,EAAM,IAAII,CAAE,GAAK,CAC3B,EACM,CAAE,cAAAC,EAAe,eAAAC,CAAe,EAAIC,GACxC7C,EAAM,MAAM,KAAKY,CAAU,EAAIkC,GAAkB9C,EAAOwC,CAAS,EAAIA,EACrEd,EAAO,MACT,EACA,MAAO,CACL,OAAQ,CACN,GAAGQ,EACH,cAAAS,EACA,SAAU,GACV,GAAGnB,EAAU,OAAS,CAAE,eAAAoB,EAAgB,OAAQG,GAAaH,CAAc,CAAE,EAAI,CAAC,CACpF,EACA,SAAAT,CACF,CACF,CACA,SAASY,GAAaJ,EAAe,CACnC,IAAIK,EAAO,IACPC,EAAO,IACPC,EAAO,KACPC,EAAO,KACX,QAAWC,KAAY,OAAO,OAAOT,CAAa,EAChD,QAAWU,KAAOD,EAChBJ,EAAO,KAAK,IAAIA,EAAMK,EAAI,CAAC,EAC3BJ,EAAO,KAAK,IAAIA,EAAMI,EAAI,CAAC,EAC3BH,EAAO,KAAK,IAAIA,EAAMG,EAAI,CAAC,EAC3BF,EAAO,KAAK,IAAIA,EAAME,EAAI,CAAC,EAG/B,MAAO,CAAE,KAAAL,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,CAAK,CAClC,CACA,IAAIG,EAAc,GACdC,GAAW,KACXC,GAAW,IACf,SAASC,GAAUC,EAAM,CACvB,OAAO,KAAK,IAAIH,GAAU,KAAK,IAAIC,GAAUE,CAAI,CAAC,CACpD,CACA,SAASC,GAAiBC,EAAQC,EAAcC,EAAQC,EAAST,EAAa,CAC5E,IAAMU,EAAYH,EAAeD,EAAO,EAAIE,EAC5C,OAAOC,EAASH,EAAO,KAAOE,EAAS,KAAK,IAAI,EAAGE,CAAS,EAAI,CAClE,CACA,SAASC,GAAaL,EAAQM,EAAWC,EAAYC,EAAW,CAC9D,SAAAC,EAAW,EACX,QAAAC,EAAUhB,EACV,OAAAS,EAAST,EACT,SAAAiB,EAAWjB,EACX,UAAAkB,EAAYlB,CACd,EAAI,CAAC,EAAG,CACN,IAAMmB,EAAcP,EAAYI,EAAUC,EACpCV,EAAeM,EAAaJ,EAASS,EAC3C,GAAIC,GAAe,GAAKZ,GAAgB,GAAK,EAAED,EAAO,EAAI,GAAK,CAACQ,GAAaR,EAAO,EAAI,GACtF,OAEF,IAAMc,EAAOd,EAAO,EAAI,EAAIa,EAAcb,EAAO,EAAI,IAC/Ce,EAAOf,EAAO,EAAI,EAAIC,EAAeD,EAAO,EAAI,IAChDgB,EAAQnB,GACZ,KAAK,IAAIY,EAAUD,EAAYM,EAAO,KAAK,IAAIA,EAAMC,CAAI,CAAC,CAC5D,EACME,EAAYJ,EAAcb,EAAO,EAAIgB,EAC3C,MAAO,CACL,MAAAA,EACA,WAAYN,EAAUV,EAAO,KAAOgB,EAAQ,KAAK,IAAI,EAAGC,CAAS,EAAI,EACrE,WAAYlB,GACVC,EACAC,EACAO,EAAY,EAAIQ,EAChBb,CACF,CACF,CACF,CACA,SAASe,GAAcC,EAAQhF,EAAO,CAAC,EAAG,CACxC,GAAI,CAAE,KAAAiD,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,CAAK,EAAIJ,GAAagC,EAAO,aAAa,EAC5D,CAAE,OAAAC,CAAO,EAAIjF,EACfgF,EAAO,eAAiBC,GAAUA,EAAO,IAAMA,EAAO,QACxDhC,EAAOgC,EAAO,MACd9B,EAAO8B,EAAO,KAEhB,IAAMC,EAASlF,EAAK,QAAUgF,EAAO,OACrC,OAAIE,IACFjC,EAAO,KAAK,IAAIA,EAAMiC,EAAO,MAAQjC,CAAI,EACzCC,EAAO,KAAK,IAAIA,EAAMgC,EAAO,MAAQhC,CAAI,EACzCC,EAAO,KAAK,IAAIA,EAAM+B,EAAO,MAAQ/B,CAAI,EACzCC,EAAO,KAAK,IAAIA,EAAM8B,EAAO,MAAQ9B,CAAI,GAEpC,CAAE,KAAAH,EAAM,KAAAC,EAAM,EAAGC,EAAOF,EAAM,EAAGG,EAAOF,CAAK,CACtD,CC9NA,IAAIiC,GAAe,EACnB,SAASC,GAAuBC,EAAOF,GAAc,CACnD,IAAMG,EAAyB,IAAI,QAC7BC,EAAWC,GAAU,CACzB,IAAIC,EAAQH,EAAO,IAAIE,CAAK,EAC5B,OAAKC,IACHA,EAAwB,IAAI,IAC5BH,EAAO,IAAIE,EAAOC,CAAK,GAElBA,CACT,EACA,MAAO,CACL,OAAOD,EAAOE,EAAUC,EAAQ,CAC9B,IAAMF,EAAQF,EAAQC,CAAK,EACrBI,EAAMC,GAAUL,EAAOE,CAAQ,EAC/BI,EAAML,EAAM,IAAIG,CAAG,EACzB,GAAIE,EACF,OAAOA,EAAI,IAETL,EAAM,MAAQJ,GAChBI,EAAM,OAAOA,EAAM,KAAK,EAAE,KAAK,EAAE,KAAK,EAExC,IAAMM,EAAU,YAAY,IAAI,EAC1BC,EAAQ,CACZ,IAAKC,GAAYT,EAAOE,EAAUC,CAAM,EAAE,KAAMO,IAC9CF,EAAM,KAAOE,EAAE,OACR,CAAE,GAAGA,EAAG,SAAUA,EAAE,UAAY,YAAY,IAAI,EAAIH,CAAQ,EACpE,CACH,EACA,OAAAC,EAAM,IAAI,MAAM,IAAMP,EAAM,OAAOG,CAAG,CAAC,EACvCH,EAAM,IAAIG,EAAKI,CAAK,EACbA,EAAM,GACf,EACA,MAAMR,EAAOE,EAAU,CACrB,OAAOJ,EAAO,IAAIE,CAAK,GAAG,IAAIK,GAAUL,EAAOE,CAAQ,CAAC,GAAG,IAC7D,EACA,QAAQS,EAAMC,EAAI,CAChB,IAAMX,EAAQH,EAAO,IAAIa,CAAI,EACzBV,GAASU,IAASC,GACpBd,EAAO,IAAIc,EAAIX,CAAK,CAExB,CACF,CACF,CC5CA,SAASY,GAAYC,EAAOC,EAAW,CACrC,MAAO,CAAE,OAAQD,EAAO,OAAQC,EAAY,EAAID,EAAO,UAAAC,CAAU,CACnE,CACA,SAASC,GAAWC,EAAGC,EAAMC,EAAOC,EAAQ,CAC1C,MAAO,CACL,KAAM,CAACH,EAAE,WAAaC,EAAK,OAC3B,KAAM,CAACD,EAAE,WAAaC,EAAK,OAC3B,MAAOC,EAAQF,EAAE,YAAcC,EAAK,OACpC,MAAOE,EAASH,EAAE,YAAcC,EAAK,MACvC,CACF,CACA,SAASG,GAAOC,EAAGC,EAAO,CACxB,IAAMC,GAAKF,EAAE,KAAOA,EAAE,MAAQC,EACxBE,GAAKH,EAAE,KAAOA,EAAE,MAAQC,EAC9B,MAAO,CACL,KAAMD,EAAE,KAAOE,EACf,KAAMF,EAAE,KAAOG,EACf,KAAMH,EAAE,KAAOE,EACf,KAAMF,EAAE,KAAOG,CACjB,CACF,CACA,SAASC,GAASC,EAAOC,EAAO,CAC9B,OAAOA,EAAM,MAAQD,EAAM,MAAQC,EAAM,MAAQD,EAAM,MAAQC,EAAM,MAAQD,EAAM,MAAQC,EAAM,MAAQD,EAAM,IACjH,CACA,SAASE,GAAUZ,EAAGa,EAAQC,EAASC,EAASjB,EAAW,CACzD,IAAMD,EAAQmB,GAAUhB,EAAE,MAAQa,CAAM,EAClCI,EAAQpB,EAAQG,EAAE,MACxB,MAAO,CACL,MAAAH,EACA,WAAYiB,GAAWA,EAAUd,EAAE,YAAciB,EACjD,WAAYnB,EAAYE,EAAE,WAAae,GAAWA,EAAUf,EAAE,YAAciB,CAC9E,CACF,CR5BA,IAAAC,EAAsB,UACtBC,GAAqC,USVrC,IAAAC,GAAsB,UAKtB,SAASC,GAA+BC,EAAsB,CAC5D,OAAQC,GACND,EAAO,SAASC,CAAU,EAAKA,EAAc,MACjD,CAEO,SAASC,GAAmCF,EAAa,CAC9D,OAAO,SAAM,kBAAkB,SAAM,MAAM,SAAM,YAAYA,CAAM,CAAC,EAAG,CACrE,aAAcD,GAAaC,CAAM,CACnC,CAAC,CACH,CAEO,SAASG,GACdH,EACAI,EACA,CACA,OAAO,SAAM,kBACX,SAAM,SAAS,SAAM,YAAYJ,CAAM,EAAGI,CAAQ,EAClD,CAAE,aAAcL,GAAaC,CAAM,CAAE,CACvC,CACF,CTSO,IAAMK,GAAoB,IAGpBC,GAAoB,IAEpBC,GAAgD,CAAC,EAAG,EAAG,EAAG,CAAC,EAC3DC,GAA+C,CAC1D,IAAM,IAAM,IAAM,CACpB,EACaC,GAAW,CAAC,CAACC,EAAGC,EAAGC,CAAC,IAC/B,OAAO,CAACF,EAAGC,EAAGC,CAAC,EAAE,IAAIC,GAAK,KAAK,MAAMA,EAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,IAE/CC,GAAkB,EAElBC,GAAiB,IAAI,IAAY,CAAC,UAAW,YAAY,CAAC,EAE1DC,MAAsB,SACjC,IAAM,OAAO,0CAAmC,CAClD,EACaC,MAAoB,SAC/B,IAAM,OAAO,wCAAiC,CAChD,EAIaC,GAAkB,GAKzBC,GAAa,QAAM,kBACvB,QAAM,MAAM,aAAc,CACxB,MAAO,QAAM,SAAS,QAAM,YAAY,CAAC,GAAI,OAAQ,QAAQ,CAAC,EAAG,EAAE,EACnE,OAAQ,QAAM,SAAS,QAAM,OAAiB,EAAG,CAAC,CAAC,EACnD,QAAS,QAAM,MAAM,QAAM,MAAM,CACnC,CAAC,EACD,CACE,aAAeC,GAAiCC,GAAeD,CAAI,CACrE,CACF,EAKaE,GAAiB,CAC5B,CAAE,GAAI,EAAG,MAAO,MAAO,EACvB,CAAE,GAAI,EAAG,MAAO,YAAa,EAC7B,CAAE,GAAI,GAAI,MAAO,aAAc,EAC/B,CAAE,GAAI,GAAI,MAAO,0CAA2C,EAC5D,CAAE,GAAI,IAAM,MAAO,YAAa,CAClC,EAEMC,GAAkB,eAIjB,SAASC,GAAaC,EAAwC,CACnE,GAAI,OAAOA,EAAc,KAAQ,SAC/B,OAAOA,EAAc,IAIvB,IAAMC,EAFWD,EAAc,kBAET,IACtB,OAAO,OAAOC,GAAQ,UAAYA,EAAI,SAASH,EAAe,EAC1DG,EAAI,MAAM,EAAG,CAACH,GAAgB,MAAM,EACpC,MACN,CACO,IAAMI,GAAiB,IACjBC,GAAkB,IAClBC,GAAuB,IACvBC,GAAuB,EAEvBC,GAAiB,GAGjBC,GAA2B,CACtC,YAAa,CAAC,EACd,eAAgB,IAAI,IACpB,OAAQ,CAAC,EACT,UAAW,IAAI,IACf,WAAY,CAAC,EACb,cAAe,IAAI,GACrB,EAKO,SAASC,MAAYC,EAAoB,CAAC,CA8B1C,IAAMC,GAAsB,IAG5B,SAASC,GAAaC,EAAY,CACvC,OAAOA,GAAM,IACT,GAAG,EAAEA,EAAK,KAAW,QAAQ,CAAC,CAAC,MAC/B,GAAG,KAAK,MAAMA,EAAK,GAAI,CAAC,KAC9B,CAUO,IAAMC,GAA0B,IAGhC,SAASC,GAAMC,EAAoC,CACxD,OAAOA,GAAY,QAASA,GAAYA,EAAS,IAC7C,IAAI,IAAIA,EAAS,IAAKA,EAAS,SAAW,OAAO,SAAS,IAAI,EAAE,KAChE,MACN,CAUO,SAASC,GAAgBC,EAK7B,CACD,OACEA,EAAM,gBAAkB,QACxBA,EAAM,kBAAoBA,EAAM,eAChCA,EAAM,cAAc,gBAAkBA,EAAM,eAC5C,CAACA,EAAM,sBAEX,CAGO,SAASC,GAAeD,EAKpB,CACT,GAAM,CAAE,MAAAE,EAAO,OAAAC,CAAO,EAAIH,EAAM,QAChC,OAAOI,GAAWJ,EAAOA,EAAM,UAAWE,EAAOC,CAAM,CACzD,CAeO,IAAME,GAAeC,GAAuB,EAEtCC,GAAW,QACrB,QACC,eACA,yBAAqB,EACrB,QAAM,MAAM,CAcV,cAAe,QAAM,SAAS,QAAM,OAAQ,CAAC,EAC7C,aAAc,QAAM,SAAS,QAAM,QAAS,EAAK,EAGjD,WAAYC,GAAiBC,EAAkB,EAC/C,YAAaD,GAAiBE,EAAmB,EAKjD,aAAcC,GAAoBC,GAAsB,MAAM,EAE9D,UAAWD,GAAoBE,GAAmB,OAAO,EAIzD,YAAa,QAAM,SAAS,QAAM,QAAS,EAAK,EAChD,kBAAmB,QAAM,SAAS,QAAM,QAAS,EAAI,EAGrD,UAAW,QAAM,SAAS,QAAM,QAAS,EAAI,EAG7C,mBAAoB,QAAM,SAAS,QAAM,QAAS,EAAI,EAItD,YAAa,QAAM,SAAS,QAAM,OAAQ,CAAC,EAG3C,YAAa,QAAM,SAAS,QAAM,OAAQ,EAAE,EAG5C,cAAe,QAAM,SAAS,QAAM,OAAQ,EAAE,EAG9C,UAAW,QAAM,SAAS,QAAM,OAAQ,EAAE,EAG1C,eAAgB,QAAM,MAAM,QAAM,OAAiB,CAAC,EAIpD,eAAgB,QAAM,MACpB,QAAM,kBAAkB,QAAM,OAAmC,EAAG,CAClE,aAAenC,GAAkBoC,GAAUpC,CAAI,CACjD,CAAC,CACH,EAGA,UAAW,QAAM,SAAS,QAAM,QAAS,EAAK,EAI9C,WAAY,QAAM,SAAS,QAAM,OAAoB,EAAG,CAAC,CAAC,EAM1D,MAAO,QAAM,SAASD,GAAY,CAAC,CAAC,EAOpC,cAAe,QAAM,SAAS,QAAM,OAAQ,EAAE,EAO9C,SAAU,QAAM,SAAS,QAAM,QAAS,EAAK,EAC7C,gBAAiB,QAAM,SAAS,QAAM,OAAQ,CAAC,EAC/C,mBAAoB,QAAM,SAAS,QAAM,OAAQ,CAAC,EAClD,SAAU,QAAM,SAAS,QAAM,QAAS,EAAK,EAC7C,MAAO,QAAM,SAAS,QAAM,OAAQ,CAAC,EACrC,WAAY,QAAM,SAAS,QAAM,OAAQ,CAAC,EAC1C,WAAY,QAAM,SAAS,QAAM,OAAQ,CAAC,EAC1C,UAAW,QAAM,SAAS,QAAM,QAAS,EAAK,EAe9C,WAAY,QAAM,MAAM,QAAM,MAAM,EAGpC,cAAe,QAAM,SAAS,QAAM,OAAQmB,EAAuB,EAGnE,YAAa,QAAM,MAAM,QAAM,OAAuC,CAAC,EAEvE,gBAAiB,QAAM,MAAM,QAAM,MAAM,CAC3C,CAAC,CACH,EACC,SAAS,KAAO,CACf,MAAO,OAEP,YAAa,OAKb,oBAAqB,OACrB,aAAc,OAGd,WAAY,CAAE,MAAO,EAAG,OAAQ,CAAE,EAIlC,aAAc,OAEd,kBAAmB,OAGnB,iBAAkB,OAElB,mBAAoB,OAEpB,aAAc,OAId,SAAU,CAAC,EAQX,MAAO,OACP,UAAW,GACX,aAAc,GACd,cAAe,GACf,YAAa,KAEb,gBAAiB,CAAC,EAElB,cAAe,KAGf,cAAe,GAEf,WAAY,KAEZ,eAAgB,KAChB,YAAa,KACb,aAAc,KACd,cAAe,EAOf,iBAAkB,EAGlB,gBAAiB,EAGjB,cAAe,OAEf,gBAAiB,OACjB,aAAc,KAId,UAAW,GAQX,cAAe,MACf,mBAAoB,OAEpB,oBAAqB,EAMrB,YAAa,OAEb,WAAY,OACZ,aAAc,OACd,eAAgB,OAChB,wBAAyB,OACzB,uBAAwB,EAC1B,EAAE,EU/bJ,IAAAmB,GAA2B,UAC3BC,GAA4B,UAC5BC,EAA6C,UCE7C,SAASC,GAAeC,EAAOC,EAAY,CACzC,IAAMC,EAAO,IAAI,IAAID,CAAU,EACzBE,EAAQH,EAAM,MAAM,OAAQI,GAAMF,EAAK,IAAIE,EAAE,IAAI,CAAC,EAClDC,EAAM,IAAI,IAAIF,EAAM,IAAKC,GAAMA,EAAE,EAAE,CAAC,EACpCE,EAAW,IAAI,IAAIN,EAAM,MAAM,IAAKI,GAAM,CAACA,EAAE,GAAIA,EAAE,MAAM,CAAC,CAAC,EAC3DG,EAAuB,IAAI,IAC3BC,EAAQR,EAAM,OAAO,QAASS,GAAM,CACxC,IAAMC,EAAQD,EAAE,QAAQ,UAAWE,GAAON,EAAI,IAAIM,CAAE,CAAC,EACrD,GAAID,EAAQ,EACV,MAAO,CAAC,EAEV,IAAME,EAAUH,EAAE,QAAQ,OAAQE,GAAON,EAAI,IAAIM,CAAE,CAAC,EACpDJ,EAAK,IAAIE,EAAE,KAAM,CAAE,MAAAC,EAAO,QAAAE,CAAQ,CAAC,EACnC,IAAMC,EAASJ,EAAE,QAAQ,MAAM,EAAGC,CAAK,EAAE,OAAO,CAACI,EAAKH,IAAOG,GAAOR,EAAS,IAAIK,CAAE,GAAK,GAAI,CAAC,EAC7F,MAAO,CACL,CACE,GAAGF,EACH,QAAAG,EACA,GAAGH,EAAE,QAAU,OAAS,CAAC,EAAI,CAAE,MAAOA,EAAE,MAAQI,CAAO,CACzD,CACF,CACF,CAAC,EACD,MAAO,CACL,KAAMb,EAAM,KACZ,MAAAG,EACA,MAAOH,EAAM,MAAM,OAAQe,GAAMV,EAAI,IAAIU,EAAE,IAAI,GAAKV,EAAI,IAAIU,EAAE,EAAE,CAAC,EACjE,GAAGP,GAAO,OAAS,CAAE,MAAAA,CAAM,EAAI,CAAC,EAChC,YAAaQ,GAAYhB,EAAOO,CAAI,EACpC,WAAYP,EAAM,WAClB,WAAYA,EAAM,WAClB,cAAeA,EAAM,aACvB,CACF,CC1BA,SAASiB,GAAaC,EAAOC,EAAQ,CACnC,IAAMC,EAAW,IAAI,IACnBF,EAAM,MAAM,OAAQG,GAAMC,EAAWD,CAAC,GAAKE,GAAeF,EAAGF,CAAM,CAAC,EAAE,IAAKE,GAAMA,EAAE,EAAE,CACvF,EACMG,EAAQN,EAAM,OAAS,CAAC,EAC9B,GAAIE,EAAS,OAAS,GAAKI,EAAM,SAAW,EAC1C,OAAON,EAET,IAAMO,EAAQD,EAAM,IAAKE,GAAS,CAChC,IAAIC,EAAQ,GACRC,EAAO,GACX,OAAAF,EAAK,QAAQ,QAAQ,CAACG,EAAIC,IAAM,CAC1BV,EAAS,IAAIS,CAAE,IACbF,EAAQ,IACVA,EAAQG,GAEVF,EAAOE,EAEX,CAAC,EACMH,EAAQ,EAAI,OAAS,CAAE,MAAAA,EAAO,KAAAC,CAAK,CAC5C,CAAC,EACD,GAAIH,EAAM,MACR,CAACM,EAAMD,IAAMC,GAAM,QAAU,GAAKA,EAAK,OAASP,EAAMM,CAAC,EAAE,QAAQ,OAAS,CAC5E,EACE,OAAOZ,EAET,IAAMc,EAAuB,IAAI,IAC3BC,EAAU,CAAC,EACXC,EAA4B,IAAI,IACtC,OAAAV,EAAM,QAAQ,CAACE,EAAMI,IAAM,CACzB,IAAMC,EAAON,EAAMK,CAAC,EACpB,GAAIC,EAAM,CACR,IAAMI,EAAUT,EAAK,QAAQ,MAAMK,EAAK,MAAOA,EAAK,KAAO,CAAC,EAC5D,QAAWF,KAAMM,EACfH,EAAK,IAAIH,CAAE,EAEbI,EAAQ,KAAK,CAAE,GAAGP,EAAM,QAAAS,CAAQ,CAAC,EACjCD,EAAU,IAAIR,EAAK,KAAM,CAAE,MAAOK,EAAK,MAAO,QAAAI,CAAQ,CAAC,CACzD,CACF,CAAC,EACM,CACL,GAAGjB,EACH,MAAOA,EAAM,MAAM,OAAQG,GAAMW,EAAK,IAAIX,EAAE,EAAE,CAAC,EAC/C,MAAOH,EAAM,MAAM,OAAQkB,GAAMJ,EAAK,IAAII,EAAE,IAAI,GAAKJ,EAAK,IAAII,EAAE,EAAE,CAAC,EACnE,MAAOH,EACP,WAAYf,EAAM,YAAcmB,GAC9BnB,EAAM,WACNM,EACAC,EACA,IAAI,IAAIP,EAAM,MAAM,IAAKG,GAAM,CAACA,EAAE,GAAIA,EAAE,IAAI,CAAC,CAAC,CAChD,EACA,YAAaiB,GAAYpB,EAAOgB,CAAS,CAC3C,CACF,CACA,SAASG,GAAWE,EAAQf,EAAOC,EAAOe,EAAQ,CAChD,IAAMC,EAAyB,IAAI,IAC7BC,EAAsB,IAAI,IAChC,OAAAlB,EAAM,QAAQ,CAACE,EAAMiB,IAAM,CACzB,IAAMC,EAASC,EAAWnB,EAAK,IAAI,EAAE,KAC/BK,EAAON,EAAMkB,CAAC,EACpBjB,EAAK,QAAQ,QAAQ,CAACG,EAAIC,IAAM,CAC9B,IAAMgB,EAAUN,EAAO,IAAIX,CAAE,GAAKA,EAC5BkB,EAAOR,EAAO,IAAIO,CAAO,EAC/B,GAAI,CAACC,EACH,OAEF,IAAMC,EAAM,GAAGJ,CAAM,IAAIE,CAAO,GAC5BG,EAAKR,EAAO,IAAIO,CAAG,GAAK,EAC5B,KAAOC,EAAKF,EAAK,QAAUA,EAAKE,CAAE,EAAE,OAASL,GAC3CK,IAEF,IAAMC,EAAQH,EAAKE,CAAE,EAErB,GADAR,EAAO,IAAIO,EAAKC,EAAK,CAAC,EAClBC,GAASnB,GAAQD,GAAKC,EAAK,OAASD,GAAKC,EAAK,KAAM,CACtD,IAAMoB,EAAaT,EAAI,IAAII,CAAO,EAC9BK,EACFA,EAAW,KAAKD,CAAK,EAErBR,EAAI,IAAII,EAAS,CAACI,CAAK,CAAC,CAE5B,CACF,CAAC,CACH,CAAC,EACMR,CACT,CCxEA,SAASU,GAASC,EAAMC,EAAUC,EAAS,CACzC,IAAMC,EAAYC,EAAWJ,EAAK,IAAI,EAAE,KAClCK,EAAuB,IAAI,IAC3BC,EAAO,CAAC,EACRC,EAAO,KAAO,CAAE,EAAG,KAAW,EAAG,IAAU,OAAQ,CAAC,EAAG,GAAI,CAAE,GAC7DC,EAAO,CAACD,EAAK,CAAC,EACpB,QAAWE,KAAMT,EAAK,QAAS,CAC7B,IAAMU,EAAOT,EAAS,IAAIQ,CAAE,EAC5B,GAAI,CAACC,EACH,SAEF,IAAMC,EAAIN,EAAK,IAAIK,EAAK,IAAI,GAAK,EACjCL,EAAK,IAAIK,EAAK,KAAMC,EAAI,CAAC,EACzB,IAAMC,EAASV,EAAQ,IAAI,GAAGC,CAAS,IAAIO,EAAK,IAAI,EAAE,IAAIC,CAAC,GAAKE,GAAgBH,CAAI,EAC9EI,EAAMN,EAAK,GAAG,EAAE,EAChBO,EAAOT,EAAK,GAAG,EAAE,EACvB,GAAIU,EAAWN,CAAI,EAAG,CACpB,IAAMO,EAAQP,EAAK,OAAO,MACpBQ,EAAMD,EAAQP,EAAK,OACnBS,EAAWP,KAAYF,EAAK,OAAO,QAAU,KAC7CU,EAAQL,IAAS,QAAUD,EAAI,OAAO,SAAW,EACnDM,GAAS,CAACL,EAAK,UAAY,CAACI,GAAYJ,EAAK,MAAQE,EACvDF,EAAK,IAAMG,EACFE,GAASL,EAAK,UAAYI,GAAYJ,EAAK,QAAUG,EAC9DH,EAAK,MAAQE,GAEbX,EAAK,KAAK,CAAE,MAAAW,EAAO,IAAAC,EAAK,SAAAC,CAAS,CAAC,EAClCX,EAAK,KAAKD,EAAK,CAAC,EAEpB,MACEO,EAAI,OAAO,KAAK,CAAE,KAAAJ,EAAM,OAAAE,CAAO,CAAC,EAChCE,EAAI,IAAMJ,EAAK,MAEnB,CACA,OAAAJ,EAAK,QAAQ,CAACe,EAAKC,IAAM,CACvBd,EAAKc,CAAC,EAAE,EAAID,EAAI,MAChBb,EAAKc,EAAI,CAAC,EAAE,EAAID,EAAI,GACtB,CAAC,EACM,CAAE,KAAArB,EAAM,KAAAM,EAAM,KAAAE,CAAK,CAC5B,CACA,SAASe,GAAQT,EAAKU,EAAO,CAC3B,OAAO,OAAO,SAASV,EAAI,CAAC,GAAK,OAAO,SAASA,EAAI,CAAC,GAAKA,EAAI,GAAKA,EAAI,GAAK,KAAK,IAAIA,EAAI,EAAIA,EAAI,EAAGA,EAAI,EAAE,EAAIU,CACjH,CACA,SAASC,GAAeC,EAAMC,EAAGC,EAAG,CAClC,IAAIC,EAAK,EACLC,EAAKJ,EAAK,OACd,KAAOG,EAAKC,GAAI,CACd,IAAMC,EAAMF,EAAKC,GAAM,EACnBJ,EAAKK,CAAG,GAAKJ,EACfE,EAAKE,EAAM,EAEXD,EAAKC,CAET,CACA,OAAOF,EAAKH,EAAK,QAAUA,EAAKG,CAAE,EAAID,CACxC,CACA,SAASI,GAAcC,EAAU,CAC/B,IAAMP,EAAuB,IAAI,IACjC,QAASJ,EAAI,EAAGA,EAAIW,EAAS,OAAQX,IAAK,CACxC,IAAMY,EAAOD,EAASX,EAAI,CAAC,EACrBZ,EAAOuB,EAASX,CAAC,EACjBJ,EAAMgB,EAAK,OAAO,MAAQA,EAAK,OACjChB,IAAQR,EAAK,OAAO,QACtBgB,EAAK,IAAIR,EAAK,eAAe,EAC7BQ,EAAK,IAAIhB,EAAK,OAAO,MAAO,eAAe,EAE/C,CACA,OAAOgB,CACT,CACA,SAASS,GAASC,EAAOZ,EAAOE,EAAM,CACpC,IAAMW,EAAM,CAACC,EAAIC,IAAU,CACrB,OAAO,SAASD,CAAE,GAAK,CAACZ,EAAK,IAAIY,CAAE,GACrCZ,EAAK,IAAIY,EAAIC,CAAK,CAEtB,EACA,OAAW,CAAE,KAAAjC,EAAM,KAAAE,CAAK,IAAK4B,EAAO,CAClC,IAAMI,EAAQlC,EAAK,CAAC,EACdS,EAAOT,EAAK,GAAG,EAAE,EACnBkC,GAASzB,IACXsB,EAAIG,EAAM,MAAO,UAAU,EAC3BH,EAAItB,EAAK,IAAK,UAAU,GAE1B,QAAWM,KAAOf,EACZe,EAAI,UAAYA,EAAI,IAAMA,EAAI,OAASG,IACzCa,EAAIhB,EAAI,MAAO,WAAW,EAC1BgB,EAAIhB,EAAI,IAAK,WAAW,GAG5B,QAAWP,KAAON,EACZM,EAAI,EAAIA,EAAI,GACduB,EAAIvB,EAAI,EAAG,UAAU,EACrBuB,EAAIvB,EAAI,EAAG,UAAU,GACXS,GAAQT,EAAKU,CAAK,IAC5Ba,EAAIvB,EAAI,EAAG,SAAS,EACpBuB,EAAIvB,EAAI,EAAG,SAAS,EAG1B,CACA,QAAS2B,EAAU,GAAMA,GAAW,CAClCA,EAAU,GACV,IAAMC,EAAS,CAAC,GAAGhB,EAAK,KAAK,CAAC,EAAE,KAAK,CAACiB,EAAGC,IAAMD,EAAIC,CAAC,EAC9CC,EAAQT,EAAM,QAAQ,CAAC,CAAE,KAAA9B,EAAM,KAAAE,CAAK,IAAM,CAC9C,GAAGA,EAAK,OAAQsC,GAAMvB,GAAQuB,EAAGtB,CAAK,CAAC,EAAE,IAAKsB,GAAM,CAACA,EAAE,EAAGA,EAAE,CAAC,CAAC,EAC9D,GAAGxC,EAAK,OAAQyC,GAAMA,EAAE,UAAYA,EAAE,IAAMA,EAAE,MAAQvB,CAAK,EAAE,IAAKuB,GAAM,CAACA,EAAE,MAAOA,EAAE,GAAG,CAAC,CAC1F,CAAC,EACD,OAAW,CAACpB,EAAGC,CAAC,IAAKiB,EACfpB,GAAeiB,EAAQf,EAAGC,CAAC,IAC7Ba,IAAY,CAACf,EAAK,IAAIC,CAAC,GAAK,CAACD,EAAK,IAAIE,CAAC,EACvCS,EAAIV,EAAG,SAAS,EAChBU,EAAIT,EAAG,SAAS,EAGtB,CACA,OAAOF,CACT,CACA,SAASsB,GAAef,EAAUP,EAAM,CACtC,IAAMuB,EAAS,CAAC,EACZC,EAAQ,CAAC,EACPC,EAAQ,IAAM,CAClB,IAAMX,EAAQU,EAAM,CAAC,EACfnC,EAAOmC,EAAM,GAAG,EAAE,EACxB,GAAIV,GAASzB,EAAM,CACjB,IAAMqC,EAAMZ,EAAM,OAAO,MACnBa,EAAMtC,EAAK,OAAO,MAAQA,EAAK,OAC/BuC,EAAO,GAAGF,CAAG,IAAIC,CAAG,GAC1BJ,EAAO,KAAK,CACV,KAAM,CACJ,GAAI,GAAGK,CAAI,IACX,KAAAA,EACA,OAAQD,EAAMD,EACd,MAAO,EACP,OAAQ,CACN,QAASZ,EAAM,OAAO,QACtB,MAAOY,EACP,KAAM,EACN,OAAQ,GACV,CACF,EACA,QAASF,CACX,CAAC,CACH,CACAA,EAAQ,CAAC,CACX,EACA,QAAWxC,KAAQuB,EACbP,EAAK,IAAIhB,EAAK,OAAO,KAAK,GAC5ByC,EAAM,EAERD,EAAM,KAAKxC,CAAI,EAEjB,OAAAyC,EAAM,EACCF,CACT,CACA,SAASM,GAAeC,EAAOhC,EAAO,CACpC,IAAMS,EAAWuB,EAAM,MAAM,OAAOxC,CAAU,EAAE,KAAK,CAACW,EAAGC,IAAMD,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EACxF6B,EAAQD,EAAM,OAAS,CAAC,EAC9B,GAAIvB,EAAS,SAAW,GAAKwB,EAAM,SAAW,EAC5C,OAEF,IAAMxD,EAAW,IAAI,IAAIuD,EAAM,MAAM,IAAKE,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EACpDxD,EAAUyD,GAAaH,CAAK,EAC5BpB,EAAQqB,EAAM,IAAKG,GAAM7D,GAAS6D,EAAG3D,EAAUC,CAAO,CAAC,EACvDwB,EAAOS,GAASC,EAAOZ,EAAOQ,GAAcC,CAAQ,CAAC,EACrD4B,EAAa,CAAC,GAAGnC,EAAK,KAAK,CAAC,EAAE,KAAK,CAACiB,EAAGC,IAAMD,EAAIC,CAAC,EAClDK,EAASD,GAAef,EAAUP,CAAI,EACtCoC,EAASb,EAAO,IAAKc,GAAMA,EAAE,KAAK,OAAO,KAAK,EAC9CC,EAAY1B,GAAO,CACvB,IAAIT,EAAK,EACLC,EAAKgC,EAAO,OAAS,EACzB,KAAOjC,EAAKC,GAAI,CACd,IAAMC,EAAMF,EAAKC,EAAK,GAAK,EACvBgC,EAAO/B,CAAG,GAAKO,EACjBT,EAAKE,EAELD,EAAKC,EAAM,CAEf,CACA,OAAOF,CACT,EACMoC,EAA0B,IAAI,IAC9BC,EAA2B,IAAI,IACrC,QAAWH,KAAKd,EAAQ,CACtBgB,EAAQ,IACNF,EAAE,KAAK,GACPA,EAAE,QAAQ,IAAKL,GAAMA,EAAE,EAAE,CAC3B,EACA,QAAWA,KAAKK,EAAE,QAChBG,EAAS,IAAIR,EAAE,GAAIK,EAAE,KAAK,EAAE,CAEhC,CACA,IAAMI,EAAyB,IAAI,IAC7BC,EAAYtD,GAAQ,CACxB,IAAMuD,EAAM,GAAGvD,EAAI,CAAC,IAAIA,EAAI,CAAC,IAAIA,EAAI,OAAO,IAAKwD,GAAMA,EAAE,KAAK,GAAKA,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,GAClF5D,EAAOyD,EAAO,IAAIE,CAAG,EACzB,GAAI,CAAC3D,EAAM,CACT,IAAM4C,EAAO,IAAIa,EAAO,IAAI,GAC5BzD,EAAO,CACL,GAAI,GAAG4C,CAAI,IACX,KAAAA,EACA,OAAQxC,EAAI,GACZ,MAAO,EACP,OAAQ,CACN,QAASmB,EAAS,CAAC,EAAE,OAAO,QAC5B,MAAO,OAAO,SAASnB,EAAI,CAAC,EAAIA,EAAI,EAAIA,EAAI,EAC5C,KAAM,EACN,OAAQ,GACV,CACF,EACAqD,EAAO,IAAIE,EAAK3D,CAAI,EACpBuD,EAAQ,IACNvD,EAAK,GACLI,EAAI,OAAO,IAAKwD,GAAMA,EAAE,KAAK,EAAE,CACjC,EACA,QAAWA,KAAKxD,EAAI,OACboD,EAAS,IAAII,EAAE,KAAK,EAAE,GACzBJ,EAAS,IAAII,EAAE,KAAK,GAAI5D,EAAK,EAAE,CAGrC,CACA,OAAOA,CACT,EACM6D,EAA6B,IAAI,IACjCC,EAAc,CAAC,EACfC,EAA6B,IAAI,IACjCC,EAAwB,IAAI,IAC5BC,EAAwB,IAAI,IAClC,OAAW,CAAE,KAAA3E,EAAM,KAAAM,EAAM,KAAAE,CAAK,IAAK4B,EAAO,CACxC,IAAMwC,EAAQ,CAAC,EACTC,EAAO,CAAC,EACVC,EAAa,GACXC,EAAS,CAACrE,EAAME,IAAW,CAC/B,IAAMG,EAAO6D,EAAM,GAAG,EAAE,EAClBE,GAAc/D,GAAM,OAASL,GAAQK,EAAK,SAAWH,GACzDgE,EAAM,KAAK,CAAE,KAAAlE,EAAM,OAAAE,CAAO,CAAC,EAE7BkE,EAAa,EACf,EACME,EAAclE,GAAQ,CAC1BgE,EAAa,GACThE,EAAI,OAAO,OAAS,IACtBiE,EAAOX,EAAStD,CAAG,EAAG,GAAG,EACzBgE,EAAa,GAEjB,EACMG,EAAQnE,GAAQ,EAChBA,EAAI,GAAK,GAAKA,EAAI,EAAIA,EAAI,IAC5B+D,EAAK,KAAK,CAAE,MAAO/D,EAAI,EAAG,IAAKA,EAAI,EAAG,GAAIA,EAAI,EAAG,CAAC,EAEpD,IAAMoE,EAAOjC,EAAOe,EAASlD,EAAI,EAAIA,EAAI,EAAIA,EAAI,EAAIA,EAAI,EAAI,CAAC,CAAC,EAC/D,QAAWwD,KAAKxD,EAAI,OACboD,EAAS,IAAII,EAAE,KAAK,EAAE,IACzBJ,EAAS,IAAII,EAAE,KAAK,GAAIY,EAAK,KAAK,EAAE,EACpCjB,EAAQ,IAAIiB,EAAK,KAAK,EAAE,EAAE,KAAKZ,EAAE,KAAK,EAAE,EAG9C,EACAhE,EAAK,QAAQ,CAACe,EAAKC,IAAM,CACvB,IAAMR,EAAMN,EAAKc,CAAC,EACdC,GAAQT,EAAKU,CAAK,GAAK,CAACC,GAAeoC,EAAY/C,EAAI,EAAGA,EAAI,CAAC,EACjEmE,EAAKnE,CAAG,EAERkE,EAAWlE,CAAG,EAEhB,IAAMqE,EAAKnB,EAAS3C,EAAI,KAAK,EACvB+D,EAAKpB,EAAS3C,EAAI,IAAM,CAAC,EACzBgE,EAAQhE,EAAI,IAAMA,EAAI,MAAQG,EACpC,GAAIH,EAAI,UAAY,CAACgE,EAAO,CAC1BP,EAAa,GACb,QAASQ,EAAIF,EAAIE,GAAKH,EAAIG,IACxBP,EAAO9B,EAAOqC,CAAC,EAAE,KAAM,GAAG,EAE5BR,EAAa,EACf,KAAO,CACDzD,EAAI,UACNwD,EAAK,KAAK,CACR,MAAOxD,EAAI,MACX,IAAKA,EAAI,IACT,GAAIA,EAAI,IAAMA,EAAI,MAClB,SAAU,EACZ,CAAC,EAEH,QAASiE,EAAIH,EAAIG,GAAKF,EAAIE,IACxBP,EAAO9B,EAAOqC,CAAC,EAAE,KAAM,GAAG,CAE9B,CACF,CAAC,EACDN,EAAWxE,EAAK,GAAG,EAAE,CAAC,EACtB,IAAML,EAAYC,EAAWJ,EAAK,IAAI,EAAE,KACpCuF,GAAM,EACVX,EAAM,QAAQ,CAAC,CAAE,KAAAlE,EAAM,OAAAE,CAAO,EAAGU,IAAM,CACrCqD,EAAM,IAAIjE,EAAK,IAAKiE,EAAM,IAAIjE,EAAK,EAAE,GAAK,GAAK,CAAC,EAChD,IAAM8E,EAASf,EAAW,IAAI/D,EAAK,IAAI,GAAK,CAAC,EAC7C8E,EAAO,KAAK,CACV,KAAMrF,EACN,OAAQH,EAAK,QAAUG,EACvB,MAAOoF,GACP,OAAA3E,CACF,CAAC,EACD6D,EAAW,IAAI/D,EAAK,KAAM8E,CAAM,EAChCD,IAAO7E,EAAK,OACZ,IAAM+E,EAAOb,EAAMtD,EAAI,CAAC,EACxB,GAAImE,EAAM,CACR,IAAMpB,EAAM,GAAG3D,EAAK,EAAE,GAAGE,CAAM,IAAI6E,EAAK,KAAK,EAAE,GAAGA,EAAK,MAAM,GACvDC,EAAOhB,EAAM,IAAIL,CAAG,EACtBqB,EACFA,EAAK,QAAQ,KAAK1F,EAAK,IAAI,EAE3B0E,EAAM,IAAIL,EAAK,CACb,KAAM3D,EAAK,GACX,GAAI+E,EAAK,KAAK,GACd,WAAY7E,EACZ,SAAU6E,EAAK,OACf,QAAS,CAACzF,EAAK,IAAI,CACrB,CAAC,CAEL,CACF,CAAC,EACDwE,EAAY,KAAK,CAAE,GAAGxE,EAAM,QAAS4E,EAAM,IAAKN,GAAMA,EAAE,KAAK,EAAE,CAAE,CAAC,EAClEC,EAAW,IAAIvE,EAAK,KAAM6E,CAAI,CAChC,CACA,IAAMc,EAAQ,CAAC,GAAG1C,EAAO,IAAKc,GAAMA,EAAE,IAAI,EAAG,GAAGI,EAAO,OAAO,CAAC,EAAE,OAAQT,GAAMiB,EAAM,IAAIjB,EAAE,EAAE,CAAC,EAAE,IAAKA,IAAO,CAAE,GAAGA,EAAG,MAAOiB,EAAM,IAAIjB,EAAE,EAAE,CAAE,EAAE,EAC7I,MAAO,CACL,MAAO,CACL,GAAGF,EACH,MAAAmC,EACA,MAAO,CAAC,GAAGjB,EAAM,OAAO,CAAC,EACzB,MAAOF,EACP,WAAAC,EACA,MAAO,MACT,EACA,QAAAR,EACA,SAAAC,EACA,WAAAK,EACA,KAAA7C,CACF,CACF,CCtVA,IAAAkE,GAA+B,SAC/BC,EAIO,UACPC,GAA6B,UAC7BC,EAA8B,UCZ9B,IAAAC,GAAsD,UACtDC,GAAwB,UCVxB,SAASC,GAAqBC,EAAQC,EAASC,EAAI,CAAC,EAAG,CACrD,MAAO,CACL,cAAeA,EAAE,UAAY,CAAC,EAAIF,EAAO,cACzC,UAAWC,EAAQ,SACnB,eAAgBD,EAAO,eACvB,SAAUA,EAAO,SACjB,YAAaC,EAAQ,MACvB,CACF,CCRA,IAAIE,EAAKC,GAAM,CAACA,EAAE,QAAQ,CAAC,EAC3B,SAASC,GAAMC,EAAK,CAClB,IAAMC,EAAI,mDAAmD,KAC3DD,EAAI,WAAW,IAAK,EAAE,CACxB,EACA,GAAI,CAACC,EACH,MAAO,CAAE,MAAOD,EAAK,QAAS,CAAE,EAElC,IAAME,EAAUD,EAAE,CAAC,IAAM,OAAS,EAAI,OAAOA,EAAE,CAAC,CAAC,EACjD,MAAO,CAAE,MAAO,OAAOA,EAAE,CAAC,CAAC,IAAIA,EAAE,CAAC,CAAC,IAAIA,EAAE,CAAC,CAAC,IAAK,QAAAC,CAAQ,CAC1D,CACA,SAASC,GAAWC,EAAMJ,EAAK,CAC7B,GAAM,CAAE,MAAAK,EAAO,QAAAH,CAAQ,EAAIH,GAAMC,CAAG,EACpC,MAAO,GAAGI,CAAI,KAAKC,CAAK,IAAIH,EAAU,EAAI,IAAIE,CAAI,aAAaP,EAAEK,CAAO,CAAC,IAAM,EAAE,EACnF,CACA,IAAII,GAAS,GACTC,GAAc,IAClB,SAASC,GAAUC,EAAOC,EAAQ,CAChC,IAAMC,EAAM,CAAC,EACTC,EAAW,CAAC,EACVC,EAAQ,CAACC,EAAGC,IAAM,CACtB,IAAMC,EAAI,CAAE,EAAG,IAAInB,EAAEiB,CAAC,CAAC,IAAIjB,EAAEkB,CAAC,CAAC,GAAI,SAAU,EAAG,GAAID,EAAG,GAAIA,EAAG,GAAIC,EAAG,GAAIA,CAAE,EAC3E,OAAAH,EAAS,KAAKI,CAAC,EACRA,CACT,EACMC,EAASC,GAAW,CACxB,IAAMF,EAAIJ,EAAS,GAAG,EAAE,GAAKC,EAAMK,EAAO,CAAC,EAAGA,EAAO,CAAC,CAAC,EACvD,QAASC,EAAI,EAAGA,EAAID,EAAO,OAAQC,GAAK,EACtCH,EAAE,GAAK,KAAK,IAAIA,EAAE,GAAIE,EAAOC,CAAC,CAAC,EAC/BH,EAAE,GAAK,KAAK,IAAIA,EAAE,GAAIE,EAAOC,CAAC,CAAC,EAC/BH,EAAE,GAAK,KAAK,IAAIA,EAAE,GAAIE,EAAOC,EAAI,CAAC,CAAC,EACnCH,EAAE,GAAK,KAAK,IAAIA,EAAE,GAAIE,EAAOC,EAAI,CAAC,CAAC,EAErC,OAAAH,EAAE,WACKA,CACT,EACMI,EAAYC,GAAS,CACzB,IAAMC,EAAuB,IAAI,IACjC,OAAOV,EAAS,IAAKI,GAAM,CACzB,GAAI,CAACK,GAAQL,EAAE,GAAKA,EAAE,IAAMV,IAAUU,EAAE,GAAKA,EAAE,IAAMV,GACnD,OAAOU,EAAE,EAEX,IAAMF,GAAKE,EAAE,GAAKA,EAAE,IAAM,EACpBD,GAAKC,EAAE,GAAKA,EAAE,IAAM,EACpBO,EAAO,GAAG,KAAK,MAAMT,EAAIP,EAAW,CAAC,IAAI,KAAK,MAAMQ,EAAIR,EAAW,CAAC,GAC1E,OAAIS,EAAE,WAAa,GAAKM,EAAK,IAAIC,CAAI,EAC5B,IAETD,EAAK,IAAIC,CAAI,EACN,IAAI1B,EAAEiB,CAAC,CAAC,IAAIjB,EAAEkB,CAAC,CAAC,KACzB,CAAC,EAAE,KAAK,EAAE,CACZ,EACMS,EAAM,CACV,OAAQ,OACR,UAAW,OACX,YAAa,OACb,UAAW,EACX,QAAS,OACT,SAAU,QACV,WAAY,CACVZ,EAAW,CAAC,CACd,EACA,OAAOE,EAAGC,EAAG,CACXF,EAAMC,EAAGC,CAAC,CACZ,EACA,OAAOD,EAAGC,EAAG,CACXE,EAAM,CAACH,EAAGC,CAAC,CAAC,EAAE,GAAK,IAAIlB,EAAEiB,CAAC,CAAC,IAAIjB,EAAEkB,CAAC,CAAC,EACrC,EACA,cAAcU,EAAKC,EAAKC,EAAKC,EAAKd,EAAGC,EAAG,CACtCE,EAAM,CAACQ,EAAKC,EAAKC,EAAKC,EAAKd,EAAGC,CAAC,CAAC,EAAE,GAAK,IAAIlB,EAAE4B,CAAG,CAAC,IAAI5B,EAAE6B,CAAG,CAAC,IAAI7B,EAAE8B,CAAG,CAAC,IAAI9B,EAAE+B,CAAG,CAAC,IAAI/B,EAAEiB,CAAC,CAAC,IAAIjB,EAAEkB,CAAC,CAAC,EACjG,EACA,WAAY,CACV,IAAMC,EAAIJ,EAAS,GAAG,EAAE,EACpBI,IACFA,EAAE,GAAK,IAEX,EACA,QAAS,CACP,IAAM,EAAII,EAASI,EAAI,UAAY,MAAM,EACrC,GACFb,EAAI,KACF,YAAY,CAAC,iBAAiBR,GAAW,SAAUqB,EAAI,WAAW,CAAC,kBAAkB3B,EAAE2B,EAAI,SAAS,CAAC,qBAAqBA,EAAI,OAAO,sBAAsBA,EAAI,QAAQ,KACzK,CAEJ,EACA,MAAO,CACL,IAAM,EAAIJ,EAAS,EAAK,EACpB,GACFT,EAAI,KAAK,YAAY,CAAC,KAAKR,GAAW,OAAQqB,EAAI,SAAS,CAAC,IAAI,CAEpE,EACA,SAASV,EAAGC,EAAGc,EAAGC,EAAG,CACnBnB,EAAI,KACF,YAAYd,EAAEiB,CAAC,CAAC,QAAQjB,EAAEkB,CAAC,CAAC,YAAYlB,EAAEgC,CAAC,CAAC,aAAahC,EAAEiC,CAAC,CAAC,KAAK3B,GAAW,OAAQqB,EAAI,SAAS,CAAC,IACrG,CACF,CACF,EACMO,EAAS,CACb,MAAAtB,EACA,OAAAC,EACA,MAAO,CAAC,EACR,WAAY,IAAMc,CACpB,EACA,OAAAA,EAAI,OAASO,EACN,CACL,OAAAA,EAEA,OAAQ,IAAMpB,EAAI,KAAK,EAAE,CAC3B,CACF,CClGA,SAASqB,GAASC,EAAOC,EAAOC,EAAW,CACzC,IAAMC,EAA4B,IAAI,IACtC,QAAWC,KAAQJ,EAAM,MACvB,GAAIK,GAAWD,CAAI,EAAG,CACpB,GAAM,CAAE,QAAAE,CAAQ,EAAIF,EAAK,OACzB,GAAIF,EAAUE,EAAK,EAAE,GAAG,OAAQ,CAC9B,IAAMG,EAAQJ,EAAU,IAAIG,CAAO,GAAKH,EAAU,IAAIG,EAAS,CAAE,MAAO,CAAC,EAAG,MAAO,CAAE,CAAC,EAAE,IAAIA,CAAO,EACnGC,EAAM,MAAM,KAAKH,CAAI,EACrBG,EAAM,MAAQ,KAAK,IAAIA,EAAM,MAAOH,EAAK,MAAM,CACjD,CACF,CAEF,OAAW,CAAE,MAAAI,CAAM,IAAKL,EAAU,OAAO,EACvCK,EAAM,KAAK,CAACC,EAAGC,IAAMD,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EAEtD,IAAMC,EAAO,CAAC,EACd,QAAWC,KAAQX,EAAO,CACxB,IAAMY,EAAYV,EAAU,IAAIS,EAAK,OAAO,EAC5C,GAAI,CAACC,EACH,SAEF,IAAMC,EAAQ,CAAC,EACTC,EAAc,CAAC,EACfC,EAA0B,IAAI,IAChCC,EACAC,EAAa,IACbC,EAAU,EACRC,GAAOR,EAAK,MAAQA,EAAK,KAAO,EAChC,CAAE,MAAAJ,EAAO,MAAAa,CAAM,EAAIR,EACzB,QAASS,EAAIC,GAAmBf,EAAOI,EAAK,MAAQS,CAAK,EAAGC,EAAId,EAAM,QAAUA,EAAMc,CAAC,EAAE,OAAO,MAAQV,EAAK,IAAKU,IAAK,CACrH,IAAMlB,EAAOI,EAAMc,CAAC,EACdE,EAAYpB,EAAK,OAAO,MACxBqB,EAAUD,EAAYpB,EAAK,OACjC,GAAIqB,GAAWb,EAAK,MAClB,SAEF,IAAMc,EAAOxB,EAAUE,EAAK,EAAE,EAC9BY,EAAQ,IAAIZ,EAAK,EAAE,EACnBe,GAAW,KAAK,IAAIM,EAASb,EAAK,GAAG,EAAI,KAAK,IAAIY,EAAWZ,EAAK,KAAK,EACvE,IAAMe,EAAY,CAAC,EACnB,QAAWC,KAAQhB,EAAK,MAAO,CAC7B,IAAMH,EAAI,KAAK,IAAImB,EAAK,MAAOJ,CAAS,EAClCd,EAAI,KAAK,IAAIkB,EAAK,IAAKH,CAAO,EACpC,GAAIf,GAAKD,EACP,SAEF,IAAMoB,EAAUC,GACdJ,GACCjB,EAAIe,GAAapB,EAAK,QACtBM,EAAIc,GAAapB,EAAK,MACzB,EACIyB,EAAQ,SAAW,GACrBA,EAAQ,KAAK,CAAE,GAAGA,EAAQ,CAAC,CAAE,CAAC,EAEhCF,EAAU,KAAKI,GAAQF,CAAO,CAAC,CACjC,CACIF,EAAU,OAAS,IACrBb,EAAM,KAAK,GAAGa,CAAS,EACvBZ,EAAY,KAAK,CAAE,OAAQX,EAAK,GAAI,EAAGuB,EAAU,KAAK,EAAE,CAAE,CAAC,GAE7D,IAAMK,EAAQ,KAAK,IAAI,KAAK,IAAIZ,EAAKI,CAAS,EAAGC,CAAO,EAClDQ,EAAW,KAAK,IAAID,EAAQZ,CAAG,EACrC,GAAIa,EAAWf,EAAY,CACzBA,EAAae,EACb,GAAM,CAACC,CAAC,EAAIJ,GACVJ,GACCM,EAAQR,GAAapB,EAAK,QAC1B4B,EAAQR,GAAapB,EAAK,MAC7B,EACAa,EAAKiB,CACP,CACF,CACIjB,GACFN,EAAK,KAAK,CACR,KAAAC,EACA,MAAOE,EAAM,KAAK,EAAE,EACpB,YAAAC,EACA,QAAAC,EACA,GAAAC,EACA,QAASE,GAAWP,EAAK,IAAMA,EAAK,MACtC,CAAC,CAEL,CACA,OAAOD,CACT,CCpFA,IAAIwB,GAAc,CAACC,EAAOC,IAAS,CAAC,CAACD,EAAM,eAAiBE,EAAWD,CAAI,EAAE,OAASD,EAAM,cAC5F,SAASG,GAASH,EAAOC,EAAM,CAC7B,OAAQD,EAAM,OAAS,CAAC,GAAG,OAAQI,GAAMA,EAAE,OAASH,CAAI,EAAE,KAAK,CAACI,EAAGC,KAAOD,EAAE,OAAS,IAAMC,EAAE,OAAS,EAAE,CAC1G,CACA,SAASC,GAAcP,EAAOC,EAAM,CAClC,IAAMO,EAASL,GAASH,EAAOC,CAAI,EAC7BQ,EAAQD,EAAO,CAAC,EACtB,GAAI,CAACC,EACH,OAEF,IAAMC,EAAO,IAAI,IAAIV,EAAM,MAAM,IAAKW,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EAChDC,EAAyB,IAAI,IACnCZ,EAAM,MAAM,QAAQ,CAACa,EAAGC,IAAM,CAC5BF,EAAO,IAAI,GAAGC,EAAE,IAAI,IAAIA,EAAE,EAAE,GAAIC,CAAC,CACnC,CAAC,EACD,IAAMC,EAAYC,GAAON,EAAK,IAAIM,CAAE,GAAG,QAAU,EAC3CC,EAAQC,GAASA,EAAK,QAAQ,OAAO,CAACC,EAAKH,IAAOG,EAAMJ,EAASC,CAAE,EAAG,CAAC,EACvEI,EAAKZ,EAAO,OAAO,CAACW,EAAKE,IAAUF,EAAMF,EAAKI,CAAK,EAAG,CAAC,EACvDC,EAAQb,EAAM,QAAU,OAAS,OAAS,CAC9C,OAAQA,EAAM,QAAUc,GAAYrB,EAAWD,CAAI,EAAE,IAAI,EACzD,MAAOQ,EAAM,MACb,IAAK,KAAK,IAAI,GAAGD,EAAO,IAAKJ,IAAOA,EAAE,OAAS,GAAKa,EAAKb,CAAC,CAAC,CAAC,CAC9D,EACMoB,EAAOF,EAAQA,EAAM,IAAMA,EAAM,MAAQF,EACzCK,EAA0B,IAAI,IAC9BC,EAA8B,IAAI,IAClCC,EAA2B,IAAI,IACjCC,EAAS,EACb,QAAWP,KAASb,EACdc,IACFM,EAAS,KAAK,IAAIA,GAASP,EAAM,OAAS,GAAKC,EAAM,KAAK,GAE5DD,EAAM,QAAQ,QAAQ,CAACL,EAAIF,IAAM,CAE/B,GADAW,EAAQ,IAAIT,CAAE,EACVF,EAAI,EAAG,CACT,IAAMT,EAAIgB,EAAM,QAAQP,EAAI,CAAC,EACvBe,EAAQjB,EAAO,IAAI,GAAGP,CAAC,IAAIW,CAAE,EAAE,GAAKJ,EAAO,IAAI,GAAGI,CAAE,IAAIX,CAAC,EAAE,EAC7DwB,IAAU,QACZH,EAAY,IAAIG,CAAK,CAEzB,CACA,IAAMC,EAASf,EAASC,CAAE,EACrBW,EAAS,IAAIX,CAAE,GAClBW,EAAS,IAAIX,EAAIQ,EAAO,GAAKI,EAASE,EAAS,GAAKN,EAAO,CAAC,EAE9DI,GAAUE,CACZ,CAAC,EAEH,IAAMC,EAAYhC,GAAYC,EAAOC,CAAI,EACnC+B,EAAkBD,EAAY,CAAC,GAAK/B,EAAM,OAAS,CAAC,GAAG,OAAQI,GAAML,GAAYC,EAAOI,EAAE,IAAI,CAAC,EACrG,MAAO,CACL,KAAAH,EACA,UAAA8B,EACA,MAAAT,EACA,QAAAG,EACA,YAAAC,EACA,SAAAC,EACA,MAAOnB,EAAO,OAAO,CAACW,EAAKE,IAAUF,EAAME,EAAM,QAAQ,OAAQ,CAAC,EAClE,GAAAD,EACA,YAAaY,EAAgB,OAAS,EAAIA,EAAgB,OAAO,CAACb,EAAKE,IAAUF,EAAMF,EAAKI,CAAK,EAAG,CAAC,EAAI,MAC3G,CACF,CACA,SAASY,GAAWjC,EAAOkC,EAAMC,EAAUC,EAAM,CAC/C,IAAM1B,EAAO,IAAI,IAAIV,EAAM,MAAM,IAAKW,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EAChD0B,EAAyB,IAAI,IACnC,OAAW,CAACrB,EAAIW,CAAQ,IAAKO,EAAK,SAAU,CAC1C,IAAMI,EAAO5B,EAAK,IAAIM,CAAE,EAClBuB,EAAMH,GAAM,UAAU,IAAIpB,CAAE,EAC5BwB,EAAIL,EAAS,QAAU,WAAaR,EAAWS,GAAQG,IAAQ,QAAU,EAAED,GAAM,QAAUA,EAAK,OAAO,KAAO,IAAMC,EAAMH,EAAK,OAASA,EAAK,KAAO,OAC1JC,EAAO,IAAIrB,EAAIyB,GAAaN,EAAUK,CAAC,CAAC,CAC1C,CACA,OAAOH,CACT,CACA,SAASK,GAAc1C,EAAOkC,EAAM,CAClC,IAAMS,EAA2B,IAAI,IACjCvB,EAAK,EACHwB,EAAgB5C,EAAM,cAC5B,GAAI,CAAC4C,GAAiBV,EAAK,UACzB,MAAO,CAAE,SAAAS,EAAU,GAAAvB,CAAG,EAExB,IAAMyB,EAAW3C,EAAWgC,EAAK,IAAI,EAAE,KACjCxB,EAAO,IAAI,IAAIV,EAAM,MAAM,IAAKW,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EACtD,QAAWK,KAAMkB,EAAK,SAAS,KAAK,EAAG,CACrC,IAAMI,EAAO5B,EAAK,IAAIM,CAAE,EAClB8B,EAASR,EAAOtC,EAAM,YAAY,IAAIsC,EAAK,IAAI,EAAI,OACnDS,EAAMD,GAAQ,KAAME,GAAMA,EAAE,OAASH,CAAQ,GAAG,OAChDI,EAASH,GAAQ,KAAME,GAAMA,EAAE,OAASJ,CAAa,GAAG,OAC1DG,GAAOE,GAAUF,IAAQE,IAC3BN,EAAS,IAAI3B,CAAE,EACfI,GAAMkB,EAAK,OAEf,CACA,MAAO,CAAE,SAAAK,EAAU,GAAAvB,CAAG,CACxB,CACA,SAAS8B,GAASlD,EAAOmD,EAAQf,EAAM,CACrC,IAAMgB,EAAuB,IAAI,IAC3BC,EAASF,EAAO,OAAQG,GAAU,CAACF,EAAK,IAAIE,EAAM,IAAI,GAAKF,EAAK,IAAIE,EAAM,IAAI,CAAC,EAAE,QAASA,GAAU,CACxG,IAAMpB,EAAO3B,GAAcP,EAAOsD,EAAM,IAAI,EAC5C,OAAOpB,EAAO,CAAC,CAAE,KAAAA,EAAM,MAAAoB,CAAM,CAAC,EAAI,CAAC,CACrC,CAAC,EAAE,KAAK,CAACjD,EAAGC,IAAM,OAAOA,EAAE,KAAK,SAAS,EAAI,OAAOD,EAAE,KAAK,SAAS,CAAC,EACrE,GAAIgD,EAAO,SAAW,EACpB,OAEF,IAAIE,EAAS,EACPC,EAAQH,EAAO,IAAI,CAAC,CAAE,KAAAnB,EAAM,MAAAoB,CAAM,IAAM,CAC5C,IAAMnB,EAAWsB,GACfH,EACApB,EAAK,UACLA,EAAK,UAAY,EAAIqB,IACrBF,EAAO,SAAW,CACpB,EACM,CAAE,SAAAV,EAAU,GAAAvB,CAAG,EAAIsB,GAAc1C,EAAOkC,CAAI,EAClD,MAAO,CACL,GAAGA,EACH,SAAAC,EACA,OAAQF,GAAWjC,EAAOkC,EAAMC,EAAUC,CAAI,EAC9C,SAAAO,EACA,WAAYvB,CACd,CACF,CAAC,EACD,OAAOsC,GAAOF,EAAOpB,CAAI,CAC3B,CACA,IAAIuB,GAAc,CAAE,MAAO,WAAY,OAAQ,KAAM,EACrD,SAASC,GAAW5D,EAAO6D,EAAMV,EAAQf,EAAM,CAC7C,OAAOyB,EAAK,MAAM,IAAK3B,GAAS,CAC9B,IAAM4B,EAASX,EAAO,KAAMY,GAAMA,EAAE,OAAS7B,EAAK,IAAI,GAAG,MACnDC,EAAWsB,GACf,CAAE,KAAMvB,EAAK,KAAM,MAAO,CAAE,GAAGyB,GAAa,GAAGG,CAAO,CAAE,EACxD5B,EAAK,UACL,CACF,EACA,OAAOwB,GACL,CACE,CACE,GAAGxB,EACH,SAAAC,EACA,OAAQF,GAAWjC,EAAOkC,EAAMC,EAAUC,CAAI,CAChD,CACF,EACAA,CACF,CACF,CAAC,CACH,CACA,SAASsB,GAAOF,EAAOpB,EAAM,CAC3B,MAAO,CACL,MAAAoB,EACA,gBAAiBpB,EAAO,CAAE,MAAOA,EAAK,MAAO,IAAKA,EAAK,MAAQA,EAAK,IAAK,EAAI,OAC7E,QAAS,IAAI,IAAIoB,EAAM,QAASQ,GAAM,CAAC,GAAGA,EAAE,OAAO,CAAC,CAAC,EACrD,YAAa,IAAI,IAAIR,EAAM,QAASQ,GAAM,CAAC,GAAGA,EAAE,WAAW,CAAC,CAAC,EAC7D,MAAO,IAAI,IAAIR,EAAM,IAAKQ,GAAMA,EAAE,IAAI,CAAC,CACzC,CACF,CClKA,IAAIC,GAAU,QCmGd,IAAIC,GAAO,4DACPC,GAAS,GACTC,GAAY,GACZC,GAAa,GACbC,GAAe,GACfC,GAAQ,mBACRC,GAAW,UACf,SAASC,GAAIC,EAAG,CACd,OAAOA,EAAE,WAAW,IAAK,OAAO,EAAE,WAAW,IAAK,MAAM,EAAE,WAAW,IAAK,MAAM,EAAE,WAAW,IAAK,QAAQ,CAC5G,CACA,SAASC,GAAOC,EAAIC,EAAGC,EAAGC,EAAOC,EAAOC,EAAOC,EAAOC,EAAU,EAAG,CACjE,IAAMC,EAAML,EAAM,OAAS,EAAIZ,GAASC,GAClCiB,EAAON,EAAM,OAAS,EAAI,cAAcH,CAAE,KAAO,SAASG,EAAM,CAAC,EAAE,KAAK,IAAII,EAAU,EAAI,kBAAkBA,CAAO,IAAM,EAAE,GAC3HG,EAAOP,EAAM,OAAS,EAAI,uBAAuBH,CAAE,KAAKG,EAAM,IAAKL,GAAM,iBAAiBA,EAAE,MAAM,iBAAiBA,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,CAAC,oBAAsB,GAKrK,MAAO,CACL,MALY,KAAK,IACjBU,EAAM,GAAKJ,EAAM,OAASC,EAAM,QAAUM,IACzCL,GAAO,QAAU,GAAKK,EACzB,EAGE,OAAQ,GAAGD,CAAI,2BAA2BT,CAAC,IAAIC,CAAC,MAAMZ,EAAI,uBAAuBkB,CAAG,uBAAuBC,CAAI,cAAcD,EAAM,CAAC,sCAAsCX,GAAIO,CAAK,CAAC,WAAWP,GAAIQ,CAAK,CAAC,UAAUC,EAAQ,gBAAgBT,GAAIS,CAAK,CAAC,UAAY,EAAE,MACrQ,CACF,CACA,SAASM,GAAWX,EAAGC,EAAG,CACxB,MAAO,CACL,MAAOV,GAAY,EAAI,EAAImB,GAC3B,OAAQ,2BAA2BV,CAAC,IAAIC,CAAC,MAAMZ,EAAI,6BAA6BE,GAAY,CAAC,4CAA4CqB,EAAU,gCAAgCrB,GAAY,CAAC,0BAClM,CACF,CACA,SAASsB,GAAWd,EAAIC,EAAGC,EAAGa,EAAMX,EAAOY,EAAW,CACpD,IAAMC,EAAMC,GAAQH,EAAMC,CAAS,EACnC,OAAOjB,GACLC,EACAC,EACAC,EACAiB,GAAcJ,EAAK,QAAQ,EAC3BX,EACAa,EAAI,MAAQA,EAAI,QAAUA,EAAI,SAC9BA,EAAI,KACN,CACF,CACA,SAASG,GAAWC,EAAG,EAAG,CACxB,OAAOA,EAAE,WACP,mCACA,CAACC,EAAGC,EAAKtB,EAAGC,IAAM,GAAGqB,CAAG,GAAG,EAAE,OAAOtB,CAAC,EAAI,EAAE,OAAS,EAAE,YAAY,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAOC,CAAC,EAAI,EAAE,OAAS,EAAE,YAAY,QAAQ,CAAC,CAAC,EACnI,CACF,CACA,SAASsB,GAAKvB,EAAGC,EAAGuB,EAAGC,EAAMC,EAAM,CACjC,MAAO,YAAY1B,EAAIwB,EAAI,CAAC,QAAQvB,EAAI0B,GAAWC,GAAY,CAAC,YAAYJ,CAAC,aAAaG,GAAWC,GAAY,EAAI,CAAC,oDAAoDhB,EAAU,eAAeZ,CAAC,QAAQC,CAAC,2DAA2D0B,EAAQ,WAAWhC,EAAQ,uEAAuEC,GAAI6B,CAAI,CAAC,WAAWC,EAAO9B,GAAI8B,CAAI,EAAI,EAAE,SACrZ,CACA,SAASG,GAAUC,EAAOC,EAAQC,EAAI,CAAC,EAAG,CACxC,IAAMC,EAAQD,EAAE,OAAS,KACnBE,EAAOF,EAAE,QAAU,IACnBG,EAASH,EAAE,OACXI,EAAaJ,EAAE,aAAeG,EAC9BE,EAAOL,EAAE,SACTM,EAASC,GAAcR,EAAQ,CACnC,OAAQC,EAAE,aAAe,OAASG,EAClC,OAAQE,GAAQN,EAAO,OAASS,GAAeH,EAAML,EAAE,YAAY,EAAI,MACzE,CAAC,EACKS,EAAYV,EAAO,WAAa,GAChCW,EAAW,IAAI,IAAIZ,EAAM,MAAM,IAAKa,GAAS,CAACA,EAAK,GAAIA,CAAI,CAAC,CAAC,EAC7DC,EAAcC,GAAmBb,EAAE,aAAe,OAAQF,CAAK,EAC/DgB,EAAgBF,IAAgB,sBAAwB,CAACb,EAAO,QAAUgB,GAAqBjB,EAAOM,CAAU,EAAI,OACpHY,EAAeF,GAAiB,CACpC,MAAOA,EAAc,MACrB,IAAKA,EAAc,MAAQA,EAAc,IAC3C,EACMG,EAAiBC,GACrBpB,EACAC,EAAO,QAAU,CAAC,EAAIoB,GAAcrB,CAAK,EACzCE,EAAE,iBACJ,EACMoB,EAASpB,EAAE,OAAS,CAAC,EACrBqB,EAAWD,EAAO,KAAME,GAAMA,EAAE,OAAO,QAAU,WAAW,EAAIR,GAAiBC,GAAqBjB,EAAOM,CAAU,EAAI,OAC3HmB,EAAOH,EAAO,OAAS,GAAK,CAACrB,EAAO,QAAUyB,GAAS1B,EAAOsB,EAAQC,CAAQ,EAAI,OAClFI,EAAQC,GAAe1B,EAAE,KAAK,EAC9B2B,EAASF,EAAM,OAASF,GAAQA,EAAK,MAAM,OAAS,EAAIK,GAAW9B,EAAOyB,EAAMH,EAAQC,CAAQ,EAAI,OACpGQ,EAASC,GACbhC,EAAM,OAAO,OAASiC,GAAWjC,EAAM,KAAK,EAAI,CAAC,CACnD,EACMkC,EAAWvC,GAASoC,EAAO,IAAIpC,CAAI,GAAKA,EACxCwC,EAAgBjC,EAAE,eAAiBkC,GAAepC,EAAOK,CAAM,EAC/DpB,EAAYwC,GAAM,iBAAmB,CACzC,GAAGA,EAAK,gBACR,KAAMU,CACR,EACME,EAAkBnC,EAAE,iBAAmB,EACvCoC,EAAYpC,EAAE,WAAa,QAC3BqC,EAAOrC,EAAE,OAAO,QAAU,CAACD,EAAO,SAAW,CAACM,EAAOiC,GAASxC,EAAOE,EAAE,MAAOD,EAAO,aAAa,EAAI,CAAC,EACvGwC,EAAMC,GAAQ1C,EAAOY,EAAUyB,EAAiBC,CAAS,EAC3DK,EAAQ,EACZ,SAASC,EAASC,EAAWC,EAAGpD,EAAGqD,EAAG,CACpC,IAAMC,EAAM,CAAC,EACPC,GAAWC,GACfC,GAAcZ,EAAME,EAAI,YAAaI,EAAYvD,IAAMD,GAAWC,GAAGwD,CAAC,CAAC,EACvE,CAAE,GAAI,QAAQH,GAAO,GAAI,MAAOjD,EAAG,OAAQqD,CAAE,CAC/C,EACIE,IACFD,EAAI,KAAKI,GAAYH,EAAQ,CAAC,EAEhC,IAAMI,EAAUC,KAAO,CACrB,EAAGA,GAAE,EAAIR,EAAE,OAASA,EAAE,WACtB,EAAGQ,GAAE,EAAIR,EAAE,OAASA,EAAE,UACxB,GACMS,GAAQ,CAAE,MAAO7D,EAAG,OAAQqD,CAAE,EACpC,OAAW,CAAE,KAAMS,GAAK,EAAAtF,GAAG,EAAAC,GAAG,EAAGsF,GAAI,KAAAC,EAAK,IAAKC,GAC7CC,GACErB,EACAc,EACAhB,EACAwB,GAAc5D,EAAO,cAAe6C,CAAC,CACvC,EACAS,GACAO,GAAUP,EAAK,CACjB,EAAG,CACD,IAAMQ,GAAOV,EAAOG,GAAI,EAAE,EAAE,EAAInB,EAAkB,EAClDW,EAAI,KACF,aAAa9E,EAAC,SAASA,EAAC,SAASC,GAAI0B,GAAW,CAAC,SAASkE,EAAI,aAAalG,EAAQ,8CACnF4B,GAAKvB,GAAGC,GAAGsF,GAAID,GAAI,KAAK,KAAME,GAAK,MAAMF,GAAI,KAAK,KAAK,MAAM,CAAC,CAChE,CACF,CACIjD,GACFyC,EAAI,KACFI,GACEY,GACEzD,EACA,CAAE,GAAGuC,EAAG,MAAOpD,EAAG,OAAQqD,EAAG,GAAG7C,EAAE,YAAa,EAC/C,CACE,KAAMgB,EACN,SAAUhB,EAAE,QACd,CACF,CACF,CACF,EAEF,IAAM+D,GAAYC,GAAc3D,EAAMN,EAAQC,EAAE,YAAY,EAC5D,OAAW,CAAE,MAAA7B,GAAO,EAAAF,EAAE,IAAK8F,GAAW,CACpC,IAAME,GAAKhG,GAAI2E,EAAE,OAASA,EAAE,WACxBqB,IAAM,GAAKA,IAAMpB,GACnBC,EAAI,KACF,kBAAkBmB,GAAK,CAAC,KAAK5G,EAAI,wDAAwDO,GAAIO,EAAK,CAAC,SACrG,CAEJ,CACA,OAAO2E,EAAI,KAAK,EAAE,CACpB,CACA,SAASoB,EAAQvB,EAAWnD,EAAGqD,EAAG,CAChC,IAAMsB,EAAMC,GACV9D,EACAd,EACAqD,EACApC,EACAkB,EAAS,CACP,QAAS0C,GACT,OAAQA,GACR,SAAUA,GACV,UAAWA,EACb,EAAI,CAAC,CACP,EACA,GAAI,CAACF,EACH,MAAO,GAET,IAAMG,EAAOC,GAAYJ,EAAI,MAAO1D,CAAS,EACvC,CAAE,OAAA+D,GAAQ,OAAAC,CAAO,EAAIC,GAAUlF,EAAGqD,CAAC,EACnC8B,GAAW,IAAIC,GAAiBJ,EAAM,EAC5CG,GAAS,eACPE,GAAc,CACZ,GAAGC,GAAqB/E,EAAQkB,EAAgB,CAC9C,UAAW,CAAC,CAACZ,CACf,CAAC,EACD,MAAAP,EACA,SAAAY,EACA,YAAAE,EACA,gBAAAuB,EACA,mBAAoBnC,EAAE,oBAAsB,EAC5C,UAAW,GACX,UAAAoC,EACA,aAAcpC,EAAE,aAChB,UAAA2C,EACA,KAAA2B,EACA,cAAAxD,CACF,CAAC,CACH,EACA,IAAM8B,GAAI,CACR,OAAQ0B,EAAK,OACb,OAAQA,EAAK,OACb,WAAYH,EAAI,WAChB,WAAYA,EAAI,UAClB,EACA,OAAAQ,GAAS,gBAAgB,CAAE,GAAG/B,GAAG,IAAK,CAAE,CAAC,EACzC+B,GAAS,OAAO,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EACrBF,EAAO,EAAI/B,EAASC,EAAWC,GAAGpD,EAAGqD,CAAC,CAC/C,CACA,IAAMkC,EAAQ,CAAC,EACXC,GACJ,GAAIrD,EAAQ,CACV,IAAMsD,EAAQC,GACZvD,EAAO,IAAKyB,GAAMA,EAAE,MAAM,CAAC,EAAE,IAAI,EACjC3B,EAAM,OAAS,OACfA,EAAM,MACR,EACM0D,EAAOC,GAAU,CACrB,MAAOH,EAAM,MACb,OAAA3E,EACA,UAAAG,EACA,MAAAR,EACA,KAAAC,EACA,QAAS+E,EAAM,SAAWxD,EAAM,OAClC,CAAC,EACDE,EAAO,QAAQ,CAAC0D,EAAOC,IAAM,CAC3B,IAAMC,EAAON,EAAM,MAAMK,CAAC,EACpBtH,GAAIuH,EAAOJ,EAAK,SAAWA,EAAK,MAAQK,IACxCvH,EAAI,KAAK,MAAMsH,EAAOJ,EAAK,OAAO,GAAKA,EAAK,OAASM,GAAiBD,IACtE1G,GAAOuG,EAAM,MAAM,CAAC,EAC1BN,EAAM,KACJlG,GAAW,MAAMyG,CAAC,GAAItH,GAAI,EAAGC,EAAI,EAAGa,GAAMkD,EAAQlD,GAAK,IAAI,EAAGC,CAAS,EAAE,OACzE,WAAWf,EAAC,QAAQC,EAAIwH,EAAc,YAAYN,EAAK,KAAK,aAAaA,EAAK,MAAM,KAAKjB,EAAQmB,EAAOF,EAAK,MAAOA,EAAK,MAAM,CAAC,QAClI,CACF,CAAC,EACDH,GAASG,EAAK,KAChB,KAAO,CACL,IAAInH,EAAI,EACF0H,EAAQ1G,GAAQ,CACpB+F,EAAM,KAAK/F,EAAI,MAAM,EACrBhB,GAAKgB,EAAI,MAAQxB,EACnB,EAkBA,GAjBI+D,IACFA,EAAK,MAAM,QAAQ,CAACzC,EAAMwG,KAAM,CAC9BI,EAAK7G,GAAW,MAAMyG,EAAC,GAAItH,EAAG,EAAGc,EAAMkD,EAAQlD,EAAK,IAAI,EAAGC,CAAS,CAAC,CACvE,CAAC,EACD2G,EACE5H,GACE,QACAE,EACA,EACA,CAAC,CAAE,OAAQ,EAAG,MAAON,EAAM,CAAC,EAC5B,GACA,UAAU6D,EAAK,MAAM,SAAW,EAAIS,EAAQT,EAAK,MAAM,CAAC,EAAE,IAAI,EAAI,aAAa,GAC/E,OACA,EACF,CACF,GAEElB,EAAM,CACR,IAAMrB,EAAM2G,GACVC,GAAYvF,EAAM,CAChB,KAAMW,EACN,MAAOhB,EAAE,UAAU,KAAOA,EAAE,YAAc,MAC5C,CAAC,EACDhC,EACA,EACA,UACF,EACA0H,EAAK,CAAE,MAAO1G,EAAI,MAAO,OAAQkE,GAAYlE,EAAI,IAAI,CAAE,CAAC,CAC1D,KAAW,CAACuC,GAAQT,GAClB4E,EACE5H,GACE,OACAE,EACA,EACAkB,GAAc,CAAE,MAAO,YAAa,OAAQ,SAAU,CAAC,EACvD+C,EAAgB,GAAGA,CAAa,YAAc,qBAC9C,GACA4D,GACE5D,EACAnB,EAAc,MACdA,EAAc,MAAQA,EAAc,IACtC,CACF,CACF,EAEEuB,EAAK,KAAMiB,GAAQA,EAAI,YAAY,OAAS,CAAC,GAC/CoC,EAAK/G,GAAWX,EAAG,CAAC,CAAC,EAEvB,IAAM8H,EAASf,EAAM,OAAS,EAAIU,GAAiB,EAC7CM,EAAS9F,EAAQ,EAAI+F,EACrBC,EAAQxF,GAAa,EAAEH,EAAO,EAAI,GAAKA,EAAO,EAAIA,EAAO,EAAIyF,EAASzF,EAAO,EAC7EuC,GAAI,KAAK,IACb,IACA,KAAK,IAAI3C,EAAO4F,EAAQ,KAAK,KAAKG,EAAQ,EAAID,CAAW,CAAC,CAC5D,EACAjB,EAAM,KACJ,WAAWe,CAAM,YAAY7F,CAAK,aAAa4C,EAAC,KAAKqB,EAAQ3C,EAAMtB,EAAO4C,EAAC,CAAC,QAC9E,EACAmC,GAASc,EAASjD,EACpB,CACA,IAAMqD,EAAQlG,EAAE,UAChB,GAAIkG,GAAS,CAAC7F,GAAQ,CAACN,EAAO,QAAS,CACrC,IAAMsD,EAAQ8C,GAAeD,EAAM,KAAM,CAAE,MAAAjG,CAAM,CAAC,EAC5CjB,EAAM2G,GACVC,GAAYM,EAAM,KAAM,CACtB,KAAMlF,EACN,MAAOoF,GAAc/C,EAAO6C,EAAM,SAAUA,EAAM,WAAW,CAC/D,CAAC,EACD,EACAlB,GAAS3B,EAAM,OACf,WACF,EACA0B,EAAM,KACJ,oBAAoB9E,CAAK,SAAS+E,GAAS,EAAG,SAASA,GAAS,EAAG,oBACnE,WAAWA,EAAM,YAAY/E,CAAK,aAAaoD,EAAM,MAAM,KAAKH,GAC9DY,GAAaoC,EAAM,KAAM7C,EAAO,CAC9B,KAAMrC,EACN,SAAUkF,EAAM,SAChB,SAAU,OACZ,CAAC,CACH,CAAC,GAAGhD,GACFmD,GACEH,EAAM,KACN7C,EACA,IAAI,IAAIjC,EAAO,IAAKE,GAAMA,EAAE,IAAI,CAAC,CACnC,CACF,CAAC,SACD4B,GAAYlE,EAAI,IAAI,CACtB,EACAgG,IAAU3B,EAAM,OAAS5F,EAC3B,CACA,IAAM6I,EAAW,KAAK,UAAU,CAC9B,UAAW,yBAAyBC,EAAO,GAC3C,GAAGvG,EAAE,OAAS,OAAS,CAAC,EAAI,CAAE,KAAMA,EAAE,IAAK,CAC7C,CAAC,EACD,MAAO,kDAAkDC,CAAK,aAAa+E,EAAM,kBAAkB/E,CAAK,IAAI+E,EAAM,eAAepH,GAAI0I,CAAQ,CAAC,2BAA2BrG,CAAK,aAAa+E,EAAM,kBAAkBD,EAAM,KAAK,EAAE,CAAC;AAAA,CAEnO,CCnaA,IAAIyB,GAAkB,CACpB,GAAGC,GACH,YAAa,OACb,UAAW,QACX,gBAAiB,EACjB,mBAAoB,CACtB,EACA,SAASC,GAAmBC,EAAG,CAC7B,IAAMC,EAAWJ,GACXK,EAAM,CAAC,EACb,OAAW,CAACC,EAAGC,CAAC,IAAK,OAAO,QAAQJ,CAAC,EAC/BI,IAAM,QAAUA,IAAMH,EAASE,CAAC,IAClCD,EAAIC,CAAC,EAAIC,GAGb,OAAOF,CACT,CCpBA,IAAIG,GAAa,GACbC,GAAUC,GAAMA,EAAE,IAAMA,EAAE,IAC9B,SAASC,GAAeC,EAASC,EAAY,CAC3C,IAAMC,EAAOF,EAAQ,OAAOH,EAAM,EAClC,GAAIK,EAAK,SAAW,EAAG,CACrB,IAAMC,EAAQH,EAAQ,CAAC,EACvB,OAAOG,EAAQ,CAAC,CAAE,GAAIA,EAAM,GAAI,GAAIF,EAAWE,EAAM,GAAG,CAAE,CAAC,EAAI,CAAC,CAClE,CACA,IAAMC,EAASF,EAAK,IAAKJ,IAAO,CAC9B,EAAAA,EACA,GAAIG,EAAWH,EAAE,GAAG,EACpB,GAAIG,EAAWH,EAAE,GAAG,EACpB,SAAU,EACV,UAAW,CACb,EAAE,EACF,QAASO,EAAI,EAAGA,EAAI,EAAID,EAAO,OAAQC,IAAK,CAC1C,IAAMC,EAAOF,EAAOC,CAAC,EACfE,EAAQH,EAAOC,EAAI,CAAC,EAEpBG,EADS,KAAK,IAAID,EAAM,EAAE,GAAKD,EAAK,EAAE,GAAIV,EAAU,GAClCW,EAAM,GAAKD,EAAK,IACxC,GAAIE,EAAQ,EAAG,CACb,IAAMC,GAAWH,EAAK,GAAKA,EAAK,IAAM,EAChCI,GAAYH,EAAM,GAAKA,EAAM,IAAM,EACrCI,EAAW,KAAK,IAAIH,EAAQ,EAAGC,CAAO,EACpCG,EAAY,KAAK,IAAIJ,EAAQG,EAAUD,CAAQ,EACrDC,EAAW,KAAK,IAAIH,EAAQI,EAAWH,CAAO,EAC9CH,EAAK,UAAYK,EACjBJ,EAAM,SAAWK,CACnB,CACF,CACA,IAAMC,EAAQ,CAAC,EACf,OAAW,CAAE,EAAAf,EAAG,GAAAgB,EAAI,GAAAC,EAAI,SAAAC,EAAU,UAAAC,CAAU,IAAKb,EAC/CS,EAAM,KACJ,CAAE,GAAIf,EAAE,GAAI,GAAIgB,EAAKE,CAAS,EAC9B,CAAE,GAAIlB,EAAE,GAAI,GAAIiB,EAAKE,CAAU,CACjC,EAEF,OAAOJ,CACT,CACA,SAASK,GAAML,EAAOM,EAAI,CACxB,IAAM,EAAIN,EAAM,OAChB,GAAI,IAAM,EACR,OAAOM,EAET,IAAMhB,EAAQU,EAAM,CAAC,EACfO,EAAOP,EAAM,EAAI,CAAC,EACxB,GAAIM,GAAMhB,EAAM,GACd,OAAOA,EAAM,IAAMgB,EAAKhB,EAAM,IAEhC,GAAIgB,GAAMC,EAAK,GACb,OAAOA,EAAK,IAAMD,EAAKC,EAAK,IAE9B,IAAIC,EAAK,EACLC,EAAK,EAAI,EACb,KAAOA,EAAKD,EAAK,GAAG,CAClB,IAAME,EAAMF,EAAKC,GAAM,EACnBT,EAAMU,CAAG,EAAE,IAAMJ,EACnBE,EAAKE,EAELD,EAAKC,CAET,CACA,IAAMC,EAAIX,EAAMQ,CAAE,EACZI,EAAIZ,EAAMS,CAAE,EACZI,EAAOD,EAAE,GAAKD,EAAE,GACtB,OAAOE,EAAO,EAAIF,EAAE,IAAML,EAAKK,EAAE,IAAME,GAAQD,EAAE,GAAKD,EAAE,IAAMA,EAAE,EAClE,CC7DA,IAAIG,GAAmB,IACnBC,GAAe,EACnB,SAASC,GAAQC,EAASC,EAAc,CACtC,GAAM,CAAE,KAAAC,EAAM,KAAAC,CAAK,EAAIH,EAAQ,OAAO,OAChCI,EAAID,EAAOD,EACjB,OAAOF,EAAQ,SAAWI,EAAI,EAAI,KAAK,IAAIP,GAAkB,KAAK,IAAI,EAAGI,EAAeG,CAAC,CAAC,EAAI,CAChG,CACA,SAASC,GAAaL,EAASM,EAAM,CACnC,GAAM,CAAE,OAAAC,EAAQ,WAAAC,EAAY,WAAAC,CAAW,EAAIH,EACrCI,EAASJ,EAAK,OAASP,GAAQC,EAASM,EAAK,YAAY,EACzDK,EAAKC,IAAQA,EAAKZ,EAAQ,SAAWU,EAASD,EAC9C,CAAE,QAAAI,CAAQ,EAAIb,EACpB,GAAIa,EAAS,CACX,IAAMC,EAAQC,GAAeF,EAAUG,GAAOA,EAAKT,EAASC,CAAU,EACtE,MAAO,CAAE,EAAIS,GAAOC,GAAMJ,EAAOG,CAAE,EAAG,EAAAN,EAAG,OAAAD,CAAO,CAClD,CACA,MAAO,CAAE,EAAIO,GAAOA,EAAKV,EAASC,EAAY,EAAAG,EAAG,OAAAD,CAAO,CAC1D,CACA,SAASS,GAAcnB,EAAS,CAAE,EAAAoB,EAAG,EAAAT,CAAE,EAAGU,EAAIC,EAAI,CAChD,IAAIC,EAAM,KACV,OAAAvB,EAAQ,OAAO,MAAM,QAASwB,GAAS,CACjCA,EAAK,OAAS,GAAKJ,EAAEI,EAAK,EAAI1B,EAAY,GAAKuB,GAAMA,GAAMD,EAAEI,EAAK,EAAIA,EAAK,WAAa1B,EAAY,GAAKa,EAAEa,EAAK,EAAI1B,EAAY,GAAKwB,GAAMA,GAAMX,EAAEa,EAAK,EAAIA,EAAK,cAAgB1B,EAAY,IAC/LyB,EAAMC,EAAK,KAEf,CAAC,EACMD,CACT,CCiBA,IAAAE,GAGO,SACPC,GAA2B,UAC3BC,GAA0B,UCjBnB,SAASC,GAAaC,EAAmC,CAC9D,GAAI,OAAOA,GAAS,UAAYA,IAAS,KACvC,MAAO,GAET,IAAMC,EAAID,EACV,OACE,OAAOC,EAAE,kBAAqB,YAC9B,OAAOA,EAAE,QAAW,YACpB,wBAAyBA,GACzB,kBAAmBA,CAEvB,CAEA,SAASC,GAAOC,EAA8B,CAC5C,OAAOA,EAAO,OACZ,CAACC,EAAMC,IAAOD,GAAQA,EAAK,IAAMA,EAAK,OAASC,EAAE,IAAMA,EAAE,MAAQD,EAAOC,EACxE,MACF,CACF,CAoBO,SAASC,GAAUN,EAAkBO,EAAwB,CAClE,IAAMC,EAAQN,GACZF,EAAK,cAAc,cAAc,OAC/BK,GACEA,EAAE,UAAYE,EAAO,SAAWF,EAAE,eAAiBE,EAAO,YAC9D,CACF,EACM,CAAE,QAAAE,CAAQ,EAAIT,EACpB,GAAI,CAACQ,GAAS,EAAEC,EAAU,GACxB,OAEF,IAAMC,EAAOF,EAAM,SAAWR,EAAK,SACnC,OAAOQ,EAAM,SACT,CAAE,MAAO,GAAKC,EAAS,WAAYC,EAAOF,EAAM,IAAMC,CAAQ,EAC9D,CAAE,MAAO,EAAIA,EAAS,WAAYC,EAAOF,EAAM,MAAQC,CAAQ,CACrE,CAIO,SAASE,GAAWX,EAA0C,CACnE,IAAMQ,EAAQN,GAAOF,EAAK,cAAc,aAAa,EAC/CY,EACJJ,GAAO,uBAAyB,OAC5B,OACAR,EAAK,iBAAiBQ,EAAM,oBAAoB,EACtD,OAAOA,GAASR,EAAK,QAAU,EAC3B,CACE,QAASQ,EAAM,QACf,aAAcA,EAAM,aACpB,MAAOA,EAAM,MACb,IAAKA,EAAM,IACX,QAASR,EAAK,QACd,KAAMA,EAAK,QAAUA,EAAK,MAC1B,YAAaY,GAAW,OAASJ,EAAM,MACvC,UAAWI,GAAW,KAAOJ,EAAM,GACrC,EACA,MACN,CAIO,SAASK,GACdC,EACAC,EACAC,EAAU,GACM,CAChB,IAAMC,EAAUH,EAAO,IAAMA,EAAO,MAC9BI,EAASF,EACX,KAAK,IAAI,EAAG,KAAK,IAAIF,EAAO,MAAOC,EAAQE,GAAW,CAAC,CAAC,EACxD,EACAE,EAAQ,KAAK,IAAIL,EAAO,YAAa,KAAK,MAAMA,EAAO,MAAQI,CAAM,CAAC,EACtEE,EAAM,KAAK,IAAIN,EAAO,UAAW,KAAK,KAAKA,EAAO,IAAMI,CAAM,CAAC,EAG7DG,EAAOD,EAAMD,EAAQJ,EAC3B,OAAIM,EAAO,IACTF,GAAS,KAAK,MAAME,EAAO,CAAC,EAC5BD,GAAO,KAAK,KAAKC,EAAO,CAAC,GAEpB,CACL,QAASP,EAAO,QAChB,aAAcA,EAAO,aACrB,MAAAK,EACA,IAAAC,CACF,CACF,CAIO,SAASE,GACdC,EACAT,EACAE,EAAU,GACV,CACA,GACEO,GAAK,UAAYT,EAAO,SACxBS,EAAI,eAAiBT,EAAO,aAE5B,MAAO,GAGT,GAAIE,EACF,OAAOO,EAAI,OAAST,EAAO,MAAQ,GAAKA,EAAO,KAAOS,EAAI,IAAM,EAElE,IAAMC,EAAQX,GAAQC,EAAQ,IAAU,EAAK,EAC7C,OACE,KAAK,IAAIS,EAAI,MAAQC,EAAM,KAAK,EAAI,GAAK,KAAK,IAAID,EAAI,IAAMC,EAAM,GAAG,EAAI,CAE7E,CC9JA,IAAAC,GAA+B,SAC/BC,GAA8C,UCO9C,IAAIC,GAAiB,GACjBC,GAAc,EACdC,GAAiB,IACrB,SAASC,GAAYC,EAAOC,EAASC,EAAWC,EAAaC,GAASA,EAAMC,EAAU,CAAC,EAAG,CACxF,IAAMC,EAAS,IAAI,IAAIN,EAAM,MAAM,IAAKO,GAAM,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACpDC,EAAQ,CAAC,EACf,QAAWC,KAAUR,EAAS,CAC5B,IAAMS,EAAQ,CAAC,EACXC,EAAO,IACPC,EAAO,KACPC,EAAO,IACLC,EAAU,CAAC,EACXC,EAAO,CAAC,EACd,QAAWX,KAAQY,GAAiBP,CAAM,EAAG,CAC3C,IAAMQ,EAAOX,EAAO,IAAIF,CAAI,EACtBc,EAAOD,GAAQf,EAAUe,EAAK,EAAE,EACtC,GAAI,GAACA,GAAQ,CAACC,GAAM,QAGpB,IAAIC,EAAWF,CAAI,IAAMA,EAAK,OAAO,MAAQR,EAAO,OAASQ,EAAK,OAAO,OAASR,EAAO,KAAM,CAC7FM,EAAK,KAAKG,EAAK,KAAK,MAAMA,EAAK,OAAS,CAAC,CAAC,CAAC,EAC3C,QACF,CACAJ,EAAQ,KAAKG,EAAK,EAAE,EACpBP,EAAM,KAAKU,GAAQF,EAAK,SAAW,EAAI,CAACA,EAAK,CAAC,EAAGA,EAAK,CAAC,CAAC,EAAIA,CAAI,CAAC,EACjE,QAAWG,KAAKH,EACdP,EAAO,KAAK,IAAIA,EAAMU,EAAE,CAAC,EACzBT,EAAO,KAAK,IAAIA,EAAMS,EAAE,CAAC,EACzBR,EAAO,KAAK,IAAIA,EAAMQ,EAAE,CAAC,EAE7B,CACA,GAAIP,EAAQ,SAAW,EACrB,SAEF,IAAMQ,EAAU,CAAE,GAAIX,EAAOC,GAAQ,EAAG,EAAGC,CAAK,EAC1CU,EAASR,EAAK,OAAS,CAC3B,EAAGA,EAAK,OAAO,CAACS,EAAGH,IAAMG,EAAIH,EAAE,EAAG,CAAC,EAAIN,EAAK,OAC5C,EAAGA,EAAK,OAAO,CAACS,EAAGH,IAAMG,EAAIH,EAAE,EAAG,CAAC,EAAIN,EAAK,MAC9C,EAAIO,EACEG,EAA0B,IAAI,IACpC,QAAWC,KAASjB,EAAO,QAAU,CAAC,EACpC,QAAWkB,KAAM,IAAI,IAAID,EAAM,KAAK,EAClCD,EAAQ,IAAIE,GAAKF,EAAQ,IAAIE,CAAE,GAAK,GAAK,CAAC,EAG9C,IAAMC,EAAS,CAAC,EAChB,QAAWF,KAASjB,EAAO,QAAU,CAAC,EAAG,CACvC,GAAIA,EAAO,oBAAsBX,GAC/B,MAEF,GAAI4B,EAAM,MAAM,SAAW,EACzB,SAEF,IAAMG,EAAS,KAAK,IAAI,GAAGH,EAAM,MAAM,IAAKC,GAAOF,EAAQ,IAAIE,CAAE,CAAC,CAAC,EAC/DG,EACAC,EAAM,GACV,QAAWJ,KAAMD,EAAM,MACrB,GAAID,EAAQ,IAAIE,CAAE,IAAME,EAGxB,QAAWR,KAAKnB,EAAUyB,CAAE,GAAK,CAAC,EAAG,CACnC,IAAMK,EAAI,KAAK,MAAMX,EAAE,EAAIE,EAAO,EAAGF,EAAE,EAAIE,EAAO,CAAC,EAC/CS,EAAID,IACNA,EAAMC,EACNF,EAAKT,EAET,CAEES,GACFF,EAAO,KAAK,CAAE,MAAAF,EAAO,GAAAI,EAAI,KAAMG,GAAUP,EAAOvB,CAAS,CAAE,CAAC,CAEhE,CACAK,EAAM,KAAK,CACT,OAAAC,EACA,GAAGyB,GAAezB,EAAQJ,CAAO,EACjC,KAAMK,EAAM,KAAK,EAAE,EACnB,QAAAY,EACA,QAASR,EAAQ,OACjB,QAAAA,EACA,MAAOA,EAAQ,QAAUlB,GAAiBI,EAAM,MAAM,OACtD,OAAA4B,CACF,CAAC,CACH,CACA,OAAOpB,CACT,CACA,SAASyB,GAAUP,EAAOvB,EAAW,CACnC,IAAMgC,EAAQ,CAAC,GAAG,IAAI,IAAIT,EAAM,MAAM,IAAIvB,CAAS,CAAC,CAAC,EAAE,KAAK,EACtDiC,EAAQD,EAAM,MAAM,EAAGtC,EAAW,EAAE,KAAK,IAAI,EAC7CwC,EAAOF,EAAM,OAAStC,GAAc,KAAKsC,EAAM,OAAStC,EAAW,GAAK,GAC9E,MAAO,GAAGuC,CAAK,GAAGC,CAAI,SAASC,GAASZ,EAAM,EAAE,CAAC,EACnD,CC5FA,SAASa,GAAiBC,EAAO,CAC/B,GAAI,CAACA,EAAM,MAAM,KAAKC,CAAU,EAC9B,MAAO,CAAC,EAEV,IAAMC,EAAO,IAAI,IAAIF,EAAM,MAAM,IAAKG,GAAM,CAACA,EAAE,GAAIA,CAAC,CAAC,CAAC,EAChDC,EAAQC,GAAeL,CAAK,EAC5BM,EAAU,IAAI,IAAIF,EAAM,IAAI,CAACG,EAAIC,IAAM,CAACD,EAAIC,CAAC,CAAC,CAAC,EAC/CC,EAAQ,IAAI,WAAWL,EAAM,OAAS,CAAC,EACvCM,EAAuB,IAAI,IAC3BC,EAAyB,IAAI,IACnC,QAAWC,KAAKZ,EAAM,MAAO,CAC3B,IAAMa,EAAIP,EAAQ,IAAIM,EAAE,IAAI,EACtB,EAAIN,EAAQ,IAAIM,EAAE,EAAE,EAC1B,GAAIC,IAAM,QAAU,IAAM,QAAUA,IAAM,EACxC,SAEFF,EAAO,IAAI,GAAGC,EAAE,IAAI,IAAIA,EAAE,EAAE,EAAE,EAAE,IAAI,GAAGA,EAAE,EAAE,IAAIA,EAAE,IAAI,EAAE,EACvD,GAAM,CAACE,EAAIC,CAAE,EAAIF,EAAI,EAAI,CAACA,EAAG,CAAC,EAAI,CAAC,EAAGA,CAAC,EACvCJ,EAAMK,EAAK,CAAC,IACZL,EAAMM,CAAE,IACR,GAAM,CAACC,EAAMC,CAAE,EAAIJ,EAAI,EAAI,CAACD,EAAE,KAAMA,EAAE,EAAE,EAAI,CAACA,EAAE,GAAIA,EAAE,IAAI,GACxDF,EAAK,IAAIM,CAAI,GAAKN,EAAK,IAAIM,EAAsB,IAAI,GAAK,EAAE,IAAIA,CAAI,GAAG,IAAIC,CAAE,CAChF,CACA,QAAST,EAAI,EAAGA,EAAIC,EAAM,OAAQD,IAChCC,EAAMD,CAAC,GAAKC,EAAMD,EAAI,CAAC,EAEzB,IAAMU,EAAWlB,EAAM,MAAM,OAAOC,CAAU,EAAE,KAAK,CAACY,EAAGM,IAAMN,EAAE,OAAO,MAAQM,EAAE,OAAO,KAAK,EACxFC,EAAuB,IAAI,IAAI,CAACF,EAAS,CAAC,EAAE,GAAIA,EAAS,GAAG,EAAE,EAAE,EAAE,CAAC,EACnEG,EAAaH,EAAS,IAAKI,GAAS,CAACA,EAAMhB,EAAQ,IAAIgB,EAAK,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAACA,EAAMd,CAAC,IAAMY,EAAK,IAAIE,EAAK,EAAE,GAAKb,EAAMD,CAAC,IAAM,CAAC,EAAE,KAAK,CAAC,CAACK,EAAGU,CAAE,EAAG,CAAC,EAAGC,CAAE,IAAMD,EAAKC,GAAMX,EAAE,OAAO,MAAQ,EAAE,OAAO,KAAK,EAClMY,EAAYzB,EAAM,OAAO,IAAK,GAAM,CACxC,IAAM0B,EAAqB,IAAI,IAC/B,SAAE,QAAQ,QAAQ,CAACnB,EAAIC,IAAM,CACtBkB,EAAG,IAAInB,CAAE,GACZmB,EAAG,IAAInB,EAAIC,CAAC,CAEhB,CAAC,EACMkB,CACT,CAAC,EACKC,EAAU,CAAC,EACjB,QAASnB,EAAI,EAAGA,EAAI,EAAIa,EAAW,OAAQb,IAAK,CAC9C,GAAM,CAACoB,EAAOC,CAAE,EAAIR,EAAWb,CAAC,EAC1B,CAACsB,EAAKC,CAAE,EAAIV,EAAWb,EAAI,CAAC,EAC5BwB,EAAW5B,EAAM,MAAMyB,EAAK,EAAGE,CAAE,EACvC,GAAIC,EAAS,SAAW,EACtB,SAEF,IAAMC,EAAuB,IAAI,IAAI,CAAC,CAACL,EAAM,GAAI,CAAE,IAAK,EAAG,IAAK,EAAG,EAAG,CAAE,CAAC,CAAC,CAAC,EAC3E,QAAWrB,IAAM,CAACqB,EAAM,GAAI,GAAGI,CAAQ,EAAG,CACxC,IAAME,EAAMD,EAAK,IAAI1B,CAAE,EACvB,GAAK2B,EAGL,QAAWC,KAAKzB,EAAK,IAAIH,CAAE,GAAK,CAAC,EAAG,CAElC,GADWD,EAAQ,IAAI6B,CAAC,EACfJ,EACP,SAEF,IAAMK,EAAMD,IAAML,EAAI,GAAK,EAAI5B,EAAK,IAAIiC,CAAC,EAAE,OACrCE,EAAOJ,EAAK,IAAIE,CAAC,EACvBF,EAAK,IAAIE,EAAG,CACV,IAAK,KAAK,IAAIE,GAAM,KAAO,IAAUH,EAAI,IAAME,CAAG,EAClD,IAAK,KAAK,IAAIC,GAAM,KAAO,KAAWH,EAAI,IAAME,CAAG,EACnD,EAAG,KAAK,IAAIE,GAAsBJ,EAAI,GAAKG,GAAM,GAAK,EAAE,CAC1D,CAAC,CACH,CACF,CACA,IAAME,EAASd,GAAae,GAAWxC,EAAOE,EAAMuB,EAAWG,EAAM,GAAIE,EAAI,EAAE,EACzEW,EAAUF,GAAQ,EAAIA,EAAS,OAC/BG,EAASD,GAAWR,EAAK,IAAIH,EAAI,EAAE,GAAK,CAAE,IAAK,EAAG,IAAK,EAAG,EAAG,CAAE,EAC/Da,EAAaJ,IAAW,QAAUA,EAAO,KAAO,EAChDK,EAAWhB,EAAM,OAAO,MAAQA,EAAM,OACtCiB,EAASf,EAAI,OAAO,MACpBgB,EAAQ,CACZlB,EAAM,GACN,GAAGI,EAAS,OAAQzB,GAAON,EAAWC,EAAK,IAAIK,CAAE,CAAC,CAAC,EACnDuB,EAAI,EACN,EACMiB,EAAcD,EAAM,KACxB,CAACvC,EAAIyC,IAAMA,EAAI,GAAK,CAACrC,EAAO,IAAI,GAAGmC,EAAME,EAAI,CAAC,CAAC,IAAIzC,CAAE,EAAE,CACzD,EACM0C,EAAUF,GAAeJ,EACzBO,EAAWH,GAAe,CAACN,EACjCd,EAAQ,KAAK,CACX,QAASC,EAAM,OAAO,QACtB,MAAOgB,EACP,IAAKC,EACL,aAAcb,EAAS,OAAS,EAChC,UAAWU,EAAO,EAIlB,UAAW,GACX,qBAAsBQ,EAAWL,EAASD,EAAWF,EAAO,IAC5D,oBAAqBQ,EAAWL,EAASD,EAAWF,EAAO,IAC3D,SAAU,CAACd,EAAO,GAAGI,EAAS,IAAKzB,GAAOL,EAAK,IAAIK,CAAE,CAAC,EAAGuB,CAAG,EAAE,IAAK3B,GAAMA,EAAE,IAAI,EAAE,KAAK,GAAG,EACzF,eAAgB,OAChB,cAAe,OACf,QAAA8C,EACA,OAAQR,GAAS,MACnB,CAAC,CACH,CACA,OAAOd,CACT,CACA,SAASa,GAAWxC,EAAOE,EAAMuB,EAAW0B,EAASC,EAAO,CAC1D,IAAMC,EAAuB,IAAI,IAC7BC,EAAM,IACNC,EAAM,KACNC,EAAO,EACX,OAAAxD,EAAM,MAAM,QAAQ,CAACyD,EAAGT,IAAM,CAC5B,IAAMnB,EAAKJ,EAAUuB,CAAC,EAAE,IAAIG,CAAO,EAC7BpB,EAAKN,EAAUuB,CAAC,EAAE,IAAII,CAAK,EACjC,GAAIvB,IAAO,QAAUE,IAAO,OAAQ,EAC9BF,IAAO,QAAUE,IAAO,SAC1ByB,IAEF,MACF,CACA,IAAME,EAAQD,EAAE,QAAQ,MAAM,KAAK,IAAI5B,EAAIE,CAAE,EAAI,EAAG,KAAK,IAAIF,EAAIE,CAAE,CAAC,EAChEA,EAAKF,GACP6B,EAAM,QAAQ,EAEhB,IAAIC,EAAK,EACT,QAAWpD,KAAMmD,EACfC,GAAMzD,EAAK,IAAIK,CAAE,GAAG,QAAU,EAEhC,IAAMqD,EAAMF,EAAM,KAAK,GAAG,EACpBG,EAAQR,EAAK,IAAIO,CAAG,GAAK,CAAE,MAAAF,EAAO,GAAAC,EAAI,MAAO,CAAC,CAAE,EACtDE,EAAM,MAAM,KAAKJ,EAAE,IAAI,EACvBJ,EAAK,IAAIO,EAAKC,CAAK,EACnBP,EAAM,KAAK,IAAIA,EAAKK,CAAE,EACtBJ,EAAM,KAAK,IAAIA,EAAKI,CAAE,CACxB,CAAC,EACMN,EAAK,MAAQG,EAAO,CAAE,IAAAF,EAAK,IAAAC,EAAK,EAAGF,EAAK,KAAM,KAAAG,EAAM,OAAQ,CAAC,GAAGH,EAAK,OAAO,CAAC,CAAE,EAAI,MAC5F,CCvIA,SAASS,GAAkBC,EAAOC,EAAaC,EAAe,CAC5D,GAAID,IAAgB,WAAaA,IAAgB,OAC/C,OAEF,IAAME,EAAQ,CAAE,GAAGC,GAAwBJ,CAAK,EAAG,cAAAE,CAAc,EACjE,OAAO,IAAI,IACTF,EAAM,MAAM,IAAI,CAACK,EAAMC,IAAU,CAC/BD,EAAK,GACLE,GAAcC,GAAaH,EAAMC,EAAOL,EAAaE,CAAK,CAAC,CAC7D,CAAC,CACH,CACF,CCiBA,IAAAM,GAA+B,SAC/BC,GAAoC,UACpCC,GAKO,UC5CP,IAAAC,GAA+B,SAC/BC,GAA2B,UAgBrBC,GAAkB,cAKjB,SAASC,GACdC,EACAC,EACA,CACA,IAAMC,EAAYF,EAAc,qBAAuB,CAAC,EAIlDG,EAAU,IAAI,IAAI,OAAO,OAAOD,CAAQ,CAAC,EACzCE,EAAsC,CAAC,EAC7C,OAAW,CAAE,KAAAC,EAAM,QAAAC,CAAQ,IAAKL,EAAY,CAC1C,IAAMM,EAASD,EAAQ,KAAKE,GAASV,GAAgB,KAAKU,CAAK,CAAC,EAC5DD,IAAW,QAAa,CAACJ,EAAQ,IAAII,CAAM,IAC7CH,EAAYC,CAAI,EAAIE,EAExB,CACA,OAAO,OAAO,KAAKH,CAAW,EAAE,SAAW,EACvCJ,EACA,CACE,GAAGA,EACH,oBAAqB,CAAE,GAAGI,EAAa,GAAGF,CAAS,CACrD,CACN,CAMO,SAASO,GACdC,EACAC,EACA,CACA,IAAMX,KAAgB,mBAAeW,EAAO,SAAS,EAIrD,OAAOX,EAAc,OAAS,wBAC1BD,GACEC,KACA,eAAWU,CAAI,EAAE,gBAAgB,aAAa,IAAIE,IAAS,CACzD,QAAM,mBAAeA,EAAM,MAAM,EACjC,WAAU,mBAAeA,EAAM,SAAS,GAAK,CAAC,CAChD,EAAE,CACJ,EACAZ,CACN,CChEA,SAASa,GAAgBC,EAAW,CAClC,IAAMC,EAAM,CAAC,EACb,QAAWC,IAAM,CAAC,GAAGF,CAAS,EAAE,KAAK,CAACG,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,EAAG,CACjE,IAAMC,EAAOJ,EAAI,GAAG,EAAE,EAClBI,GAAQH,EAAG,OAASG,EAAK,IAC3BA,EAAK,IAAM,KAAK,IAAIA,EAAK,IAAKH,EAAG,GAAG,EAEpCD,EAAI,KAAK,CAAE,GAAGC,CAAG,CAAC,CAEtB,CACA,OAAOD,CACT,CA2GA,SAASK,GAAuBC,EAAO,CACrC,IAAMC,EAAM,CAAC,EACPC,EAAuB,IAAI,IACjC,QAAWC,IAAK,CAAC,GAAGH,CAAK,EAAE,KAAK,CAACI,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,EAAG,CAC5D,IAAMC,EAAM,GAAGH,EAAE,OAAO,IAAIA,EAAE,MAAM,IAAIA,EAAE,IAAI,GACxCI,EAAOL,EAAK,IAAII,CAAG,EACzB,GAAIC,GAAQJ,EAAE,MAAQI,EAAK,IACzBA,EAAK,IAAM,KAAK,IAAIA,EAAK,IAAKJ,EAAE,GAAG,EACnCI,EAAK,MAAQC,GAAgB,CAAC,GAAGD,EAAK,MAAO,GAAGJ,EAAE,KAAK,CAAC,MACnD,CACL,IAAMM,EAAO,CAAE,GAAGN,EAAG,MAAOK,GAAgBL,EAAE,KAAK,CAAE,EACrDF,EAAI,KAAKQ,CAAI,EACbP,EAAK,IAAII,EAAKG,CAAI,CACpB,CACF,CACA,OAAOR,CACT,CCxIA,IAAAS,GAA+B,SAQlBC,GAAqB,IAAI,IAAI,CACxC,mBACA,cACA,kBACA,aACA,kBACA,aACA,gBACA,eACF,CAAC,EAEKC,GAAkB,0CAIlBC,GAAoB,IAAI,IAAI,CAAC,kBAAmB,YAAY,CAAC,EAK5D,SAASC,GAEdC,EAAaC,EAAe,CAC5B,GAAIA,EACF,OAAOD,EAAO,KAAKE,GAAKA,EAAE,UAAYD,CAAK,EAE7C,IAAME,EAAaH,EAAO,OAAOE,GAAKN,GAAmB,IAAIM,EAAE,WAAW,CAAC,EAC3E,OACEC,EAAW,KAAKD,GACdL,GAAgB,KAAK,GAAGK,EAAE,OAAO,IAAIA,EAAE,MAAQ,EAAE,EAAE,CACrD,GAAKC,EAAW,KAAKD,GAAK,CAACJ,GAAkB,IAAII,EAAE,WAAW,CAAC,CAEnE,CAYO,SAASE,GAAYC,EAAcC,EAA6B,CACrE,IAAMC,EAAQF,EAAkB,QAAQ,KACtCH,MAAK,mBAAeA,EAAE,cAAe,SAAS,IAAMI,CACtD,GAAG,SAAS,CAAC,EACb,OAAOC,KACD,mBAAeA,EAAK,cAAe,QAAQ,GAC3C,CAAC,EACH,CAAC,CACP,CAKA,IAAMC,GAAuB,IAAI,IAAI,CACnC,aACA,SACA,SACA,cACA,UACF,CAAC,EAID,SAASC,GAAMC,EAAgBC,EAAuB,CACpD,OAAO,OAAQD,EAAc,KAAQ,WAChCA,EAAc,IAAIC,CAAI,EACtBD,EAA8BC,CAAI,CACzC,CAIA,IAAMC,GAAa,IAAI,IAAI,CACzB,OACA,MACA,iBACA,kBACA,KACF,CAAC,EAED,SAASC,GAAQH,EAAgBI,EAAwC,CACvE,IAAMC,EAAON,GAAMC,EAAG,MAAM,EACxB,OAAOK,GAAS,UAAYH,GAAW,IAAIG,CAAI,GACjDD,EAAK,KAAK,CACR,MAAOL,GAAMC,EAAG,OAAO,EACvB,IAAKD,GAAMC,EAAG,KAAK,CACrB,CAAC,EAEH,IAAMM,EAAWP,GAAMC,EAAG,aAAa,EACvC,QAAWO,KAASD,GAAY,CAAC,EAC/BH,GAAQI,EAAOH,CAAI,CAEvB,CAEA,SAASI,GAAOC,EAA6C,CAC3D,IAAMC,EAAS,CAAC,GAAGD,CAAS,EAAE,KAAK,CAACE,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,EACxDC,EAAwC,CAAC,EAC/C,QAAWC,KAAMJ,EAAQ,CACvB,IAAMK,EAAOF,EAAI,GAAG,EAAE,EAClBE,GAAQD,EAAG,OAASC,EAAK,IAC3BA,EAAK,IAAM,KAAK,IAAIA,EAAK,IAAKD,EAAG,GAAG,EAEpCD,EAAI,KAAK,CAAE,GAAGC,CAAG,CAAC,CAEtB,CACA,OAAOD,CACT,CAUO,SAASG,GAAeC,EAAsC,CACnE,IAAMC,EAAqB,CAAC,EAC5B,QAAWlB,KAAKiB,EAAU,CACxB,IAAMhB,EACHF,GAAMC,EAAG,WAAW,GACpBD,GAAMC,EAAG,MAAM,GACfD,GAAMC,EAAG,MAAM,GACfD,GAAMC,EAAG,SAAS,EACfmB,EAAQpB,GAAMC,EAAG,OAAO,EACxBoB,EAAMrB,GAAMC,EAAG,KAAK,EAC1B,GACE,CAACC,GACD,EAAEmB,EAAMD,IACRrB,GAAqB,IAAIC,GAAMC,EAAG,MAAM,CAAW,EAEnD,SAEF,IAAMqB,EAA0C,CAAC,EACjDlB,GAAQH,EAAGqB,CAAK,EAChBH,EAAM,KAAK,CACT,KAAAjB,EACA,QAASF,GAAMC,EAAG,SAAS,EAC3B,MAAAmB,EACA,IAAAC,EACA,OAASrB,GAAMC,EAAG,QAAQ,GAA4B,EACtD,MAAOqB,EAAM,OAASb,GAAOa,CAAK,EAAI,CAAC,CAAE,MAAAF,EAAO,IAAAC,CAAI,CAAC,CACvD,CAAC,CACH,CACA,OAAOE,GAAuBJ,CAAK,CACrC,CCxHO,IAAMK,GAAuB,IAAI,IAAI,CAC1C,aACA,kBACA,gBACA,aACA,iBACF,CAAC,EAEKC,GACJ,gEAEK,SAASC,GAEdC,EAAaC,EAAe,CAC5B,OAAIA,EACKD,EAAO,KAAKE,GAAKA,EAAE,UAAYD,CAAK,EAE1BD,EAAO,OAAOE,GAAKL,GAAqB,IAAIK,EAAE,WAAW,CAAC,EAC3D,KAAKA,GACrBJ,GAAkB,KAAK,GAAGI,EAAE,OAAO,IAAIA,EAAE,MAAQ,EAAE,EAAE,CACvD,CACF,CAIA,SAASC,GAAIC,EAAgBC,EAAuB,CAClD,OAAO,OAAQD,EAAc,KAAQ,WAChCA,EAAc,IAAIC,CAAI,EACtBD,EAA8BC,CAAI,CACzC,CAKA,IAAMC,GAAc,2BAEpB,SAASC,GAAWH,EAAgB,CAClC,IAAMC,EAAOF,GAAIC,EAAG,MAAM,EAC1B,GAAI,SAAOC,GAAS,UAAY,CAACC,GAAY,KAAKD,CAAI,GAGtD,OAAO,OAAO,YACZA,EAAK,MAAM,GAAG,EAAE,IAAIG,GAAQ,CAC1B,IAAMC,EAAID,EAAK,QAAQ,GAAG,EAC1B,MAAO,CAACA,EAAK,MAAM,EAAGC,CAAC,EAAGD,EAAK,MAAMC,EAAI,CAAC,CAAC,CAC7C,CAAC,CACH,CACF,CAIA,SAASC,GAAMN,EAAgBC,EAAuB,CACpD,IAAMM,EAAMR,GAAIC,EAAGC,CAAI,EACvB,OAAIM,IAAQ,OACHA,EAEIR,GAAIC,EAAG,MAAM,IACZC,CAAI,GAAKE,GAAWH,CAAC,IAAIC,CAAI,CAC7C,CAEA,IAAMO,GAAe,CACnB,MACA,SACA,KACA,SACA,QACA,WACA,WACF,EACMC,GAAgB,CACpB,MACA,SACA,SACA,gBACA,OACA,YACF,EACMC,GAAc,CAAC,OAAQ,QAAS,QAAS,KAAM,OAAQ,IAAI,EAKjE,SAASC,GAAMX,EAAgBY,EAAiB,CAC9C,QAAWX,KAAQW,EAAO,CACxB,IAAMC,EAAQP,GAAMN,EAAGC,CAAI,EACrBa,EAAM,QAAQ,MAAM,QAAQD,CAAK,EAAIA,EAAM,CAAC,EAAIA,IAAU,EAAE,EAC/D,MAAM,GAAG,EAAE,CAAC,EACZ,KAAK,EACR,GAAIC,IAAQ,IAAMA,IAAQ,IACxB,OAAOA,CAEX,CAEF,CAEA,IAAMC,GAAQ,yBAGP,SAASC,GAAahB,EAAgB,CAC3C,IAAMiB,EAAS,OAAON,GAAMX,EAAGS,EAAa,CAAC,EAC7C,GAAI,OAAO,SAASQ,CAAM,GAAKA,EAAS,EACtC,OAAO,KAAK,MAAMA,CAAM,EAE1B,IAAMC,EAAQP,GAAMX,EAAGQ,EAAY,EACnC,OAAOU,GAASH,GAAM,KAAKG,CAAK,EAAIA,EAAM,OAAS,MACrD,CAKA,SAASC,GAAQN,EAAgB,CAI/B,OAHuB,MAAM,QAAQA,CAAK,EACtCA,EACA,OAAOA,GAAS,EAAE,EAAE,MAAM,GAAG,GACtB,IAAIC,GAAO,CACpB,IAAMM,EACJN,IAAQ,IAAMA,IAAQ,MAAQA,IAAQ,OAAY,IAAM,OAAOA,CAAG,EACpE,OAAO,OAAO,SAASM,CAAC,EAAIA,EAAI,MAClC,CAAC,CACH,CAEA,SAASC,GAAQR,EAAgB,CAI/B,OAHuB,MAAM,QAAQA,CAAK,EACtCA,EACA,OAAOA,GAAS,EAAE,EAAE,MAAM,GAAG,GACtB,IAAIC,GAAO,CACpB,IAAMQ,EAAO,OAAOR,GAAO,EAAE,EAAE,KAAK,EACpC,OAAOQ,IAAS,IAAMA,IAAS,IAAM,OAAYA,CACnD,CAAC,CACH,CAEA,IAAMC,GAAgB,WAMtB,SAASC,GAAexB,EAAgB,CACtC,IAAMyB,EAAOJ,GAAQtB,GAAIC,EAAG,KAAK,CAAC,EAClC,GAAI,CAACyB,EAAK,SAASF,EAAa,EAC9B,OAEF,IAAMG,EAAKP,GAAQb,GAAMN,EAAG,IAAI,CAAC,EAC3B2B,EAAMN,GAAQf,GAAMN,EAAG,KAAK,CAAC,EAC7B4B,EAAMT,GAAQb,GAAMN,EAAG,KAAK,CAAC,EAC7B6B,EAAMV,GAAQb,GAAMN,EAAG,KAAK,CAAC,EAC7B8B,EAAKX,GAAQb,GAAMN,EAAG,IAAI,CAAC,EAC7B+B,EAAI,EACR,OAAON,EAAK,IAAI,CAACO,EAAK3B,IAAM,CAC1B,IAAMe,EAAIM,EAAGrB,CAAC,IAAM2B,IAAQT,GAAgB,EAAI,GAC5CU,EAAK,EACLC,EAAQ,EACZ,QAASC,EAAI,EAAGA,EAAIf,EAAGe,IAAKJ,IAAK,CAC/B,IAAMb,EAAQS,EAAII,CAAC,EACbK,EACJR,EAAIG,CAAC,IAAMb,GAASH,GAAM,KAAKG,CAAK,EAAIA,EAAM,OAAS,QACnDmB,EAAQR,EAAIE,CAAC,EACbO,EACJR,EAAGC,CAAC,IACHK,GAAcC,IAAU,OACrB,KAAK,MAAMD,EAAaC,CAAK,EAC7B,QACFC,IAAU,SACZL,GAAMK,EACNJ,IAEJ,CACA,OAAOF,IAAQT,IAAiBH,EAAI,GAAKc,IAAUd,EAAIa,EAAK,MAC9D,CAAC,CACH,CAKA,SAASM,GACPC,EACAC,EACAC,EACA,CACA,IAAMC,EAASH,GAAI,SAAS,GAAG,EAC/B,OAAQA,GAAM,IAAI,MAAM,MAAM,EAAE,QAAQ,CAACI,EAAOb,IAAoB,CAClE,IAAM,EAAI,OAAOa,CAAK,EAChBX,EAAK,EAAI,EAAIQ,EAAS,EAAI,CAAC,EAAIC,EACrC,MAAI,CAAC,OAAO,UAAU,CAAC,GAAKT,IAAO,OAC1B,CAAC,EAEH,CAAC,CAAE,GAAAA,EAAI,GAAIU,EAAS,CAAE,UAAWZ,EAAI,CAAE,EAAI,CAAC,CAAG,CAAC,CACzD,CAAC,CACH,CAEA,SAASc,GACP7C,EACAyC,EACAC,EACA,CACA,IAAMI,EAAU/C,GAAIC,EAAG,SAAS,EAE1B+C,EAAuC,CAAC,EAC9C,OAAW,CAACC,EAAQC,CAAM,IAAK,OAAO,QAAQH,GAAW,CAAC,CAAC,EAAG,CAC5D,IAAMI,EAAQ/B,GAAQ8B,EAAO,EAAE,EACzBE,EAAUhC,GAAQ8B,EAAO,EAAE,EAAE,QAAQ,CAAChB,EAAI5B,IAC9C4B,IAAO,QAAaA,EAAK,EACrB,CAACiB,EAAM7C,CAAC,IAAM,OAAY,CAAE,GAAA4B,CAAG,EAAI,CAAE,GAAAA,EAAI,cAAeiB,EAAM7C,CAAC,CAAE,CAAC,EAClE,CAAC,CACP,EACM+C,EACJD,EAAQ,OAAS,GAAK,CAACV,EACnBU,EACAZ,GAAUlB,GAAQ4B,EAAO,EAAE,EAAE,CAAC,EAAGR,EAAUC,CAAW,EACxDU,EAAM,OAAS,IACjBL,EAAOC,CAAM,EAAII,EAErB,CACA,OAAO,OAAO,KAAKL,CAAM,EAAE,OAAS,EAAIA,EAAS,MACnD,CAIA,SAASM,GAAOrD,EAAgBsD,EAAiB,CAC/C,IAAMC,EAAQjD,GAAMN,EAAG,OAAO,EACxBwD,EAAMlD,GAAMN,EAAG,KAAK,EACpByD,EAAQtC,GAAQb,GAAMN,EAAG,OAAO,CAAC,EAAE,CAAC,EAC1C,OAAOsD,GAAUG,IAAU,OACvB,CAAE,MAAOF,EAAQ,EAAG,IAAKA,EAAQ,EAAIE,CAAM,EAC3C,CAAE,MAAAF,EAAO,IAAAC,CAAI,CACnB,CAEO,SAASE,GAAiBC,EAAwC,CACvE,IAAMC,EAAwB,CAAC,EAC/B,QAAW5D,KAAK2D,EAAU,CACxB,IAAMlB,EAAWjB,GAAexB,CAAC,EAC3B,CAAE,MAAAuD,EAAO,IAAAC,CAAI,EAAIH,GAAOrD,EAAGyC,IAAa,MAAS,EACjDoB,EAAO7C,GAAahB,CAAC,EAC3B,GAAI,EAAEwD,EAAMD,IAAUM,IAAS,OAC7B,SAEF,IAAMC,EAAUxD,GAAMN,EAAG,SAAS,EAC5BkB,EAAQP,GAAMX,EAAGQ,EAAY,EAC7BuD,EAASpD,GAAMX,EAAGU,EAAW,EACnCkD,EAAO,KAAK,CACV,IAAK,GAAGE,CAAO,IAAIP,CAAK,IAAIC,CAAG,GAC/B,MACGO,GAAU,CAAC7D,GAAY,KAAK6D,CAAM,EAAIA,EAAS,UAC/C7C,GAASA,EAAM,QAAU,GACtB,IAAIA,CAAK,KACT,GAAG4C,CAAO,KAAKP,EAAQ,GAAG,eAAe,CAAC,IAAIC,EAAI,eAAe,CAAC,IACxE,QAAAM,EACA,MAAAP,EACA,IAAAC,EACA,KAAAK,EACA,MAAA3C,EACA,MAAO2B,GAAQ7C,EAAGyC,EAAUe,EAAMD,CAAK,CACzC,CAAC,CACH,CACA,OAAOK,EAAO,KAAK,CAACI,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,CAChD,CJ3NO,IAAMC,GAAiBC,GAC3B,MAAMC,IAAS,CACd,IAAI,mBAAqC,CACvC,MAAO,OACT,EACA,IAAI,oBAAkC,CACpC,MAAO,MACT,EAEA,IAAI,kBAAmB,CACrB,MAAO,EACT,EACA,IAAI,cAAe,CACjB,MAAO,EACT,EAEA,IAAI,aAAiD,CACnD,GAAI,CACF,SAAO,uBAAmBA,CAAI,EAAE,aAClC,MAAQ,CACN,MACF,CACF,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,kBAAmB,CACrB,OAAOA,EAAK,YAAcA,EAAK,iBACjC,EACA,IAAI,mBAAoB,CACtB,OAAOA,EAAK,aAAeA,EAAK,kBAClC,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,WAAY,CACd,SAAO,sBAAkBA,CAAI,EAAE,KACjC,EAIA,IAAI,YAAa,CACf,OAAOA,EAAK,cAAc,SAAS,QAAQ,OAASA,EAAK,KAC3D,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,UAAW,CACb,GAAIA,EAAK,WAAY,CACnB,IAAMC,EAAI,IAAI,IACd,QAAW,KAAKD,EAAK,WAAW,MAC9BC,EAAE,IAAI,EAAE,GAAI,CAAC,EAEf,OAAOA,CACT,CAEF,EAKA,IAAI,aAAc,CAChB,IAAMA,EAAI,IAAI,IACd,QAAW,KAAKD,EAAK,YAAY,OAAS,CAAC,EACzCC,EAAE,IAAI,EAAE,GAAI,EAAE,MAAM,EAEtB,OAAOA,CACT,EACA,IAAI,WAAY,CACd,OAAOD,EAAK,OAAO,MAAM,QAAU,CACrC,EACA,IAAI,WAAY,CACd,OAAOA,EAAK,OAAO,MAAM,QAAU,CACrC,EACA,IAAI,WAAY,CACd,OAAOA,EAAK,OAAO,OAAO,QAAU,CACtC,EACA,IAAI,UAAW,CACb,OAAOA,EAAK,QAAU,MACxB,EACA,IAAI,iBAAkB,CACpB,OAAOE,GAAgBF,CAAI,CAC7B,EAIA,IAAI,aAAc,CAChB,OACEA,EAAK,QAAU,SACdA,EAAK,WACJA,EAAK,kBACJA,EAAK,QAAU,QAAa,CAACE,GAAgBF,CAAI,EAExD,EAIA,IAAI,eAAgB,CAClB,OAAOA,EAAK,WAAa,CAACA,EAAK,YACjC,EAUA,IAAI,kBAAmB,CACrB,OAAOA,EAAK,MACRG,GAAqBH,EAAK,iBAAkBA,EAAK,KAAK,EACtD,EACN,EAIA,IAAI,iBAAkB,CACpB,OAAOA,EAAK,OAAO,MAAM,KAAKI,GAAKA,EAAE,QAAQ,OAAS,CAAC,GAAK,EAC9D,EAGA,IAAI,aAAc,CAChB,OAAOJ,EAAK,OAAO,aAAe,CAAC,CACrC,EAEA,IAAI,aAAc,CAChB,IAAMK,EAAQL,EAAK,OAAO,MAC1B,OAAOK,GAAO,OAASC,GAAWD,CAAK,EAAI,CAAC,CAC9C,EASA,IAAI,oBAAqB,CACvB,OAAOL,EAAK,WAAaO,GAAkBP,EAAK,OAAO,OAAO,QAAU,CAAC,CAC3E,EAIA,IAAI,qBAAsB,CACxB,OAAOA,EAAK,OAAO,aACrB,EAGA,IAAI,YAAa,CACf,OAAOA,EAAK,aAAeA,EAAK,WAClC,EAGA,IAAI,UAAW,CACb,GAAM,CAAE,MAAAQ,CAAM,EAAIR,EAClB,OAAOQ,GACLR,EAAK,WAAW,KAAKS,GAASA,EAAM,OAAO,QAAU,WAAW,EAC9DC,GAAqBF,EAAO,KAAK,UAAU,EAC3C,MACN,EAGA,IAAI,gBAAiB,CACnB,OAAOG,EAAkBX,EAAK,gBAAgB,EAAE,UAClD,EAEA,IAAI,kBAAgC,CAClC,OAAOA,EAAK,WAAW,OAAS,GAAK,CAAC,KAAK,eACvCA,EAAK,WACLA,EAAK,gBAAgB,IAAIY,IAAS,CAAE,KAAAA,CAAK,EAAE,CACjD,EAGA,IAAI,UAAW,CACb,GAAM,CAAE,MAAAJ,CAAM,EAAIR,EACZa,EAAS,KAAK,iBACpB,OAAOL,GAASK,EAAO,OAAS,GAAK,CAACb,EAAK,cAAc,QACrDc,GAASN,EAAOK,EAAQ,KAAK,QAAQ,EACrC,MACN,EAIA,IAAI,aAAc,CAChB,GAAM,CAAE,MAAAL,CAAM,EAAIR,EACZe,EAAO,KAAK,SAClB,OAAOf,EAAK,MAAM,QAAU,IAC1B,KAAK,gBACLQ,GACAO,GACAf,EAAK,WAAW,OAAS,GACzBe,EAAK,MAAM,OAAS,EAClBC,GAAWR,EAAOO,EAAMf,EAAK,WAAY,KAAK,QAAQ,EACtD,MACN,EAEA,IAAI,YAAa,CACf,OACE,KAAK,aAAa,IAAIiB,GAASA,EAAM,MAAM,CAAC,CAAE,GAC9C,KAAK,UAAU,OACf,CAAC,CAEL,EAEA,IAAI,YAAa,CACf,MAAO,CAACC,GAAe,IAAIlB,EAAK,gBAAgB,CAClD,EAEA,IAAI,eAAgB,CAClB,IAAMmB,EAAS,KAAK,UAAU,gBAC9B,OAAOA,GAAU,CAAE,GAAGA,EAAQ,KAAMnB,EAAK,aAAa,OAAQ,CAChE,EAGA,IAAI,YAAa,CACf,OAAOoB,GAAa,KAAK,WAAW,CACtC,EACA,UAAUC,EAAc,CACtB,OAAO,KAAK,WAAW,IAAIA,CAAI,GAAKA,CACtC,EAGA,IAAI,wBAAyB,CAC3B,QAAWC,KAAK,KAAK,UAAU,OAAS,CAAC,EACvC,GAAIA,EAAE,SAAS,QAAU,QACvB,QAAWC,KAASD,EAAE,OAAO,OAAO,EAClC,GAAIC,IAAUC,GACZ,MAAO,GAKf,MAAO,EACT,EAEA,IAAI,kBAAmB,CACrB,IAAMC,EAAQ,KAAK,UAAU,OAAS,CAAC,EACvC,OAAOA,EAAM,SAAW,EAAI,KAAK,UAAUA,EAAM,CAAC,EAAG,IAAI,EAAI,aAC/D,EAkBA,IAAI,sBAA4C,CAC9C,OAAOzB,EAAK,cAAc,UACvB,KAAK,cAAgBA,EAAK,oBAAsB,QAC/C,UACA0B,GAAmB1B,EAAK,kBAAmBA,EAAK,KAAK,CAC3D,EACA,IAAI,cAAe,CACjB,OAAQA,EAAK,cAAc,SAAS,OAAO,MAAM,QAAU,GAAK,CAClE,EAIA,IAAI,iBAAkB,CACpB,OAAO,KAAK,SACR,CACE,MAAO,UACP,IAAK,4EACP,EACA,KAAK,aACH,CACE,MAAO,YACP,IAAK,uEACP,EACA,MACR,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAK,cAAc,aAC5B,EAEA,IAAI,iBAAkB,CACpB,MAAO,CAACA,EAAK,cAAc,SAAW,CAAC,KAAK,QAC9C,EAGA,IAAI,WAAY,CACd,OAAOA,EAAK,cAAc,WAAa,CAAC,CAC1C,EAKA,IAAI,iBAAkB,CACpB,OAAOA,EAAK,cAAc,iBAAmB,CAAC,CAChD,EACA,IAAI,gBAAiB,CACnB,OAAOA,EAAK,cAAc,cAC5B,EACA,IAAI,UAAW,CACb,OAAOA,EAAK,cAAc,QAC5B,EAIA,IAAI,WAAY,CACd,OAAOA,EAAK,cAAc,WAAa,EACzC,EACA,IAAI,aAAc,CAChB,MAAO,IAAIA,EAAK,MAAQ,KAAK,QAAQ,CAAC,CAAC,GACzC,EAIA,IAAI,mBAAoB,CACtB,OAAOA,EAAK,QAAU,GAAKA,EAAK,aAAe,GAAKA,EAAK,aAAe,CAC1E,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,YAAa,CACf,OAAOA,EAAK,SAAS,GAAG,EAAE,CAC5B,EAGA,IAAI,gBAAiB,CACnB,OAAOA,EAAK,MAAQ2B,GAAiB3B,EAAK,KAAK,EAAI,CAAC,CACtD,CACF,EAAE,EACD,MAAMA,IAAS,CAGd,IAAI,SAAU,CACZ,OAAOA,EAAK,cAAc,OAASA,EAAK,aAAeA,EAAK,cAC9D,CACF,EAAE,EACD,MAAMA,IAAS,CAEd,IAAI,eAAsC,CAE1C,EAEA,IAAI,mBAA8C,CAElD,EACA,IAAI,eAAgB,CAClB,IAAM4B,EAAQ5B,EAAK,YACnB,OAAO4B,EAAQC,GAAmB7B,EAAM4B,CAAK,EAAI,MACnD,EACA,IAAI,eAAgB,CAClB,IAAMA,EAAQ5B,EAAK,YACnB,OAAO4B,KAAS,mBAAeA,EAAO,SAAS,EAAe,MAChE,EACA,IAAI,sBAAuB,CACzB,IAAME,EAAS9B,EAAK,YACpB,OAAK8B,KAGE,eAAW9B,CAAI,EACnB,OAAO,OAAO+B,MACZ,mBAAeA,EAAG,eAAe,EAAe,SAC/CD,EAAO,YACT,CACF,EACC,IAAIC,IAAM,CACT,QAASA,EAAE,QACX,QAAM,mBAAeA,EAAG,MAAM,EAC9B,eAAc,mBAAeA,EAAG,SAAS,EAAuB,IAClE,EAAE,EAZK,CAAC,CAaZ,CACF,EAAE,EACD,MAAM/B,IAAS,CACd,IAAI,kBAAmB,CACrB,OAAOA,EAAK,qBAAqB,OAAO,GACtCgC,GAAmB,IAAI,EAAE,WAAW,CACtC,CACF,EAGA,IAAI,oBAAqB,CACvB,OAAOhC,EAAK,qBAAqB,OAAO,GACtCiC,GAAqB,IAAI,EAAE,WAAW,CACxC,CACF,EAEA,IAAI,eAAgB,CAClB,OAAOjC,EAAK,cAAgB,CAAC,CAC/B,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,aAAc,CAChB,OAAOkC,GAAgBlC,EAAK,mBAAoBA,EAAK,aAAa,CACpE,EACA,IAAI,WAAY,CACd,OAAOmC,GAAcnC,EAAK,iBAAkBA,EAAK,WAAW,CAC9D,EACA,IAAI,gBAAiB,CACnB,OAAOA,EAAK,cAAc,KAAKoC,GAAKA,EAAE,MAAQpC,EAAK,SAAS,CAC9D,EACA,IAAI,UAAW,CACb,OAAOA,EAAK,MAAQqC,GAAcrC,EAAK,KAAK,EAAI,MAClD,EAGA,IAAI,aAAc,CAChB,OAAOA,EAAK,MAAQsC,GAAStC,EAAK,MAAOA,EAAK,WAAW,EAAI,MAC/D,EAIA,kBAAkBuC,EAAqC,CACrD,GAAM,CAAE,gBAAAC,CAAgB,KAAI,eAAWxC,CAAI,EACrCyC,EAAWD,EAAgB,IAAID,CAAY,EAC7CC,EAAgB,IAAID,CAAY,EAChC,OACEG,EAAS1C,EAAK,eAAe,qBAAuB,CAAC,EAIrD2C,EAAQ,CACZJ,EACA,GAAIE,EAAW,CAACA,EAAS,KAAM,GAAGA,EAAS,OAAO,EAAI,CAAC,CACzD,EACA,MAAO,CACL,KAAMF,EACN,QAAS,CAAC,GAAGI,EAAO,GAAGA,EAAM,QAAQvC,GAAKsC,EAAMtC,CAAC,GAAK,CAAC,CAAC,CAAC,CAC3D,CACF,EAGA,IAAI,sBAAuB,CACzB,IAAMI,EAAQR,EAAK,MACnB,OACEQ,GAAO,aAAe,QACrBA,GAAO,gBAAkB,QACxBA,EAAM,gBAAkBR,EAAK,mBAEnC,CACF,EAAE,EACD,MAAMA,IAAS,CAEd,IAAI,cAAe,CACjB,IAAM8B,EAAS9B,EAAK,YACpB,OAAO8B,EAAS9B,EAAK,kBAAkB8B,EAAO,YAAY,EAAI,MAChE,EAEA,IAAI,gBAAiB,CACnB,IAAIc,EACJ,GAAI,CACFA,KAAO,sBAAkB5C,CAAI,CAC/B,MAAQ,CACN,MACF,CACA,IAAM6C,EAAUC,GAAYF,EAAM5C,EAAK,WAAW,OAAO,EACzD,OAAO6C,EAAQ,OACX,IAAI,GAAAE,QAAwB,CAC1B,QAAAF,EACA,QAAM,WAAO7C,CAAI,EAAE,cAAc,IACnC,CAAC,EACD,MACN,EAEA,IAAI,cAAe,CACjB,IAAMgD,EAAWhD,EAAK,kBAChBiD,EAAO,KAAK,eAClB,OAAOD,EACHE,GAAeD,EAAOD,EAAS,OAAOG,GAAKF,EAAK,OAAOE,CAAC,CAAC,EAAIH,CAAQ,EACrE,MACN,CACF,EAAE,EACD,MAAMhD,IAAS,CAKd,IAAI,eAAgB,CAClB,GAAM,CAAE,SAAAoD,EAAU,aAAAC,EAAc,aAAAC,CAAa,EAAItD,EAC3CuD,EACJvD,EAAK,sBACJqD,IAAiB,QAChBG,GAAiBJ,EAAU,CAACC,CAAY,CAAC,IAAM,OACnD,OAAOD,GAAYE,GAAgBC,EAC/BE,GAAmBH,EAAcF,CAAQ,EACzC,MACN,CACF,EAAE,EACD,MAAMpD,IAAS,CACd,IAAI,eAAgB,CAClB,OAAOA,EAAK,WAAa0D,GAAe1D,EAAK,UAAU,EAAI,MAC7D,EACA,IAAI,SAAmB,CACrB,OAAO2D,GACL3D,EAAK,WACLA,EAAK,SACLA,EAAK,gBACLA,EAAK,SACP,CACF,EAMA,IAAI,cAAe,CACjB,OAAOA,EAAK,OAAS,KAAK,WAAa4D,GAAc5D,EAAK,KAAK,EAAI,CAAC,CACtE,EAIA,IAAI,gBAAiB,CACnB,GAAIA,EAAK,mBAAqB,YAAc,CAACA,EAAK,MAChD,OAEF,IAAM6D,EAAS7D,EAAK,eACd8D,EAAOD,EACTvB,GAAStC,EAAK,MAAO6D,EAAQA,EAAO,IAAI,EACxC7D,EAAK,YACT,GAAI,CAAC8D,EACH,OAEF,GAAM,CAACC,EAAW,GAAGC,CAAI,EAAIC,GAC3B,CAACH,EAAK,UAAW,GAAGA,EAAK,IAAI,EAC7BD,GAAQ,KACV,EACA,MAAO,CAAE,GAAGC,EAAM,UAAWC,EAAY,KAAAC,CAAK,CAChD,EAGA,IAAI,sBAAuB,CACzB,IAAMA,EAAO,KAAK,gBAAgB,MAAQ,CAAC,EAC3C,MAAO,CACL,QAAS,CAAC,GAAG,IAAI,IAAIA,EAAK,IAAI5B,GAAKA,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,EACpD,YAAa,CACX,GAAG,IAAI,IACL4B,EAAK,OAAO5B,GAAKA,EAAE,MAAM,SAAW,EAAK,EAAE,IAAIA,GAAKA,EAAE,MAAM,CAC9D,CACF,CACF,CACF,EAEA,IAAI,mBAA8C,CAChD,IAAM8B,EAAWlE,EAAK,eAAe,mBAErC,OAAOkE,IAAa,EAAE,QAASA,IAAaA,EAAS,KACjDA,EACA,MACN,EAEA,IAAI,oBAAqB,CACvB,OAAOC,GAAgBnE,EAAK,kBAAkB,CAChD,EAGA,IAAI,eAAgB,CAClB,IAAM8D,EAAO,KAAK,eACZM,EAAQpE,EAAK,mBACbqE,EAAUrE,EAAK,eACrB,OAAO8D,GACLM,GACAC,GACA,KAAK,mBAAmB,SAASA,EAAQ,KAAK,EAC5CC,GACEC,GAAcT,EAAK,KAAM9D,EAAK,cAAc,EAC5CoE,EACAC,CACF,EACA,MACN,EAGA,IAAI,aAAc,CAChB,IAAMP,EAAO,KAAK,eAClB,OAAOA,EACH,CACE,GAAGA,EACH,KACE,KAAK,eAAe,MACpBS,GAAcT,EAAK,KAAM9D,EAAK,cAAc,CAChD,EACA,MACN,EAMA,IAAI,YAAa,CACf,MAAO,CAACA,EAAK,cAAc,SAAW,CAAC,KAAK,WAC9C,EAGA,IAAI,UAAW,CACbwE,GAASxE,EAAK,gBAAgB,EAC9B,IAAMyE,EAAYzE,EAAK,cAAc,cACrC,OAAOA,EAAK,WACV,KAAK,YACLA,EAAK,OACLA,EAAK,eACLyE,EACEC,GAAS1E,EAAK,MAAOA,EAAK,cAAeyE,CAAS,EAClD,CAAC,CACP,EAGA,IAAI,aAAc,CAChBD,GAASxE,EAAK,gBAAgB,EAC9B,IAAMyE,EAAYzE,EAAK,cAAc,cACrC,MAAI,CAACA,EAAK,aAAe,CAAC,KAAK,YAAc,CAACA,EAAK,OAAS,CAACyE,EACpD,CAAC,EAEHE,GACL3E,EAAK,MACLA,EAAK,QACLyE,EACApD,GAAQrB,EAAK,UAAUqB,CAAI,EAC3BrB,EAAK,YACP,CACF,EAcA,IAAI,eAAgB,CAClB,OAAOA,EAAK,uBAAyB,sBACnCA,EAAK,WACHU,GAAqBV,EAAK,WAAYA,EAAK,UAAU,EACrD,MACN,EAYA,IAAI,eAAgB,CAClB,IAAM8B,EAAS9B,EAAK,YACpB,OAAO8B,EAAS,CAACA,EAAO,YAAY,EAAI,CAAC,CAC3C,EAaA,IAAI,QAAS,CACX,OAAO8C,GAAY5E,EAAK,MAAOA,EAAK,SAAS,EAAE,MACjD,EACA,IAAI,QAAS,CACX,OAAO4E,GAAY5E,EAAK,MAAOA,EAAK,SAAS,EAAE,MACjD,EAKA,IAAI,WAAY,CACd,OAAO4E,GAAY5E,EAAK,MAAOA,EAAK,SAAS,CAC/C,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,iBAAkB,CACpB,OAAOA,EAAK,MACR6E,GAAgB7E,EAAK,MAAOA,EAAK,aAAcA,EAAK,iBAAiB,EACrE,MACN,EAEA,IAAI,WAAY,CACd,OAAO,KAAK,iBAAiB,OAAS,CAAC,CACzC,EACA,IAAI,qBAAsB,CACxB,OAAO,KAAK,iBAAiB,QAC/B,EACA,IAAI,mBAAoB,CACtB,OAAO,KAAK,iBAAiB,MAC/B,EAWA,IAAI,qBAAsB,CACxB,IAAM8E,EAAO9E,EAAK,cAClB,OAAO8E,EACH,CAAE,MAAOA,EAAK,MAAO,IAAKA,EAAK,MAAQA,EAAK,IAAK,EACjD,MACN,EAKA,IAAI,sBAAuB,CACzB,IAAMA,EAAO9E,EAAK,cACZ+E,EAAS/E,EAAK,aACdgF,EAAQD,GAAQ,QAAUA,EAAO,cAAgB,OACnDE,EAAe,GACfC,EAAW,GACf,GAAIJ,GAAQ9E,EAAK,WACf,QAAWmF,KAAQnF,EAAK,WAAW,MAC7BgF,GAAS,CAACA,EAAMG,EAAK,EAAE,IAGtBL,EAAK,UAAU,IAAIK,EAAK,EAAE,EAEpBA,EAAK,QAAUA,EAAK,OAAO,KAAO,IAC3CF,EAAe,IAFfC,EAAW,IAMjB,MAAO,CAAE,aAAAD,EAAc,SAAAC,CAAS,CAClC,EAEA,IAAI,mBAAoB,CACtB,IAAM1E,EAAQR,EAAK,WACnB,OAAOA,EAAK,cAAc,SAAWQ,EACjC4E,GACE5E,EACAR,EAAK,qBACLA,EAAK,aACP,EACA,MACN,EAGA,IAAI,mBAAoB,CACtB,IAAMqF,EAASrF,EAAK,cAAc,SAAS,WACrCsF,EACJD,GAAU,KAAK,kBACXA,EAAO,IAAI,CAACE,EAAG,IAAMC,GAAiB,EAAGH,EAAO,MAAM,CAAC,EACvDA,EACAI,EAAU,IAAI,IAAIzF,EAAK,eAAe,EACtCK,EAAQL,EAAK,YAAY,MAC/B,OAAOsF,GAASjF,GAASoF,EAAQ,KAAO,EACpCH,EAAM,IAAI,CAAC/D,EAAO,IAChBkE,EAAQ,IAAIpF,EAAM,CAAC,GAAG,MAAQ,EAAE,EAAIkB,EAAQmE,EAC9C,EACAJ,CACN,EAEA,SAASK,EAAgB,CACvB,GAAM,CAAE,SAAAC,EAAU,cAAeC,CAAU,EAAI7F,EAC/C,OAAO4F,GAAYC,EACfC,GAAkB,CAAE,OAAAH,EAAQ,SAAAC,EAAU,UAAAC,CAAU,CAAC,EACjD,MACN,CACF,EAAE,EACD,MAAM7F,IAAS,CASd,IAAI,YAAa,CACf,IAAMK,EAAQL,EAAK,OAAO,MACpB+F,EAAU/F,EAAK,cAAc,QAEnC,OADkBA,EAAK,WAAa+F,IAChB1F,GAASE,GAAkBF,EAAM,MAAM,EACvDC,GAAWD,EAAOL,EAAK,iBAAiB,EACxC,CAAC,CACP,EAGA,IAAI,aAAc,CAChB,IAAM2F,EAAS3F,EAAK,YACdgG,EAAShG,EAAK,cACpB,OAAO2F,IAAW,KACd3F,EAAK,SAAS2F,CAAM,EACpBK,EACE,CAAE,MAAOA,EAAO,MAAO,IAAKA,EAAO,GAAI,EACvC,MACR,CACF,EAAE,EACD,MAAMhG,IAAS,CAId,IAAI,gBAAiB,CACnB,IAAM8B,EAAS9B,EAAK,YACdiG,EAAOjG,EAAK,YAClB,OAAO8B,GAAUmE,EACb,CACE,QAASnE,EAAO,QAChB,aAAcA,EAAO,aACrB,GAAGmE,CACL,EACA,MACN,CACF,EAAE,EKv3BJ,IAAAC,GAA+B,SCExB,SAASC,EAASC,EAAkD,CACzE,OAAO,OAAOA,GAAU,UAAYA,IAAU,IAChD,CCOA,SAASC,GAAaC,EAA4C,CAChE,OACEC,EAASD,CAAI,GACbA,EAAK,OAAS,oBACd,OAAOA,EAAK,IAAO,UACnB,OAAOA,EAAK,gBAAmB,YAC/B,MAAM,QAAQA,EAAK,aAAa,CAEpC,CAMO,SAASE,GAASC,EAAkB,CACzC,OAAOA,EAAM,QAAQH,GACnBC,EAASD,CAAI,GAAK,MAAM,QAAQA,EAAK,KAAK,EACtC,CAACA,EAAM,GAAGA,EAAK,KAAK,EACpB,CAACA,CAAI,CACX,CACF,CAiBO,SAASI,GAAiB,CAC/B,MAAAD,EACA,gBAAAE,EACA,aAAAC,CACF,EAIG,CACD,IAAMC,EAAaL,GAASC,CAAK,EAC9B,OAAOH,GAAQD,GAAaC,CAAI,CAAC,EACjC,OAAOA,GAAQA,EAAK,cAAc,SAASM,CAAY,CAAC,EAE3D,OADkBC,EAAW,KAAKP,GAAQA,EAAK,KAAOK,CAAe,IAChDE,EAAW,SAAW,EAAIA,EAAW,CAAC,EAAI,OACjE,CFzCO,SAASC,GAAsBC,EAA2BC,EAAc,CAC7E,IAAMC,EAAUF,EAAQ,gBACxB,OAAOE,GAAS,IAAID,CAAI,EAAKC,EAAQ,IAAID,CAAI,GAAG,MAAQA,EAAQA,CAClE,CA0BA,SAASE,GACPH,EACAI,EACAC,EACA,CACAA,EAAO,MAAOC,GAAmB,CAC/B,QAAQ,MAAM,qBAAqBF,CAAI,GAAIE,CAAK,EAChDN,EAAQ,cAAc,GAAGI,CAAI,KAAKE,CAAK,GAAIA,CAAK,CAClD,CAAC,CACH,CAMA,IAAMC,GAAqB,IAEpB,SAASC,GACdC,EACAC,EAAUH,GACK,CACf,IAAMI,EAAM,KAAK,IAAI,EAAG,KAAK,MAAMD,GAAWD,EAAI,IAAMA,EAAI,QAAU,CAAC,CAAC,EACxE,MAAO,CAAE,GAAGA,EAAK,MAAO,KAAK,IAAI,EAAGA,EAAI,MAAQE,CAAG,EAAG,IAAKF,EAAI,IAAME,CAAI,CAC3E,CAqBO,SAASC,GACdC,EACAC,EAGe,CACf,OAAOA,EACHD,EAAa,IAAIE,GACfA,EAAE,OAAS,EACP,CACE,GAAGA,EACH,OAAQD,EAAO,aACf,UAAW,OACX,QAASA,EAAO,QAChB,MAAOA,EAAO,MACd,IAAKA,EAAO,GACd,EACAC,CACN,EACAF,CACN,CAaO,SAASG,GAAiB,CAC/B,QAAAhB,EACA,SAAAiB,EACA,SAAAC,EACA,gBAAAC,EACA,OAAAC,EAAS,CAAC,CACZ,EAMG,CACD,IAAMC,EAAWC,GAAiB,CAChC,MAAOtB,EAAQ,MACf,gBAAAmB,EACA,aAAcD,CAChB,CAAC,EACGK,EACJ,OAAIF,GACFlB,GACEH,EACA,kBAAkBkB,CAAQ,IAAIM,GAASP,CAAQ,CAAC,GAChD,QAAQ,QAAQI,EAAS,eAAeI,GAAUR,CAAQ,EAAGC,CAAQ,CAAC,CACxE,EACAK,EAASF,EAAS,IAElBE,EAASvB,EAAQ,QAAQ,mBAAoB,CAC3C,YAAa,GAAGkB,CAAQ,WAAMM,GAASP,CAAQ,CAAC,GAChD,KAAM,CAAE,SAAAC,EAAU,IAAKO,GAAUR,CAAQ,EAAG,OAAAG,CAAO,CACrD,CAAC,EAAE,GAEEG,CACT,CAcO,SAASG,GAAsB,CACpC,QAAA1B,EACA,SAAAiB,EACA,SAAAC,EACA,gBAAAC,CACF,EAKG,CACD,IAAMQ,EAASL,GAAiB,CAC9B,MAAOtB,EAAQ,MACf,gBAAAmB,EACA,aAAcD,CAChB,CAAC,EACD,OAAIS,GACF3B,EAAQ,eAAe,CACrB,QAASiB,EAAS,QAClB,MAAOA,EAAS,MAChB,IAAKA,EAAS,IACd,aAAcC,CAChB,CAAC,EAEIS,IAAW,MACpB,CAMA,SAASC,GACP5B,EACA6B,EACA,CACA,GAAIA,IAAY,OACd,MAAO,CAAC,EAEV,IAAMC,EAAQ9B,EAAQ,OAAO,KAC3B+B,MAAK,mBAAeA,EAAG,SAAS,IAAMF,CACxC,EACMG,EAAiBF,KAAQ,mBAAeA,EAAO,eAAe,EAAI,CAAC,EACzE,OAAO,MAAM,QAAQE,CAAK,EACtBA,EACG,OAAOC,GAAK,OAAOA,GAAM,QAAQ,EACjC,IAAIA,GAAKlC,GAAsBC,EAASiC,CAAC,CAAC,EAC7C,CAAC,CACP,CAyBO,SAASC,GAAkB,CAChC,QAAAlC,EACA,aAAAa,EACA,QAAAgB,EACA,aAAAM,CACF,EAKG,CACD,IAAMC,EAAuBR,GAAqB5B,EAASmC,CAAY,EAKjEE,EAAUT,GAAqB5B,EAAS6B,CAAO,EAC/CS,EAAUzB,EAAa,OAAOE,GAAKsB,EAAQ,SAAStB,EAAE,MAAM,CAAC,EAC7DwB,EAASD,EAAQ,QAAU,EAAIA,EAAUzB,EACzC2B,EAAW,CACf,KAAM,CACJ,MAAOD,EAAO,IAAIxB,IAAM,CACtB,SAAUA,EAAE,OACZ,IAAKU,GAAUV,CAAC,EAChB,GAAIoB,IAAiB,QACrBC,EAAqB,SAASrB,EAAE,MAAM,EAClC,CAAE,OAAQ,CAACoB,CAAY,CAAE,EACzB,CAAC,CACP,EAAE,EAMF,OAAQN,EAAUU,EAAO,MAAM,CAAC,EAAE,IAAI,IAAM,CAACV,CAAO,CAAC,EAAI,CAAC,EAC1D,kBAAmB,EACrB,CACF,EAGI7B,EAAQ,WACVG,GACEH,EACA,kCACAA,EAAQ,WAAW,oBAAqBwC,CAAQ,CAClD,EAEAxC,EAAQ,QAAQ,oBAAqBwC,CAAQ,CAEjD,CT7QO,IAAMC,GAAkBC,GAC5B,MAAMC,IAAS,CAUd,IAAI,wBAAyB,CAC3B,IAAMC,EAAQD,EAAK,MACbE,EAAWD,EAAQE,GAAcF,CAAK,EAAI,CAAC,EACjD,OAAOA,EACHG,GAAuBH,EAAO,CAC5B,OAAQC,EAAS,OAAS,EAAIG,GAAaH,CAAQ,EAAI,GACzD,CAAC,EACD,CAAC,CACP,CACF,EAAE,EACD,MAAMF,IAAS,CAWd,IAAI,kBAAmB,CACrB,GAAM,CAAE,gBAAAM,CAAgB,KAAI,eAAWN,CAAI,EACrCO,EAAQP,EAAK,eAAe,oBAE5BQ,EAAW,IAAI,IACnB,OAAO,QAAQD,GAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAACE,EAAKC,CAAM,IAAM,CAACA,EAAQD,CAAG,CAAC,CAClE,EACME,EAAUC,GACdA,IAAS,QAAaN,EAAgB,IAAIM,CAAI,EACzCN,EAAgB,IAAIM,CAAI,GAAG,MAAQA,EACpC,OACN,OAAQC,GAAmBF,EAAOH,EAAS,IAAIK,CAAM,CAAC,GAAKF,EAAOE,CAAM,CAC1E,EAIA,IAAI,sBAAuB,CACzB,IAAMC,EAAa,IAAI,IAIvB,QAAWC,OAAK,eAAWf,CAAI,EAAE,OAAQ,CACvC,IAAMgB,KAAe,mBAAeD,EAAG,SAAS,EAC7C,KACH,GAAI,CAACE,GAAmB,IAAID,CAAW,EACrC,SAEF,IAAME,EAAQ,CACZ,QAASH,EAAE,QACX,QAAM,mBAAeA,EAAG,MAAM,EAC9B,YAAAC,CACF,EACA,QAAWJ,OAAQ,mBAAeG,EAAG,eAAe,EAAe,CACjE,IAAMN,EAAMU,MAAsB,eAAWnB,CAAI,EAAGY,CAAI,EACxDE,EAAW,IAAIL,EAAK,CAAC,GAAIK,EAAW,IAAIL,CAAG,GAAK,CAAC,EAAIS,CAAK,CAAC,CAC7D,CACF,CACA,OAAO,IAAI,IACT,CAAC,GAAGJ,CAAU,EAAE,QAAQ,CAAC,CAACL,EAAKW,CAAM,IAAM,CACzC,IAAMC,EAASC,GAAcF,EAAQ,EAAE,EACvC,OAAOC,EAAS,CAAC,CAACZ,EAAKY,CAAM,CAAU,EAAI,CAAC,CAC9C,CAAC,CACH,CACF,CACF,EAAE,EACD,MAAMrB,IAAS,CAMd,IAAI,sBAAuB,CACzB,OAAOuB,GACLC,GAAoBxB,EAAK,uBAAwBA,EAAK,WAAW,EACjEA,EAAK,gBACP,CACF,EAKA,IAAI,0BAA2B,CAC7B,IAAMyB,EAASzB,EAAK,YACpB,OACEyB,IAAW,QACXC,GAAiB,CACf,MAAO,CAAC,MAAG,eAAW1B,CAAI,EAAE,KAAK,EACjC,gBAAiBA,EAAK,gBACtB,aAAcyB,EAAO,YACvB,CAAC,IAAM,MAEX,EAKA,kBAAkBE,EAAgB,CAChC,IAAMC,EAAO5B,EAAK,UAAU,IAAI2B,CAAM,EAChCE,EAAMD,EAAOE,GAAgBF,CAAI,EAAI,OACrCG,EAAcF,EAChBG,GAAwBhC,EAAK,iBAAkB6B,CAAG,EAClD,OACEJ,EAASzB,EAAK,YACdiC,EAAWjC,EAAK,SAChBkC,EAAYlC,EAAK,cACjBmC,EACJV,GAAUQ,GAAYC,EAClBE,GAAkB,CAAE,OAAAT,EAAQ,SAAAM,EAAU,UAAAC,CAAU,CAAC,EACjD,OACAG,EACJZ,GAAUU,EACN,CACE,OAAQV,EAAO,aACf,UAAW,OACX,QAASA,EAAO,QAChB,GAAGU,CACL,EACA,OACN,MAAO,CACL,IACEN,GAAOE,EACH,CAAE,SAAUO,GAAeT,CAAG,EAAG,SAAUE,CAAY,EACvD,OACN,UACEN,GAAUY,EACN,CACE,SAAUC,GAAeD,CAAW,EACpC,SAAUZ,EAAO,YACnB,EACA,OAGN,UACEA,GAAUY,EACN,CAAE,SAAUA,EAAa,SAAUZ,EAAO,YAAa,EACvD,MACR,CACF,CACF,EAAE,EACD,MAAMzB,IAAS,CAId,IAAI,MAA+B,CACjC,IAAIuC,EACJ,GAAI,CACFA,KAAO,sBAAkBvC,CAAI,CAC/B,MAAQ,CACN,MACF,CACA,OAAOwC,GAAaD,CAAI,EAAIA,EAAO,MACrC,CACF,EAAE,EY1KG,IAAME,GAAmBC,GAC7B,MAAMC,IAAS,CAId,IAAI,gBAAiB,CACnB,OAAOC,GAAiB,CACtB,UAAWD,EAAK,UAChB,KAAM,CAAE,WAAYA,EAAK,cAAe,EACxC,aAAc,CAAC,CAACA,EAAK,cAAc,SAAW,CAAC,CAACA,EAAK,YACrD,OAAQA,EAAK,SAAS,OAAS,EAC/B,MAAOA,EAAK,OAAO,OAAO,QAAU,EACpC,KAAM,CAAC,CAACA,EAAK,IACf,CAAC,CACH,EAGA,IAAI,eAAgB,CAClB,IAAME,EAAO,KAAK,eAAiBF,EAAK,YAAc,OACtD,OAAOE,EACH,CAAE,GAAGA,EAAM,KAAMC,GAAcD,EAAK,KAAMF,EAAK,cAAc,CAAE,EAC/D,MACN,EACA,IAAI,gBAAiB,CACnB,IAAME,EAAO,KAAK,cAClB,GAAKA,EAGL,OAAOE,GAAeF,EAAM,CAAE,MAAOF,EAAK,SAAU,CAAC,CACvD,EAGA,IAAI,gBAAiB,CACnB,OAAOK,GAAeC,EAAkBN,EAAK,gBAAgB,EAAG,CAC9D,UAAWA,EAAK,UAChB,KAAM,CAAC,CAACA,EAAK,IACf,CAAC,CACH,EAEA,IAAI,gBAAiB,CACnB,IAAME,EAAO,KAAK,cACZK,EAAKP,EAAK,aAAeA,EAAK,aAC9BQ,EAAOD,IAAO,KAAO,OAAYP,EAAK,UAAU,IAAIO,CAAE,EAC5D,OAAOL,GAAQM,GAAQR,EAAK,MACxBS,GAAWT,EAAK,MAAO,CAACE,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAGM,CAAI,EAC3D,CAAC,CACP,EAGA,IAAI,kBAAmB,CACrB,IAAMD,EAAKP,EAAK,WAAaA,EAAK,YAAc,KAChD,OAAOO,IAAO,KACV,OACAG,GAAWV,EAAK,gBAAgBO,CAAE,EAAGI,IAAM,CACzC,EAAGA,EAAE,EAAIX,EAAK,OAASA,EAAK,WAC5B,EAAGW,EAAE,EAAIX,EAAK,OAASA,EAAK,UAC9B,EAAE,CACR,CACF,EAAE,EACD,MAAMA,IAAS,CAKd,IAAI,eAAgB,CAClB,IAAME,EAAOF,EAAK,aAAeA,EAAK,cACtC,GAAI,CAACE,GAAQ,CAACF,EAAK,UACjB,OAEF,IAAMY,EAIA,CAAC,EACHC,EAAgB,EAChBC,EAAW,EACf,QAAWC,KAAOb,EAAK,KAAM,CAC3B,GAAI,CAACa,EAAI,KAAM,CACbD,IACA,QACF,CACA,IAAME,EAAeC,GAAwBjB,EAAK,iBAAkB,CAClE,OAAQe,EAAI,OACZ,UACEA,EAAI,YAAc,OACd,OACA,GAAGA,EAAI,MAAM,IAAIA,EAAI,SAAS,EACtC,CAAC,EACKG,EAAQF,EACVhB,EAAK,qBAAqB,IAAIgB,CAAY,EAC1C,OACJ,GAAI,CAACA,GAAgB,CAACE,EAAO,CAC3BL,IACA,QACF,CACAD,EAAM,KAAK,CACT,IAAKG,EAAI,KACT,QAASG,EAAM,QACf,OAAQ,CACN,aAAAF,EACA,QAASD,EAAI,KAAK,OAClB,GAAGI,GAAQJ,EAAI,KAAMA,EAAI,EAAE,CAC7B,CACF,CAAC,CACH,CACA,MAAO,CACL,MAAOH,EAAM,MAAM,EAAGQ,EAAc,EACpC,KAAM,CACJ,UAAWP,EACX,SAAAC,EACA,OAAQ,KAAK,IAAI,EAAGF,EAAM,OAASQ,EAAc,CACnD,CACF,CACF,EACA,IAAI,iBAAkB,CACpB,OAAO,KAAK,eAAe,IAC7B,EAKA,oBAAoBC,EAAenB,EAAOF,EAAK,YAAa,CAC1D,IAAMe,EAAMb,EAAO,CAACA,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAEmB,CAAK,EAAI,OAC3D,GAAI,CAACN,GAAK,KACR,OAEF,IAAMO,EACJP,EAAI,YAAc,OACd,OACA,GAAGA,EAAI,MAAM,IAAIA,EAAI,SAAS,GAC9BQ,EACJF,IAAU,EACNrB,EAAK,aAAa,aAClBiB,GAAwBjB,EAAK,iBAAkB,CAC7C,OAAQe,EAAI,OACZ,UAAAO,CACF,CAAC,EACP,MAAO,CACL,MAAOP,EAAI,MACX,SAAAQ,EACA,SAAU,CACR,OAAQR,EAAI,OACZ,UAAAO,EACA,QAASP,EAAI,KAAK,OAClB,GAAGI,GAAQJ,EAAI,KAAMA,EAAI,EAAE,CAC7B,CACF,CACF,EAGA,IAAI,cAAe,CACjB,IAAMb,EAAOF,EAAK,aAAeA,EAAK,cACtC,GAAI,CAACE,GAAQ,CAACF,EAAK,UACjB,OAEF,IAAMwB,EAAQ,IAAI,IAAIxB,EAAK,kBAAoB,CAAC,CAAC,EACjD,OAAIA,EAAK,cACPwB,EAAM,IAAItB,EAAK,UAAU,KAAMF,EAAK,YAAY,EAE3CwB,EAAM,KACTC,GAAc,CAACvB,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAGsB,CAAK,EACnD,MACN,CACF,EAAE,ECpKG,IAAME,GAAgBC,GAC1B,MAAMC,IAAS,CAId,IAAI,gBAAiB,CACnB,OACEA,EAAK,cAAc,gBAAkB,IACrCC,EAAkBD,EAAK,gBAAgB,EAAE,UAE7C,CACF,EAAE,EACD,MAAMA,IAAS,CAKd,IAAI,aAAc,CAChB,GAAM,CAAE,KAAAE,EAAM,YAAaC,CAAO,EAAIH,EACtC,OACEE,IAAS,QACTA,EAAK,aACLC,IAAW,QACXH,EAAK,gBACLA,EAAK,SAAS,SAAW,GACzB,CAACE,EAAK,cAAc,cAAc,KAChCE,GAAKA,EAAE,UAAYD,EAAO,SAAWC,EAAE,QACzC,CAEJ,CACF,EAAE,EACD,MAAMJ,IAAS,CACd,IAAI,WAAY,CACd,GAAM,CAAE,KAAAE,EAAM,YAAAG,CAAY,EAAIL,EAC9B,OAAOA,EAAK,aAAeE,GAAQG,EAC/BC,GAAUJ,EAAMG,CAAW,EAC3B,MACN,EACA,IAAI,gBAAiB,CACnB,IAAME,EAAUP,EAAK,cAAc,QACnC,OAAOO,EAAUC,GAAeD,CAAO,EAAI,MAC7C,EACA,IAAI,kBAAmB,CACrB,IAAMA,EAAUP,EAAK,cAAc,QACnC,OAAOO,GAAWP,EAAK,WACnBS,GAAeT,EAAK,WAAYO,EAAQ,MAAM,EAC9C,MACN,EAEA,IAAI,mBAAoB,CACtB,IAAMG,EAASV,EAAK,cAAc,SAAS,OACrCW,EAASX,EAAK,cAAc,SAAS,OAC3C,OAAOU,GAAUC,EACbC,GAAeF,EAAO,MAAOC,EAAQD,EAAO,UAAU,EACtD,CAAC,CACP,EAGA,IAAI,uBAAwB,CAC1B,IAAMC,EAASX,EAAK,aACpB,OAAOW,GAAQ,SAAW,CAACA,EAAO,eAAiBX,EAAK,WACpDa,GAAeb,EAAK,WAAYW,EAAO,QAAQ,MAAM,EACrD,MACN,CACF,EAAE,EACD,MAAMX,IAAS,CAEd,IAAI,cAAe,CACjB,IAAMc,EAAYd,EAAK,iBACvB,OAAOA,EAAK,WAAa,CAACA,EAAK,MAAQc,GAAad,EAAK,cACrDe,GAAaD,EAAWd,EAAK,aAAa,EAC1C,CAAC,CACP,EAGA,IAAI,uBAAwB,CAC1B,MACE,CAAC,CAACA,EAAK,MAAM,aACb,CAAC,CAACA,EAAK,cACPA,EAAK,YACL,CAACA,EAAK,aACN,CAACA,EAAK,WAEV,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,sBAAuB,CACzB,GAAM,CAAE,MAAAgB,CAAM,EAAIhB,EAClB,OAAOA,EAAK,oBAAsBA,EAAK,uBAAyBgB,EAC5DC,GAAqBD,EAAO,CAC1B,YAAahB,EAAK,qBAClB,cAAeA,EAAK,cACpB,MAAOA,EAAK,UAAU,KACxB,CAAC,EACD,CAAC,CACP,EAGA,IAAI,qBAAsB,CACxB,GAAM,CAAE,KAAAE,EAAM,YAAAG,CAAY,EAAIL,EAC9B,OAAOE,GAAM,aAAeG,EACxBC,GAAUJ,EAAMG,CAAW,EAC3B,MACN,CACF,EAAE,EACD,MAAML,IAAS,CACd,IAAI,qBAAsB,CACxB,OACEA,EAAK,qBAAqB,OAAS,GACnCA,EAAK,sBAAwB,MAEjC,EAIA,IAAI,yBAA0B,CAC5B,IAAMkB,EAAQlB,EAAK,oBACnB,GAAI,CAACkB,GAASlB,EAAK,qBAAqB,SAAW,EACjD,MAAO,GAET,GAAM,CAAE,KAAAmB,EAAM,MAAAC,CAAM,EAAIC,GACtBrB,EAAK,qBACLkB,EACAlB,EAAK,SACP,EACA,OAAOmB,EAAO,GAAKC,EAAQ,CAC7B,EACA,IAAI,qBAAsB,CACxB,OAAOpB,EAAK,qBAAqB,KAAKI,GAAKA,EAAE,KAAK,CACpD,CACF,EAAE,EACD,MAAMJ,IAAS,CAGd,IAAI,mBAAoB,CACtB,GAAI,CAACA,EAAK,oBACR,OAEF,IAAMsB,EAAYC,IAAiC,CACjD,EAAGA,EAAE,EAAIvB,EAAK,OAASA,EAAK,WAC5B,EAAGuB,EAAE,EAAIvB,EAAK,OAASA,EAAK,UAC9B,GACMwB,EAASxB,EAAK,cAAgB,KAAOA,EAAK,cAAgB,KAChE,GAAIwB,EAAQ,CACV,IAAMC,EAAOzB,EAAK,YAAY,KAAK0B,GAAKC,GAAWD,EAAE,OAAQF,CAAM,CAAC,EACpE,MAAO,CACL,MAAOA,EAAO,MACd,IAAKA,EAAO,IACZ,OAAQC,EAAOH,EAASG,EAAK,OAAO,EAAI,MAC1C,CACF,CACA,IAAMG,EAAS5B,EAAK,aAAeA,EAAK,aAClC6B,EAAOD,IAAW,KAAO,OAAY5B,EAAK,SAAS4B,CAAM,EAC/D,OAAOC,GAAQD,IAAW,KACtB,CACE,GAAGC,EACH,OAAQC,GAAW9B,EAAK,gBAAgB4B,CAAM,EAAGN,CAAQ,CAC3D,EACA,MACN,EACA,qBAAqBS,EAAYC,EAAY,CAC3C,IAAMd,EAAQlB,EAAK,oBACnB,OAAOA,EAAK,qBAAuBkB,EAC/Be,GAAajC,EAAK,qBAAsBkB,EAAOa,EAAIC,CAAE,EACrD,MACN,EACA,IAAI,UAAW,CACb,OAAOE,GAASlC,EAAK,SAAWmC,GAAaC,EAAW,CAC1D,EAEA,IAAI,sBAAuB,CACzB,OAAOpC,EAAK,oBAAsBqC,GAA0B,CAC9D,CACF,EAAE,Ef9GG,SAASC,GACdC,EACAC,EACAC,EACsB,CACtB,GAAI,GAACF,GAAS,CAACC,GAGf,OAAOE,GAAWH,EAAM,MAAOA,EAAM,KAAK,EACtCE,EACA,CAAE,UAAW,EAAG,OAAQ,EAAG,GAAGA,EAAM,QAAS,EAAK,CACxD,CAEO,IAAME,GAAeC,GACzB,MAAMC,IAAS,CAKd,IAAI,aAAsB,CACxB,OAAO,KAAK,IAAIC,GAAmBD,EAAK,YAAcE,EAAiB,CACzE,EAIA,IAAI,cAAqC,CACvC,IAAMC,EAAOH,EAAK,YAClB,GAAI,CAACG,EACH,OAEF,IAAMC,EAAOJ,EAAK,KAAO,KAAK,aAAe,KAAK,YAC5CK,GACHL,EAAK,eAAe,SAAS,QAAU,GAAKM,GAC/C,OAAOC,GACLJ,EAAK,KAAK,OAAS,EACnBC,EAAO,KAAK,cAAgBI,EAAcH,CAC5C,CACF,EAEA,IAAI,kBAAmB,CACrB,IAAMX,EAAQ,KAAK,aACnB,OAAOA,EACHe,GAAiBT,EAAK,eAAe,UAAY,CAAC,EAAGN,EAAM,KAAK,EAChE,MACN,EAGA,IAAI,gBAAiB,CACnB,OAAOD,GACL,KAAK,aACL,CAAC,CAACO,EAAK,cAAc,KACrBA,EAAK,eACP,CACF,EAGA,IAAI,gBAAiB,CACnB,IAAMU,EAAQ,KAAK,iBACbC,EAASC,GACbZ,EAAK,YACLA,EAAK,aACL,KAAK,YACP,EACA,OAAOA,EAAK,aAAeU,EACvBC,EAAO,IAAI,CAACE,EAAGC,KAAO,CAAE,GAAGD,EAAG,EAAGH,EAAM,KAAKI,CAAC,CAAE,EAAE,EACjDH,CACN,EAGA,IAAI,YAAa,CACf,OAAO,KAAK,IACVH,EACA,GAAG,KAAK,eAAe,IAAIO,GAAKC,GAAYD,EAAE,MAAO,CAAC,EAAE,GAAK,CAAC,CAChE,CACF,EAQA,IAAI,cAAe,CACjB,IAAME,EAASjB,EAAK,aACdG,EAAOH,EAAK,YACZkB,EACJf,GAAQc,GAAQ,OACZE,GAAehB,EAAM,KAAK,YAAY,EACtC,OACN,OAAOc,EACHG,GAAcH,EAAQ,CACpB,OAAQjB,EAAK,SAAS,SAAW,EAAIA,EAAK,YAAc,OACxD,OAAQkB,GAAc,CACpB,GAAGA,EACH,KAAMA,EAAW,MAAQ,KAAK,kBAAkB,WAAa,EAC/D,CACF,CAAC,EACD,MACN,EAGA,IAAI,oBAAqB,CACvB,IAAMf,EAAOH,EAAK,YACZqB,EAAOrB,EAAK,eAClB,GAAI,CAACG,GAAQkB,IAAS,MAAQ,KAAK,cAAc,WAAa,GAC5D,OAEF,IAAMC,EAAcnB,EAAK,UAAU,OAASkB,EACtCE,EAAMD,EACRnB,EAAK,UACLA,EAAK,KAAK,KAAKY,GAAKA,EAAE,OAASM,CAAI,EACvC,OAAOE,EACH,CACE,MAAOA,EAAI,MACX,QAASC,GACPD,EACAD,EAAc,OAAYnB,EAAK,UAC/BA,EAAK,KACLoB,EAAI,IACN,CACF,EACA,MACN,EAGA,UAAUE,EAAiBC,EAAiB,CAC1C,IAAMvB,EAAOH,EAAK,YACZN,EAAQ,KAAK,aACbgB,EAAQ,KAAK,iBACnB,GAAI,CAACP,GAAQ,CAACT,GAAS,CAACgB,EACtB,OAEF,IAAM,EAAIA,EAAM,OACbgB,EAAU1B,EAAK,YAAcA,EAAK,OACnCG,EAAK,KAAK,OAAS,CACrB,EACMoB,EAAM,CAACpB,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAE,CAAC,EACtCwB,EAAIjB,EAAM,KAAK,CAAC,EAAIV,EAAK,OAASA,EAAK,WACvC4B,GAAMH,EAAUzB,EAAK,YAAcA,EAAK,OAASG,EAAK,OAC5D,OAAOoB,GACL,KAAK,IAAIG,EAAUC,CAAC,GAAKjC,EAAM,MAAQ,EAAI,GAC3CkC,GAAM,GACNA,GAAML,EAAI,GACR,EACA,MACN,EAIA,IAAI,eAAgB,CAClB,IAAMM,EAAOC,GAAgB9B,EAAK,YAAY,EAC9C,OACEQ,EACA,KAAK,IAAI,EAAGqB,EAAO,CAAC,EAAIE,GACxB/B,EAAK,oBAET,EAOA,IAAI,YAA0C,CAC5C,IAAMgC,EAAS,KAAK,aACd,CAAE,MAAAC,EAAO,OAAAC,CAAO,EAAIlC,EAAK,WAC/B,GACE,CAACgC,GACDA,EAAO,GAAK,GACZC,IAAU,GACVjC,EAAK,aACLA,EAAK,aAEL,OAEF,GAAIA,EAAK,YACP,MAAO,MAET,IAAMmC,EAAO,KAAK,cAEZ/B,EAAOJ,EAAK,KAAO,KAAK,aAAe,KAAK,YAC5CoC,EAAUC,IACbrC,EAAK,UAAY,KAAK,WAAaqC,GAAYL,EAAO,EACnDM,EAAQC,GACZvC,EAAK,UACDgC,EAAO,EAAIO,EAAS/B,GAAeJ,EACjC,IACA,GACDA,EAAOmC,EAAS/B,GAAewB,EAAO,EACvCQ,EAAS,KAAK,IAAIJ,EAAOH,EAAQ,EAAIQ,EAAe,EAAGH,EAAKH,CAAI,CAAC,EAKvE,OAJc,KAAK,IACjBC,EAAO5B,CAAW,EAClB8B,EAAKH,EAAOD,EAASO,EAAe,CACtC,GACgBD,EAAS,MAAQ,OACnC,EACA,IAAI,WAAY,CACd,OACE,KAAK,eACJ,KAAK,aAAe,MACjBxC,EAAK,WAAW,OAASyC,GACzB,EAER,EACA,IAAI,aAAc,CAChB,OAAO,KAAK,aAAe,QACvB,KAAK,IAAIjC,EAAaR,EAAK,WAAW,MAAQ,EAAIyC,EAAe,EACjEjC,CACN,EAKA,IAAI,aAAc,CAChB,IAAMwB,EAAS,KAAK,aACdf,EAASjB,EAAK,aACd0C,EAASzB,GAAQ,SAAS,OAAO,OAAO,CAAC,GAAG,MAClD,OAAOe,GAAUA,EAAO,EAAI,GAAKU,GAAU,CAACzB,EAAO,cAC/C,KAAK,IACH0B,GAAkBD,GACjB,KAAK,YAAc,KAAK,UAAYlC,GAAewB,EAAO,CAC7D,EACA,CACN,EAGA,IAAI,WAA+C,CACjD,GAAM,CAAE,MAAAY,EAAO,OAAAC,EAAQ,QAAAC,CAAQ,EAAI9C,EAAK,MACxC,OAAO4C,IAAU,GACb,OACAC,EAAO,SAAW,GAAKC,IAAY,OACjCF,EACA,CACE,MAAAA,EACA,OAAQ,CAAC,GAAGC,CAAM,EAClB,GAAIC,IAAY,OAAY,CAAC,EAAI,CAAE,QAAAA,CAAQ,CAC7C,CACR,EAEA,IAAI,gBAAiB,CACnB,IAAMC,EAAS/C,EAAK,YACd,CAAE,MAAA4C,EAAO,OAAAC,CAAO,EAAI7C,EAAK,MAC/B,OAAO+C,EACHC,GACED,EAAO,IAAIE,GAAKA,EAAE,MAAM,CAAC,EAAG,IAAI,EAChCjD,EAAK,aAAe4C,IAAU,GAAK,OAASA,EAC5CC,CACF,EACA,MACN,EAGA,YAAYzC,EAAqC,CAC/C,IAAMM,EAAQ,KAAK,eACbsB,EAAS,KAAK,aACpB,OAAOtB,GAASsB,GAAUA,EAAO,EAAI,EACjCkB,GAAU,CACR,MAAOxC,EAAM,MACb,OAAAsB,EACA,UAAWhC,EAAK,UAChB,MAAOA,EAAK,UACZ,KAAAI,EACA,QAASJ,EAAK,YACV,EACCU,EAAM,SAAWV,EAAK,MAAM,OACnC,CAAC,EACD,MACN,EACA,IAAI,WAAY,CACd,OAAO,KAAK,YAAYA,EAAK,KAAO,KAAK,aAAe,KAAK,WAAW,CAC1E,EAMA,IAAI,cAAuB,CACzB,IAAMgC,EAAS,KAAK,aACdmB,EAAcnD,EAAK,UAAYQ,EAAc,KAAK,YAClD4C,EAAU,KAAK,YACrB,GAAI,CAACpB,EACH,OAAOoB,EAET,IAAMC,EAAO,KAAK,UAClB,GAAIA,EACF,OAAO,KAAK,IAAIpD,GAAmBoD,EAAK,KAAK,EAG/C,IAAMC,EAAQ,KAAK,IACjBrD,GACAD,EAAK,WAAW,OACd,EAAIyC,GACJzC,EAAK,oBACT,EACA,OAAIA,EAAK,UACA,KAAK,IACVoD,EACA,KAAK,IAAIE,EAAOtB,EAAO,EAAI,KAAK,UAAYxB,CAAW,CACzD,EAEKwB,EAAO,EAAI,GAAKmB,EAAc,EACjC,KAAK,IACHC,EACA,KAAK,IACHE,EACAtB,EAAO,EAAI,KAAK,IAAImB,EAAcnB,EAAO,EAAG,KAAK,WAAW,EAC1D,KAAK,UACLxB,CACJ,CACF,EACA4C,CACN,EAGA,IAAI,SAAU,CACZ,IAAMC,EAAO,KAAK,UAClB,OAAOA,EACH,CAAE,MAAOA,EAAK,MAAO,OAAQA,EAAK,MAAO,EACzC,CAAE,MAAOrD,EAAK,UAAW,OAAQ,KAAK,YAAa,CACzD,EAGA,IAAI,iBAAkB,CACpB,IAAMgC,EAAS,KAAK,aACdqB,EAAO,KAAK,UAClB,OAAQrB,EAEJqB,EACEE,GAAavB,EAAQqB,EAAK,MAAOA,EAAK,OAAQrD,EAAK,UAAW,CAC5D,QAASwD,GACT,OAAQA,GACR,SAAUA,GACV,UAAWA,EACb,CAAC,EACDD,GACEvB,EACAhC,EAAK,UACL,KAAK,aACLA,EAAK,UACL,CACE,SAAU,KAAK,YACf,QAAS,KAAK,WACd,OAAQ,KAAK,UACb,SAAU,KAAK,WACjB,CACF,EAnBF,MAoBN,CACF,EAAE,EACD,MAAMA,IAAS,CAGd,iBAAkB,CAChB,OAAOyD,GAAOC,GAAe1D,CAAI,EAAG2D,EAAoB,CAC1D,EAIA,gBAAgBC,EAAa,CAC3B,GAAM,CAAE,YAAAC,EAAa,YAAAC,EAAa,aAAAC,CAAa,EAAI/D,EAC7CgE,EAAQ,IAAI,IACdD,IAAiB,MACnBC,EAAM,IAAID,EAAcE,EAAe,EAErCJ,IAAgB,MAAQA,IAAgBE,GAC1CC,EAAM,IAAIH,EAAaK,EAAc,EAEvCN,EAAE,kBAAkBI,CAAK,EACzBJ,EAAE,iBAAiBE,EAAaI,EAAc,CAChD,EAEA,MAAMN,EAAa,CAQjB,IAAMO,EAAMC,GAAO,EACnBR,EAAE,gBAAgB,CAChB,OAAQ5D,EAAK,OAASmE,EACtB,OAAQnE,EAAK,OAASmE,EACtB,WAAYnE,EAAK,WAAamE,EAC9B,WAAYnE,EAAK,WAAamE,EAK9B,IAAAA,CACF,CAAC,EAGDP,EAAE,OACA5D,EAAK,oBACD,CAAC,EAAG,EAAG,EAAG,CAAC,EACXA,EAAK,SACHqE,GACAC,EACR,CACF,CACF,EAAE,EACD,MAAMtE,IAAS,CAKd,aAAauE,EAAiCC,EAAoB,CAChE,GAAM,CAAE,MAAAC,EAAO,SAAAC,EAAU,aAAAC,EAAc,gBAAAC,CAAgB,EAAI5E,EAC3D,GAAI,CAACyE,GAAS,CAACC,GAAY,CAACC,GAAgB,CAACC,EAC3C,OAEFC,GAAS7E,EAAK,cAAeA,EAAK,gBAAgB,EAClD,IAAM8E,KAAiB,cAAU,IAAM9E,EAAK,gBAAgB,CAAC,EA2B7D,MAAO,CAAE,MA1BK+E,GAAc,CAG1B,GAAGC,GAAqBL,EAAcC,EAAiB,CACrD,UAAW,CAAC,CAAC5E,EAAK,WACpB,CAAC,EACD,MAAAyE,EACA,SAAAC,EACA,YAAa1E,EAAK,qBAClB,gBAAiBA,EAAK,gBACtB,mBAAoBA,EAAK,mBACzB,UAAAwE,EACA,UAAWxE,EAAK,UAChB,UAAAuE,EAIA,QAAM,cAAU,IAAMvE,EAAK,SAAS,EACpC,aAAcA,EAAK,aACnB,eAAA8E,EAGA,cAAe9E,EAAK,cAEpB,QAASA,EAAK,gBAChB,CAAC,EACe,eAAA8E,CAAe,CACjC,EACA,IAAI,eAAgB,CAClB,OAAOG,GAAajF,CAAI,CAC1B,EAEA,UAAUkF,EAAkB,CAC1B,IAAMC,EAAKnF,EAAK,YACVoF,EAAOD,EAAKnF,EAAK,UAAU,IAAImF,CAAE,EAAI,OAC3C,OAAOC,EACFC,GAAaH,EAAME,EAAK,GAAIA,EAAK,MAAM,GAAK,mBAC7C,MACN,EAIA,YAAa,CACX,IAAME,EAAStF,EAAK,YACduF,EAAUvF,EAAK,cACfwF,EAAQD,GAAS,oBAEjBE,EAASH,GAAU,GAAGA,EAAO,OAAO,IAAIA,EAAO,KAAK,IAAIA,EAAO,GAAG,GAClEI,EAAMC,GAAM3F,EAAK,iBAAiB,EAClC4F,EACJL,GAAS,OAAS,wBACdI,GAAMJ,EAAQ,aAA6B,EAC3C,OACAM,EAASH,EACX,CAAE,IAAAA,EAAK,OAAQD,CAAO,EACtBG,GAAMN,GAAUG,EACd,CACE,IAAK,CACH,GAAAG,EACA,MAAOD,GAAMJ,EAAS,sBAAsC,EAC5D,OAAQE,EAER,WAAYzF,EAAK,eAAe,IAC9B8F,GAAQN,IAAQM,CAAI,GAAKA,CAC3B,EACA,gBACGP,EAAS,iBACVC,IAAQF,EAAO,YAAY,GAC3BA,EAAO,aACT,QAASC,EAAS,QAClB,OAAQvF,EAAK,eACT,cACCuF,EAAS,cAChB,CACF,EACA,OACN,GAAI,CAACM,EACH,OAEF,IAAME,EAAY/F,EAAK,UAAYA,EAAK,UAAY,OAC9CgG,EAAWD,KACb,eAAW/F,CAAI,EAAE,OAAO,KAAKiG,GAAKA,EAAE,UAAYF,EAAU,OAAO,EACjE,OACEG,EAAcF,KAChB,4BACE,mBAAeA,EAAU,SAAS,EAClC,eACF,EACA,OACEG,EACJD,GAAa,OAAS,mBAClB,CACE,KAAMP,GAAMO,EAAY,aAA6B,EACrD,MAAOP,GACJO,EAAY,OACT,QACN,EACA,OAAQ,MACV,EACA,OACN,OAAO,KAAK,MACV,KAAK,UAAU,CACb,GAAGL,EACH,MAAOM,GAAO,MAAQA,EAAM,MAAQA,EAAQ,OAC5C,cAAenG,EAAK,eAAiB,OACrC,OAAQA,EAAK,iBACb,GAAGoG,GAAmB,CACpB,QAASpG,EAAK,cACd,aAAcA,EAAK,aACnB,aAAcA,EAAK,aACnB,kBAAmBA,EAAK,kBACxB,YAAaA,EAAK,kBAClB,UAAWA,EAAK,UAChB,gBAAiBA,EAAK,gBACtB,mBAAoBA,EAAK,mBACzB,YAAaA,EAAK,WACpB,CAAC,EACD,MAAOA,EAAK,WAAW,OACnBA,EAAK,WAAW,IAAIa,GAAMA,EAAE,MAAQA,EAAIA,EAAE,IAAK,EAC/C,OACJ,MAAOb,EAAK,WAAW,OAAS,EAAIA,EAAK,UAAY,OACrD,UAAWA,EAAK,gBAAkB,OAClC,eAAgBA,EAAK,eAAiBA,EAAK,eAAiB,OAC5D,MAAOA,EAAK,UACZ,OAAQA,EAAK,WACf,CAAC,CACH,CACF,EAGA,IAAI,mBAAoB,CACtB,OAAQA,EAAK,aAETA,EAAK,cACH,8EACAA,EAAK,YAAcA,EAAK,YACtB,OACA,GAAGqG,EAAkBrG,EAAK,gBAAgB,EAAE,KAAK,6DALrD,sBAMN,EAGA,IAAI,uBAAwB,CAC1B,OAAQA,EAAK,WAETA,EAAK,SAAS,OACZ,oEACA,KAAK,WAAW,EACd,OACA,sEALJ,2BAA2BqG,EAAkBrG,EAAK,gBAAgB,EAAE,KAAK,SAM/E,EAGA,QAAS,CACP,GAAM,CAAE,MAAAyE,EAAO,aAAAE,CAAa,EAAI3E,EAChC,OAAOyE,GAASE,GAAgB,CAAC,KAAK,kBAClC2B,GAAU7B,EAAOE,EAAc,CAC7B,MAAO3E,EAAK,UACZ,OAAQA,EAAK,YACb,MAAOA,EAAK,WACZ,MAAOA,EAAK,UACZ,YAAaA,EAAK,qBAClB,UAAWA,EAAK,UAChB,kBAAmBA,EAAK,kBACxB,aAAcA,EAAK,aACnB,gBAAiBA,EAAK,gBACtB,mBAAoBA,EAAK,mBACzB,OAAQA,EAAK,YACb,YAAaA,EAAK,YAClB,aAAcA,EAAK,SAAS,OAAS,EACrC,MAAOA,EAAK,UAAYA,EAAK,cAAgB,OAC7C,SAAUA,EAAK,YACf,aAAcA,EAAK,aACnB,SAAUA,EAAK,aACf,YAAaA,EAAK,gBAClB,UAAWA,EAAK,eAAiB,CAC/B,KAAMA,EAAK,cACX,SAAUA,EAAK,aACf,YAAaA,EAAK,eACpB,EAGA,KAAM,KAAK,sBAAwB,OAAY,KAAK,WAAW,CACjE,CAAC,EACD,MACN,EACA,IAAI,cAAe,CACjB,IAAMuG,EAAUvG,EAAK,cAAc,QACnC,OAAOuG,EACHC,GAAaD,EAAS,CACpB,OAAQvG,EAAK,OACb,WAAYA,EAAK,WACjB,OAAQA,EAAK,OACb,WAAYA,EAAK,WACjB,aAAcA,EAAK,aAAeA,EAAK,UAAYQ,CACrD,CAAC,EACD,MACN,CACF,EAAE,EACD,MAAMR,IAAS,CAGd,IAAI,mBAAoB,CACtB,IAAMyG,EAAYzG,EAAK,iBACvB,OAAOyG,GAAa,CAACzG,EAAK,YAAc0G,GAAWD,CAAS,EAAI,MAClE,EAEA,IAAI,qBAAsB,CACxB,IAAME,EAAU3G,EAAK,eACf4G,EAAQ5G,EAAK,aACnB,OAAO2G,GAAWC,EAAQA,EAAM,EAAED,EAAQ,OAAO,IAAI,EAAI,EAAI,CAC/D,EAGA,IAAI,mBAAoB,CACtB,IAAM3C,EAAQhE,EAAK,sBACb4G,EAAQ5G,EAAK,aACb,CAAE,KAAA6G,EAAM,YAAAC,CAAY,EAAI9G,EACxB4B,EACJoC,GAAS4C,GAASC,GAAM,aAAeC,EACnCC,GAAUF,EAAMC,CAAW,EAC3B,OACN,OAAO9C,GAAS4C,GAAShF,EACrBoF,GACEhD,EACAJ,GAAKA,EAAIhC,EAAG,MAAQA,EAAG,WACvBgF,EAAM,EACN5G,EAAK,SACP,EACA,CAAC,CACP,CACF,EAAE,EACD,MAAMA,IAAS,CAId,IAAI,aAAc,CAChB,IAAMiB,EAASjB,EAAK,aACdiH,EAAQhG,GAAQ,SAAS,OAAO,OAAS,CAAC,EAC1C0F,EAAU3G,EAAK,eACf4G,EAAQ5G,EAAK,aACbkH,EACJP,GAAWC,GAASO,GAAkBP,EAAM,MAAM,EAC9CD,EAAQ,WAAW,OAAOS,GACxBC,GAAiBD,EAAG,CAAE,EAAGR,EAAM,EAAG,MAAO5G,EAAK,SAAU,CAAC,CAC3D,EACA,CAAC,EACP,MAAO,CACL,UAAWiB,GAAQ,UAAY,QAAa,CAACA,EAAO,cACpD,OACEjB,EAAK,kBAAkB,OAAS,EAAIA,EAAK,YAAc,OACzD,aAAciH,EAAM,KAAKlG,GAAK,CAACA,EAAE,UAAU,EAC3C,aAAckG,EAAM,KAAKlG,GAAKA,EAAE,UAAU,EAC1C,WAAY,IAAI,IAAImG,EAAM,IAAIE,GAAKA,EAAE,IAAI,CAAC,CAC5C,CACF,EACA,cAAcE,EAAYC,EAAY,CACpC,IAAMhB,EAAUvG,EAAK,cAAc,QAC7B4G,EAAQ5G,EAAK,aACnB,OACGuG,GAAWK,EAAQY,GAAcjB,EAASK,EAAOU,EAAIC,CAAE,EAAI,OAC5DE,GAAYzH,EAAK,kBAAmBA,EAAK,oBAAqBsH,EAAIC,CAAE,GACpE,IAEJ,CACF,EAAE,EVxtBG,IAAMG,GAAqBC,GAC/B,QAAQC,IAAS,CAChB,SAASC,EAAgB,CACvBD,EAAK,MAAQC,EACbD,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,eAAgB,CACdA,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,iBAAiBE,EAAiB,CAChCF,EAAK,cAAgBE,CACvB,EACA,WAAWC,EAAY,CACrBH,EAAK,YAAcG,CACrB,EACA,YAAYA,EAAY,CACtBH,EAAK,aAAeG,CACtB,EACA,mBACEA,EACAC,EACAC,EACA,CACAL,EAAK,eAAiBG,EACtBH,EAAK,wBAA0BI,EAC/BJ,EAAK,cAAgB,CAAE,GAAGK,EAAO,cAAeL,EAAK,aAAc,EACnEA,EAAK,iBACP,EACA,aAAc,CACZA,EAAK,gBAAkBA,EAAK,aAC9B,EACA,iBAAiBM,EAAiB,CAChCN,EAAK,cAAgBM,CACvB,EACA,gBAAgBC,EAAiB,CAC/BP,EAAK,aAAeO,CACtB,EACA,cAAcC,EAAuB,CACnCR,EAAK,WAAaQ,CACpB,EAKA,iBAAiBC,EAAc,CAC7BT,EAAK,cAAgBS,EACrB,IAAMC,EAAQV,EAAK,MACnB,GAAIU,GAAO,aAAe,QAAS,CACjC,IAAMC,EAAaC,GAAgBF,EAAOD,CAAI,EAC9CI,GAAa,QAAQH,EAAOC,CAAU,EACtCX,EAAK,MAAQW,CACf,CACF,EACA,aAAaG,EAAe,CAC1Bd,EAAK,UAAYc,CACnB,EACA,YAAYC,EAAe,CACzBf,EAAK,SAAWe,CAClB,EACA,eAAeC,EAAqB,CAClChB,EAAK,YAAcgB,CACrB,EACA,gBAAgBC,EAAsB,CACpCjB,EAAK,aAAeiB,CACtB,EACA,aAAaC,EAAkB,CAC7BlB,EAAK,UAAYkB,CACnB,EACA,eAAeH,EAAe,CAC5Bf,EAAK,YAAce,CACrB,EACA,qBAAqBA,EAAe,CAClCf,EAAK,kBAAoBe,CAC3B,EACA,aAAaA,EAAe,CAC1Bf,EAAK,UAAYe,CACnB,EACA,sBAAsBA,EAAe,CACnCf,EAAK,mBAAqBe,CAC5B,EACA,eAAeI,EAAY,CACzBnB,EAAK,YAAcmB,CACrB,EACA,eAAeC,EAAiB,CAC9BpB,EAAK,YAAcoB,CACrB,EACA,iBAAiBA,EAAiB,CAChCpB,EAAK,cAAgBoB,CACvB,EACA,aAAaC,EAAa,CACxBrB,EAAK,UAAYqB,CACnB,EACA,cAAcC,EAAqB,CACjCtB,EAAK,WAAasB,CACpB,EAGA,UAAUC,EAAiB,CACzB,IAAMC,EAAM,IAAI,IAAIxB,EAAK,WAAW,IAAIyB,GAAK,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACzDzB,EAAK,WAAauB,EAAM,IAAIG,GAAQF,EAAI,IAAIE,CAAI,GAAK,CAAE,KAAAA,CAAK,CAAC,CAC/D,EAGA,SAASC,EAA8B,CACjCA,IAAU3B,EAAK,MAAM,QACvBA,EAAK,MAAM,OAAS,CAAC,GAEvBA,EAAK,MAAM,MAAQ2B,CACrB,EACA,gBAAgBC,EAA6B,CAC3C5B,EAAK,MAAM,QAAU4B,CACvB,EACA,WAAWF,EAAc,CACvB,IAAMJ,EAAStB,EAAK,WACpBA,EAAK,WAAasB,EAAO,KAAKG,GAAKA,EAAE,OAASC,CAAI,EAC9CJ,EAAO,OAAOG,GAAKA,EAAE,OAASC,CAAI,EAClC,CAAC,GAAGJ,EAAQ,CAAE,KAAAI,CAAK,CAAC,CAC1B,EACA,aAAaA,EAAcG,EAA8B,CACvD7B,EAAK,WAAaA,EAAK,WAAW,IAAIyB,GACpCA,EAAE,OAASC,EAAO,CAAE,GAAGD,EAAG,MAAO,CAAE,GAAGA,EAAE,MAAO,GAAGI,CAAM,CAAE,EAAIJ,CAChE,CACF,EAKA,cAAcK,EAAwB,CACpC9B,EAAK,WAAa8B,CACpB,EACA,kBAAkBC,EAA+B,CAC/C/B,EAAK,eAAiB+B,CACxB,EACA,kBAAkBC,EAAqC,CACrDhC,EAAK,eAAiBgC,CACxB,EACA,sBAAsBC,EAAgC,CACpDjC,EAAK,mBAAqBiC,CAC5B,EASA,mBAAmBC,EAAgB,CACjC,IAAMC,EAASnC,EAAK,gBAElBmC,IAAW,QACXC,GAAS,CAAC,MAAG,eAAWpC,CAAI,EAAE,KAAK,CAAC,EAAE,KACpCqC,GAASA,EAA0B,KAAOF,CAC5C,IAEAnC,EAAK,gBAAkBkC,EAE3B,EACA,eAAeI,EAAuB,CACpCtC,EAAK,YAAcsC,CACrB,EACA,mBAAmBC,EAAiB,CAC9BA,EAAM,KAAK;AAAA,CAAI,IAAMvC,EAAK,gBAAgB,KAAK;AAAA,CAAI,IACrDA,EAAK,gBAAkBuC,EAE3B,EACA,kBAAkB9B,EAAqB,CACrCT,EAAK,eAAiBS,CACxB,EACA,iBAAiB+B,EAAgC,CAC/CxC,EAAK,cAAgBwC,CACvB,EACA,iBAAiBC,EAAiB,CAChCzC,EAAK,cAAgByC,CACvB,EACA,aAAa1B,EAAe,CAC1Bf,EAAK,UAAYe,EACjBf,EAAK,WAAa,IACpB,EAGA,cAAc0C,EAA+C,CAC3D1C,EAAK,WAAa0C,EAClB,IAAMC,EAAO3C,EAAK,cACZ4C,EAAQ5C,EAAK,eACb6C,EACJH,GAASC,EACL,CAACA,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAE,KAAKG,GAAKA,EAAE,OAASJ,EAAM,GAAG,EAC7D,OACAK,EACJF,GAAOD,GAAS5C,EAAK,MACjBgD,GAAUhD,EAAK,MAAO6C,EAAKH,EAAO,OAAQE,EAAM,MAAM,EACtD,OACN5C,EAAK,YAAc+C,GAAQ,IAC7B,EACA,cAAcE,EAAyC,CACrDjD,EAAK,WAAaiD,CACpB,EACA,eAAeC,EAAwB,CACrClD,EAAK,YAAckD,CACrB,EACA,gBAAgBZ,EAAuB,CACrCtC,EAAK,aAAesC,CACtB,EACA,gBAAgBA,EAAuB,CACrCtC,EAAK,aAAesC,CACtB,EACA,WAAWa,EAAkB,CAC3BnD,EAAK,UAAYmD,CACnB,EACA,cAAe,CACbnD,EAAK,aAAe,KACpBA,EAAK,UAAY,EACnB,EAGA,uBAAwB,CACtBA,EAAK,YAAc,KACnBA,EAAK,eAAiB,KACtBA,EAAK,cAAgB,KACrBA,EAAK,YAAc,KACnBA,EAAK,aAAe,KACpBA,EAAK,aAAe,KACpBA,EAAK,UAAY,EACnB,EACA,gBAAgBsC,EAAgB,CAC9B,IAAMS,EAAO/C,EAAK,UAAU,IAAIsC,CAAM,EAChCc,EAAWpD,EAAK,SAChBqD,EAAYrD,EAAK,cACvB,GAAI+C,GAAQK,GAAYC,EAAW,CACjC,IAAMC,KAAU,eAAWtD,CAAI,EACzBuD,EAASvD,EAAK,YAIdwD,EAAOD,EACTE,GAAkB,CAAE,OAAAnB,EAAQ,SAAAc,EAAU,UAAAC,CAAU,CAAC,EACjD,UACA,8BAA0BC,CAAO,GACnCA,EAAQ,WACNA,EAAQ,UAAU,oBAAqB,cAAe,CACpD,YAAa,CACX,GAAIP,EAAK,GACT,KAAMA,EAAK,KACX,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,KAAMA,EAAK,QAAQ,KACnB,WAAYA,EAAK,QAAQ,QAIzB,qBAAsBW,GAAgBX,CAAI,GAAG,OAI7C,sBAAuBW,GAAgBX,CAAI,GAAG,UAI9C,YAAaA,EAAK,SAAS,OAC3B,QAASA,EAAK,QACd,GAAIQ,GAAUC,EACV,CACE,QAASD,EAAO,QAChB,aAAcA,EAAO,aACrB,MAAOC,EAAK,MACZ,IAAKA,EAAK,GACZ,EACA,CAAC,CACP,CACF,CAAC,CACH,CAEJ,CACF,EAIA,aAAaG,EAAWC,EAAYC,EAAY,CAC9C,GAAM,CAAE,KAAAC,CAAK,EAAI9D,EACbA,EAAK,gBAAkB,QAAU8D,EACnCA,EAAK,iBAAiB9D,EAAK,WAAa4D,CAAE,GAE1C5D,EAAK,cAAgB,OACrBA,EAAK,MAAQ+D,GAAUJ,CAAC,EACxB3D,EAAK,WAAa4D,GAEpB5D,EAAK,WAAa6D,CACpB,EACA,KAAKG,EAAgBC,EAAiBC,EAAiB,CACrD,GAAM,CAAE,KAAAJ,CAAK,EAAI9D,EACjB,GAAIA,EAAK,gBAAkB,QAAU8D,EAAM,CACzCA,EAAK,OAAOA,EAAK,QAAUE,EAAQC,CAAO,EAC1C,MACF,CACAjE,EAAK,cAAgB,OACrB,IAAMmE,EAAIC,GAAUpE,EAAMgE,EAAQC,EAASC,EAASlE,EAAK,SAAS,EAClEA,EAAK,MAAQmE,EAAE,MACfnE,EAAK,WAAamE,EAAE,WACpBnE,EAAK,WAAamE,EAAE,UACtB,EACA,kBAAmB,CACjBnE,EAAK,uBAAyB,GAC9BA,EAAK,eACP,EAEA,mBAAoB,CAClBA,EAAK,kBACP,EACA,WAAY,CAEV,GAAIA,EAAK,gBAAkB,OAAQ,CACjC,IAAMqE,EAASrE,EAAK,aACdsE,EAAUtE,EAAK,YAAc,OAC7BuE,EAAMD,EAAUE,GAAeC,EAC/BC,EAASJ,EAAUE,GAAexE,EAAK,UACvC2E,EAAe3E,EAAK,QAAQ,OAAS0E,EAASH,EAChDF,GAAUM,EAAe,IAC3B3E,EAAK,WAAa4E,GAChBP,EACAM,EACA3E,EAAK,OACL0E,CACF,GAEF,MACF,CAIA,IAAMG,EAAM7E,EAAK,gBACb6E,IACF7E,EAAK,MAAQ6E,EAAI,MACjB7E,EAAK,WAAa6E,EAAI,WACtB7E,EAAK,WAAa6E,EAAI,WAE1B,EACA,kBAAmB,CACjB7E,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,eAAiB,OACtBA,EAAK,wBAA0B,OAC/BA,EAAK,cAAgB,MACvB,CACF,EAAE,EACD,QAAQA,IAAS,CAIhB,cAAc8E,EAAeC,EAAoB,CAC/C,IAAMC,EAAWhF,EAAK,gBAAkB,OACpCgF,IACFhF,EAAK,cAAgB,QAEvBA,EAAK,MAAQ8E,EACb9E,EAAK,WAAa+E,EACdC,GACFhF,EAAK,UAAU,CAEnB,EAGA,WAAY,CACNA,EAAK,gBAAkB,SACzBA,EAAK,cAAgB,OAEvBA,EAAK,UAAU,CACjB,EAGA,aAAc,CACRA,EAAK,gBAAkB,SACrBA,EAAK,eACPA,EAAK,cAAgB,QAErBA,EAAK,cAAgB,MACrBA,EAAK,UAAU,GAGrB,CACF,EAAE,EACD,QAAQA,GAAQ,CAIf,SAASiF,GAAwB,CAC/B,aAAajF,EAAK,kBAAkB,EACpCA,EAAK,uBAAyB,GAC9BA,EAAK,mBAAqB,WAAW,IAAM,IACrC,YAAQA,CAAI,GACdA,EAAK,iBAAiB,CAE1B,EAAGkF,EAAoB,CACzB,CAQA,SAASC,GAA6B,CACpC,qBAAqBnF,EAAK,mBAAmB,EAC7CA,EAAK,oBAAsB,sBAAsB,IAAM,IACjD,YAAQA,CAAI,GACdA,EAAK,kBAAkB,CAE3B,CAAC,CACH,CAEA,MAAO,CAsBL,SAASsC,EAAgB8C,EAAYC,EAAY,CAC/C,IAAMC,EAAYtF,EAAK,cAAc,cACrC,GAAIsF,IAAYhD,CAAM,EAAG,CACvB,QAAWiD,KAAOD,EAAUhD,CAAM,EAChCiD,EAAI,GAAKH,EACTG,EAAI,GAAKF,EAEXF,EAA2B,CAC7B,CACF,EACA,sBAAAF,CACF,CACF,CAAC,EDpbI,IAAMO,GAAkBC,GAAmB,QAAQC,GAAQ,CAChE,IAAIC,EAEAC,EAEJ,SAASC,EAAWC,EAAwB,CAC1C,GAAM,CAAE,WAAAC,CAAW,KAAI,cAAWL,CAAI,EACtC,OAAOK,EAAW,QAAK,mBAAgBL,CAAI,EAAG,qBAAsB,CAClE,GAAGI,EACH,OAAQH,GAAgB,OAIxB,eAAgBK,GAAU,CACxBN,EAAK,oBAAiB,qBAAkBM,CAAM,GAAK,EAAE,CACvD,CACF,CAAC,CACH,CAEA,SAASC,GAAiB,CACxB,OAAOC,GAAiB,CACtB,QAASR,EAAK,cACd,aAAcA,EAAK,aACnB,aAAcA,EAAK,aACnB,kBAAmBA,EAAK,iBAC1B,CAAC,CACH,CAMA,SAAUS,EAAcC,EAAc,CACpC,IAAMC,EAAQ,YAAY,IAAI,EACxBC,EAAUC,GAAe,IAAIb,EAAK,gBAAgB,EAElDc,EAASd,EAAK,YACde,EAAQH,GAAWE,EAASE,GAAaN,EAAOI,CAAM,EAAIJ,EAE1DO,EACJL,GAAWZ,EAAK,YAAc,GAAK,CAACe,EAAM,MACtCG,GAAeH,EAAOf,EAAK,WAAW,EACtC,OACAmB,EAAQC,EAAkBpB,EAAK,gBAAgB,EAAE,IACrDiB,GAAQ,OAASF,EACjBf,EAAK,YACLA,EAAK,KAAOA,EAAK,cAAc,WAAa,MAC9C,EACA,GAAImB,EAKF,MAAO,CAAE,OAHPF,GAAUE,EAAM,QACZ,CAAE,GAAGA,EAAO,QAAS,CAAE,GAAGA,EAAM,QAAS,OAAAF,CAAO,CAAE,EAClDE,EACW,SAAU,YAAY,IAAI,EAAIR,CAAM,EAEvD,IAAMU,EAAWd,EAAe,EAC1Be,EAAMC,GAAa,MAAMb,EAAOW,CAAQ,EAC9C,OAAIC,EACK,CAAE,OAAQA,EAAK,SAAU,YAAY,IAAI,EAAIX,CAAM,EAEpD,MAAMY,GAAa,OAAOb,EAAOW,EAAUlB,CAAU,CAI/D,CAcA,IAAIqB,EAAc,EAEZC,EAAgB,IAAI,IAK1B,SAAUC,EAAWhB,EAAc,CACjC,IAAMN,EAAU,EAAEoB,EACZG,EAAS,IAAM3B,EAAK,QAAUU,GAASN,IAAYoB,EACnDI,EAAS3B,GAAgB,OAC3B4B,EACJ,GAAI,CAEF,GAAI7B,EAAK,gBAAkBU,EAAM,MAAM,OAASV,EAAK,cACnD,MAAM,IAAI,MACR,4BAA4BU,EAAM,MAAM,OAAO,eAAe,CAAC,iBAAiBV,EAAK,cAAc,eAAe,CAAC,oGACrH,EAEF6B,EAAW,MAAOpB,EAAcC,CAAK,CACvC,OAASoB,EAAG,CAMV,GAAI,CAACH,EAAO,GAAKC,GAAQ,QACvB,MAAO,GAET,MAAME,CACR,CACA,IAAMC,EAAOJ,EAAO,EACpB,OAAII,IACF/B,EAAK,aAAe6B,EAAS,OAC7B7B,EAAK,YAAY6B,EAAS,QAAQ,GAE7BE,CACT,CAIA,SAASC,EAAgBtB,EAAcI,EAAwB,CAC7D,IAAMmB,EAAQvB,EAAM,YACpB,OAAOA,EAAM,aAAe,SAAWuB,GAEjCC,GAAaxB,EAAOV,EAAK,kBAAkBc,EAAO,YAAY,CAAC,GAC/DqB,GAAoBF,EAAOnB,EAAO,YAAY,IAC7C,KACH,MACN,CAMA,SAAUsB,EACRC,EACAC,EACAxB,EACAyB,EAAgB,GAChBC,EACA,CACA,IAAMZ,EAAS3B,GAAgB,OAC/BD,EAAK,iBAAiB,aAAa,EACnC,IAAMyC,EAASC,GAAUL,EAAMC,EAAM,CACnC,cAAetC,EAAK,eAAiBc,GAAQ,YAC/C,CAAC,EACK6B,EAAS7B,EAASkB,EAAgBS,EAAQ3B,CAAM,EAAI,OACpDJ,EACJ,CAACV,EAAK,eACN2C,IAAW,QACXA,IAAWF,EAAO,cACdG,GAAgBH,EAAQE,CAAM,EAC9BF,EACN,GAAID,EAAS,CACXxC,EAAK,iBAAiB,oBAAoB,EAC1C,GAAI,CACF,GAAM,CAAE,QAAA6C,EAAS,MAAAC,CAAM,EAAK,MAAMN,EAAQ9B,CAAK,EAC/CA,EAAM,MAAQmC,EACd7C,EAAK,WAAa,CAAE,MAAO6C,EAAQ,OAAQ,MAAAC,CAAM,CACnD,OAAShB,EAAG,CACV,GAAIF,GAAQ,QACV,OAEF,QAAQ,KAAK,4CAA6CE,CAAC,EAC3D9B,EAAK,WAAa,MACpB,CACA,GAAI4B,GAAQ,QACV,MAEJ,MACE5B,EAAK,WAAa,OAEpB,IAAM+C,EAAWR,EAAgBvC,EAAK,aAAe,KACrDA,EAAK,MAAQU,EACbV,EAAK,YAAcc,EACnBd,EAAK,oBAAsB2C,EAC3B3C,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxByB,EAAc,MAAM,EACpBzB,EAAK,aAAe,OACpBA,EAAK,SAAW,CAAC,EAKjBA,EAAK,sBAAsB,EACvB+C,IAAa,MAAQ/C,EAAK,UAAU,IAAI+C,CAAQ,IAClD/C,EAAK,aAAe+C,GAEtB/C,EAAK,iBAAiB,kBAAkB,EACxC,MAAO0B,EAAWhB,CAAK,CACzB,CAKA,IAAIsC,EAAW,EAEf,SAASC,GAAY,CACnB,IAAMC,EAAO,EAAEF,EACf,OAAA/C,GAAgB,MAAM,EACtBA,EAAiB,IAAI,gBACrBD,EAAK,aAAe,GACb,CACL,OAAQ,IAAMkD,IAASF,EACvB,OAAQ/C,EAAe,MACzB,CACF,CAQA,SAAUkD,EACRC,EACAtC,EACAa,EACA,CAGA,IAAM0B,EAASC,GAAaF,CAAa,EACzC,GAAI,EAAAA,EAAc,OAAS,oBAAsBC,IAAW,QAG5D,GAAI,CACF,IAAME,EAAY,QAAM,cAAWvD,CAAI,EAAE,WAAW,QAClD,mBAAgBA,CAAI,EACpB,kBACA,CACE,cAAe,CACb,KAAM,yBACN,IAAK,GAAGqD,CAAM,kBACd,QAASD,EAAc,QACvB,oBAAqBA,EAAc,mBACrC,EACA,QAAS,CAACtC,CAAM,CAClB,CACF,EACIa,EAAO,IACT3B,EAAK,aAAeuD,EAAS,IAAIC,IAAM,CACrC,QAAS1C,EAAO,QAChB,MAAO0C,EAAE,IAAI,OAAO,EACpB,IAAKA,EAAE,IAAI,KAAK,EAChB,aAAcA,EAAE,IAAI,cAAc,EAClC,UAAYA,EAAE,IAAI,WAAW,GAA4B,EACzD,UAAWA,EAAE,IAAI,WAAW,EAC5B,qBAAsBA,EAAE,IAAI,sBAAsB,EAClD,oBAAqBA,EAAE,IAAI,qBAAqB,EAChD,SAAUA,EAAE,IAAI,UAAU,EAC1B,eAAgB,OAChB,cAAe,MACjB,EAAE,EAEN,OAAS1B,EAAG,CACV,QAAQ,KAAK,mDAAoDA,CAAC,CACpE,CACF,CAKA,SAAU2B,EACRC,EACA5C,EACA6C,EACA,CACA,IAAMC,KAAU,cAAW5D,CAAI,EACzB6D,EAASH,EACXE,EAAQ,OAAO,KAAKE,GAAKA,EAAE,UAAYJ,CAAO,EAC9C,OACJ,GAAKG,EAGL,GAAI,CACF,OAAQ,MAAMD,EAAQ,WAAW,QAC/B,mBAAgB5D,CAAI,EACpB,kBACA,CACE,iBAAe,mBAAe6D,EAAQ,SAAS,EAC/C,QAAS,CAAC/C,CAAM,CAClB,CACF,CACF,OAASgB,EAAG,CACV,QAAQ,KAAK,wBAAwB6B,CAAI,kBAAmB7B,CAAC,EAC7D,MACF,CACF,CAIA,SAAUiC,EAAUjD,EAAwBa,EAAuB,CACjE,IAAM4B,EAAW,MAAOE,EACtBzD,EAAK,WAAW,QAChBc,EACA,OACF,EACIyC,GAAY5B,EAAO,IACrB3B,EAAK,kBAAoBuD,EAE7B,CAIA,SAAUS,EAAYlD,EAAwBa,EAAuB,CACnE,IAAM4B,EAAW,MAAOE,EACtBzD,EAAK,aAAa,QAClBc,EACA,SACF,EACIyC,GAAY5B,EAAO,IACrB3B,EAAK,aAAeiE,GAAiBV,CAAQ,EAEjD,CAMA,SAAUW,EACR5B,EACA6B,EACArD,EACA,CACA,GAAM,CAAE,OAAAa,EAAQ,OAAAC,CAAO,EAAIqB,EAAU,EACrCjD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACb,GAAI,CACF,IAAMqC,EACJ,OAAO8B,GAAW,SAAWA,EAAW,MAAMA,EAAOvC,CAAM,EACzDD,EAAO,IACT,MAAOS,EAAeC,EAAMC,EAAMxB,CAAM,EAE5C,OAASgB,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,iCAAkCG,CAAC,EACjD9B,EAAK,MAAQ8B,EAEjB,QAAE,CACIH,EAAO,GACT3B,EAAK,cAAc,CAEvB,CACA,OAAO2B,EAAO,CAChB,CAEA,SAASyC,GAAY,CACnBnE,GAAgB,MAAM,EACtBA,EAAiB,OACjB+C,IACAxB,GACF,CAIA,SAAS6C,GAAY,CACnBD,EAAU,EACVpE,EAAK,MAAQ,OACbA,EAAK,YAAc,OACnBA,EAAK,oBAAsB,OAC3BA,EAAK,aAAe,OACpBA,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxByB,EAAc,MAAM,EACpBzB,EAAK,aAAe,OACpBA,EAAK,WAAa,OAClBA,EAAK,SAAW,CAAC,EACjBA,EAAK,MAAQ,OACbA,EAAK,UAAY,GACjBA,EAAK,aAAe,GACpBA,EAAK,cAAgB,GACrBA,EAAK,sBAAsB,EAC3BA,EAAK,iBAAiB,CACxB,CAEA,MAAO,CAEL,YAAa,CACXqE,EAAU,CACZ,EAGA,YAAa,CACPrE,EAAK,gBACPqE,EAAU,EACVrE,EAAK,aAAe,GAExB,EAEA,UAAW,CACToE,EAAU,EACVpE,EAAK,UAAY,GACjBA,EAAK,cAAgB,GACrBA,EAAK,aAAe,EACtB,EACA,eAAgB,CACdoE,EAAU,CACZ,EACA,WAAS,QAAK,UAAW/B,EAAcC,EAAO,eAAgB,CAC5D,MAAO4B,EAAa5B,EAAMD,CAAI,CAChC,CAAC,EACD,uBAAqB,QAAK,UACxBiC,EACAxD,EACA,CACAd,EAAK,iBAAiB,cAAc,EACpC,IAAM+B,EAAO,MAAOmC,EAClB,QAASI,EAAYA,EAAS,IAAI,MAAM,GAAG,EAAE,IAAI,GAAK,MAAS,MAC/D1C,MAAU,iBAAa0C,CAAQ,EAAE,SAAS,CAAE,SAAU,OAAQ,OAAA1C,CAAO,CAAC,EACtEd,CACF,EACIA,GAAUiB,GAAQ/B,EAAK,QACzB,MAAOgE,EAAYlD,EAAQ,IAAMd,EAAK,cAAgBc,CAAM,EAEhE,CAAC,EAID,eAAa,QAAK,UAChBsC,EACAtC,EACAyD,EAA2B,CAAC,EAC5B,CACA,GAAM,CAAE,OAAA5C,EAAQ,OAAAC,CAAO,EAAIqB,EAAU,EACrCjD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACbA,EAAK,iBAAiB,mBAAmB,EACzC,GAAI,CACF,IAAMwE,EAAa,YAAY,IAAI,EAC7BC,EAAW,QAAM,cAAWzE,CAAI,EAAE,WAAW,QACjD,mBAAgBA,CAAI,EACpB,cACA,CAAE,cAAAoD,EAAe,OAAAtC,EAAQ,KAAAyD,EAAM,OAAA3C,CAAO,CACxC,EACA,GAAI,CAACD,EAAO,EACV,OAGF,GADA3B,EAAK,WAAW,YAAY,IAAI,EAAIwE,CAAU,EAC1C,CAACC,EACH,MAAM,IAAI,MACR,iHACF,EAoBF,GAlBA,MAAOrC,EACLqC,EACAC,GAAS5D,CAAM,EACfA,EACA,GACA6D,GAAWvB,CAAa,EACpB1C,MACE,cAAWV,CAAI,EAAE,WAAW,QAC1B,mBAAgBA,CAAI,EACpB,gBACA,CACE,cAAAoD,EACA,UAAW1C,EAAM,MAAM,IAAIkE,GAAKA,EAAE,IAAI,EACtC,OAAAhD,CACF,CACF,EACF,MACN,EACI,CAACD,EAAO,EACV,OAKF3B,EAAK,iBAAiB,qBAAqB,EAC3C,MAAM,QAAQ,IAAI,CAChBuE,EAAK,OAAS,SACV,UACA,QAAKpB,CAAW,EAAEC,EAAetC,EAAQa,CAAM,KACnD,QAAKoC,CAAS,EAAEjD,EAAQa,CAAM,KAC9B,QAAKqC,CAAW,EAAElD,EAAQa,CAAM,CAClC,CAAC,CACH,OAASG,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,gCAAiCG,CAAC,EAChD9B,EAAK,MAAQ8B,EAEjB,QAAE,CACIH,EAAO,GACT3B,EAAK,cAAc,CAEvB,CACF,CAAC,EAKD,iBAAe,QAAK,WAAa,CAC/B,IAAMc,EAASd,EAAK,YACd0D,EAAU1D,EAAK,aAAa,QAC9Bc,IACF,MAAOkD,EACLlD,EACA,IACEd,EAAK,cAAgBc,GACrBd,EAAK,aAAa,UAAY0D,CAClC,EAEJ,CAAC,EAGD,0BAAwB,QAAK,WAAa,CACxC,IAAMY,EAAWtE,EAAK,kBAChB6E,EAAMP,EAAW,KAAK,UAAUA,CAAQ,EAAI,OAClD,GAAIO,IAAQ3E,IAGZA,EAAiB2E,EACjB7E,EAAK,mBAAqB,OACtB,EAACsE,GAGL,GAAI,CACF,IAAMjC,EAAQ,QAAM,iBAAaiC,CAAQ,EAAE,SAAS,MAAM,KACtD,WAAQtE,CAAI,GAAK6E,IAAQ3E,IAC3BF,EAAK,mBAAqB8E,GAAgBzC,CAAI,EAElD,OAASP,EAAG,IACN,WAAQ9B,CAAI,GAAK6E,IAAQ3E,MAC3B,cAAWF,CAAI,EAAE,OACf,gEAAgE,OAAO8B,CAAC,CAAC,IACzE,SACF,CAEJ,CACF,CAAC,EAID,iBAAe,QAAK,WAAa,CAC/B,IAAMiD,EAAQ/E,EAAK,eAAe,OAAS,CAAC,EACtC6E,EAAM,KAAK,UAAUE,CAAK,EAC1BrE,EAAQV,EAAK,MACbgF,EAAU,IAAI,IACpB,MAAM,QAAQ,IACZD,EAAM,IAAI,CAAC,CAAE,IAAAE,EAAK,QAAAvB,EAAS,OAAA5C,CAAO,OAChC,QAAK,WAAa,CAChB,IAAMoE,EAAW,GAAGxB,CAAO,IAAI5C,EAAO,OAAO,IAAIA,EAAO,KAAK,IAAIA,EAAO,GAAG,GACvEqE,EAAQ1D,EAAc,IAAIyD,CAAQ,EACtC,GAAI,CAACC,EAAO,CACV,IAAM5B,EAAW,MAAOE,EACtBC,EACA5C,EACA,iBACF,EACA,GAAI,CAACyC,EACH,OAEF4B,EAAQC,GAAe7B,CAAQ,EAAE,IAAI8B,IAAM,CACzC,GAAGA,EACH,QAASvE,EAAO,OAClB,EAAE,EACFW,EAAc,IAAIyD,EAAUC,CAAK,CACnC,CACAH,EAAQ,IAAIC,EAAKE,CAAK,CACxB,CAAC,EAAE,CACL,CACF,KAEE,WAAQnF,CAAI,GACZA,EAAK,QAAUU,GACf,KAAK,UAAUV,EAAK,eAAe,OAAS,CAAC,CAAC,IAAM6E,IAEpD7E,EAAK,iBAAmB+E,EAAM,OAASC,EAAU,OAErD,CAAC,EACD,eAAa,QAAK,WAAa,CAC7BvD,EAAc,MAAM,EACpB,IAAMX,EAASd,EAAK,YACd0D,EAAU1D,EAAK,WAAW,QAC5Bc,IACF,MAAOiD,EACLjD,EACA,IACEd,EAAK,cAAgBc,GAAUd,EAAK,WAAW,UAAY0D,CAC/D,EAEJ,CAAC,EAKD,aAAW,QAAK,UAAW4B,EAAyB,CAClD,IAAM5E,EAAQV,EAAK,MACnB,GAAI,CAACU,EACH,OAEF,IAAM6E,EAAMC,GAAe9E,EAAO+E,GAAiBH,CAAM,CAAC,EAC1D,GAAIC,EAAI,MAAM,SAAW,EAAG,IAC1B,cAAWvF,CAAI,EAAE,OACf,yFACA,MACF,EACA,MACF,CACA,GAAM,CAAE,OAAA2B,CAAO,EAAIsB,EAAU,EAC7BjD,EAAK,SAAW,CACd,GAAGA,EAAK,SACR,CACE,MAAAU,EACA,WAAYV,EAAK,iBACjB,MAAOU,EAAM,KACb,aAAcV,EAAK,YACrB,CACF,EACAA,EAAK,aAAe,OACpB,IAAM0F,EAAQ,GAAGC,GAAkBC,GAAeN,EAAQtF,EAAK,YAAY,EAAE,IAAI,CAAC,OAAOsF,EAAO,OAAO,IAAIA,EAAO,MAAM,eAAe,CAAC,GACxItF,EAAK,MAAQ,CAAE,GAAGuF,EAAK,KAAMG,CAAM,EACnC1F,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO0B,EAAW1B,EAAK,KAAK,IAC9BA,EAAK,cAAc,CAEvB,OAAS8B,EAAG,CACNH,EAAO,IACT3B,EAAK,MAAQ8B,EACb9B,EAAK,cAAc,EAEvB,CACF,CAAC,EACD,eAAa,QAAK,WAAa,CAC7B,IAAM6F,EAAO7F,EAAK,WAClB,GAAK6F,EAGL,CAAA7F,EAAK,SAAWA,EAAK,SAAS,MAAM,EAAG,EAAE,EACzCA,EAAK,MAAQ6F,EAAK,MAClB7F,EAAK,WAAa6F,EAAK,WACvB7F,EAAK,aAAe6F,EAAK,aACzB7F,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO0B,EAAWmE,EAAK,KAAK,IAC9B7F,EAAK,cAAc,CAEvB,OAAS8B,EAAG,CACV9B,EAAK,MAAQ8B,EACb9B,EAAK,cAAc,CACrB,EACF,CAAC,EACD,mBAAiB,QAAK,WAAa,CACjC,IAAMU,EAAQV,EAAK,MACnB,GAAKU,EAGL,CAAAV,EAAK,UAAY,GACjBA,EAAK,iBAAiB,kBAAkB,EAExC,GAAI,EAKE,MAAO0B,EAAWhB,CAAK,IACzBV,EAAK,cAAc,CAEvB,OAAS8B,EAAG,CACV,QAAQ,MAAM,oCAAqCA,CAAC,EACpD9B,EAAK,MAAQ8B,EACb9B,EAAK,cAAc,CACrB,EACF,CAAC,CACH,CACF,CAAC,E2BhqBD,SAAS8F,GAAcC,EAAsC,CAC3D,OAAOC,EAASD,CAAK,GAAK,OAAOA,EAAM,KAAQ,UACjD,CAKA,SAASE,GAAYC,EAAkB,CACrC,IAAMC,EAAOL,GAAcI,CAAO,EAC9BA,EAAQ,IAAI,MAAM,EAClBF,EAASE,CAAO,EACdA,EAAQ,KACR,OACN,OAAO,OAAOC,GAAS,SAAWA,EAAO,MAC3C,CAKO,SAASC,GAAaC,EAAwC,CACnE,IAAIC,EACJ,GAAIN,EAASK,CAAO,GAAKL,EAASK,EAAQ,aAAa,EAAG,CACxD,GAAM,CAAE,QAAAE,EAAS,MAAAC,EAAO,OAAAC,EAAQ,aAAAC,CAAa,EAAIL,EAAQ,cACrD,OAAOE,GAAY,UAAY,OAAOC,GAAU,WAClDF,EAAS,CACP,QAAAC,EAIA,MAAO,OAAOE,GAAW,SAAWA,EAASD,EAAQ,EACrD,aACE,OAAOE,GAAiB,SAAWA,EAAe,OACpD,YAAaT,GAAYI,EAAQ,YAAY,CAC/C,EAEJ,CACA,OAAOC,CACT,CAWO,SAASK,GACdC,EACAC,EACA,CACA,OACGD,EAAM,eAAiB,QACtBA,EAAM,eAAiBC,EAAO,eAChCD,EAAM,UAAYC,EAAO,SACzBD,EAAM,OAASC,EAAO,OACtBD,EAAM,MAAQC,EAAO,GAEzB,CAWO,SAASC,GAAgB,CAC9B,MAAAF,EACA,MAAAG,CACF,EAGG,CACD,IAAIC,EACAC,EACJ,QAAWC,KAAQH,EACbG,EAAK,OAASN,EAAM,YACtBI,EAASE,EAAK,GAEdD,IAAY,QACZE,EAAWD,CAAI,GACfN,EAAM,OAASM,EAAK,OAAO,OAC3BN,EAAM,MAAQM,EAAK,OAAO,MAAQA,EAAK,SAEvCD,EAAUC,EAAK,IAInB,OAAOF,GAAUC,GAAW,IAC9B,CC/HA,IAAMG,GAAa,iBACbC,GAAa,gBAInB,SAASC,GAASC,EAAa,CAC7B,IAAMC,EAASJ,GAAW,KAAKG,CAAG,EAC5BE,EAASJ,GAAW,KAAKE,CAAG,EAClC,MAAO,CACL,GAAIC,EACA,CAAC,CAAE,OAAQA,EAAO,CAAC,EAAI,UAAW,OAAO,OAAOA,EAAO,CAAC,CAAC,EAAI,CAAC,CAAE,CAAC,EACjE,CAAC,EACL,GAAIC,EAAS,CAAC,CAAE,OAAQA,EAAO,CAAC,EAAI,UAAWA,EAAO,CAAC,CAAE,CAAC,EAAI,CAAC,EAC/D,CAAE,OAAQF,EAAK,UAAW,MAAU,CACtC,CACF,CAEA,SAASG,GAAYC,EAAkB,CACrC,OAAOC,EAAWD,CAAQ,EAAE,KAAK,MAAM,GAAG,EAAE,CAAC,CAC/C,CAKO,SAASE,GAAYN,EAAaO,EAAoC,CAC3E,IAAMC,EAAQD,EAAM,IAAIE,GAAKA,EAAE,IAAI,EACnC,OAAW,CAAE,OAAAC,EAAQ,UAAAC,CAAU,IAAKZ,GAASC,CAAG,EAAG,CACjD,IAAMY,EAAQJ,EAAM,OAClBK,GACEC,GAAYT,EAAWQ,CAAI,EAAE,IAAI,IAAMH,IACtCC,IAAc,QAAaR,GAAYU,CAAI,IAAMF,EACtD,EACA,GAAIC,EAAM,OAAS,EACjB,OAAOA,CAEX,CACA,MAAO,CAAC,CACV,ChC1BO,IAAMG,GAAuBC,GACjC,QAAQC,IAAS,CAChB,sBAAsBC,EAAmB,CACvC,GAAI,CAACD,EAAK,kBAAmB,IAO3B,gBACEA,KACA,WAAQ,IAAM,CAEVA,EAAK,oBACL,aAAU,IAAMA,EAAK,gBAAkB,KAAK,GAE5CA,EAAK,UAAU,CAEnB,CAAC,CACH,KAEA,gBACEA,KAGA,YACE,IAAM,CACJ,IAAME,EAAOF,EAAK,UAClB,OAAOE,EACH,GAAGF,EAAK,MAAM,KAAK,IAAIA,EAAK,aAAa,MAAM,IAAIE,EAAK,OAAO,GAC/D,EACN,EACA,IAAM,CACJF,EAAK,UAAU,CACjB,CACF,CACF,KAGA,gBACEA,KACA,YACE,KAAO,CACL,MAAOA,EAAK,MACZ,MAAO,KAAK,UAAUA,EAAK,eAAe,OAAS,CAAC,CAAC,CACvD,GACA,IAAM,CACCA,EAAK,cAAc,CAC1B,EACA,CACE,gBAAiB,GACjB,OAAQ,CAACG,EAAGC,IAAMD,EAAE,QAAUC,EAAE,OAASD,EAAE,QAAUC,EAAE,KACzD,CACF,CACF,KAEA,gBACEJ,KACA,YACE,IACEA,EAAK,mBAAqB,WACtB,KAAK,UAAUA,EAAK,mBAAqB,IAAI,EAC7C,OACNK,GAAO,CACDA,IAAQ,QACLL,EAAK,uBAAuB,CAErC,EACA,CAAE,gBAAiB,EAAK,CAC1B,CACF,KAGA,gBACEA,KACA,YACE,IAAMA,EAAK,UACX,IAAM,CACAA,EAAK,gBAAkB,QACzBA,EAAK,UAAU,CAEnB,CACF,CACF,KAcA,gBACEA,KACA,WAAQ,IAAM,CACZ,IAAMM,EAAQC,MAAa,eAAWP,CAAI,EAAE,OAAO,KACnD,aAAU,IAAM,CACd,IAAMQ,EAASR,EAAK,YACdS,EAAQT,EAAK,MACbU,EACJJ,GAASE,GAAUG,GAAcL,EAAOE,CAAM,EAC1CF,EACA,OAGAM,EACJF,GAAU,aAAeD,GAAO,MAC5BI,GAAYH,EAAS,YAAaD,EAAM,KAAK,EAC7C,CAAC,EACHD,GAAUC,GAAS,CAACT,EAAK,eAC3BA,EAAK,eACHU,GAAYE,EAAS,SAAW,EAC5BE,GAAgB,CAAE,MAAOJ,EAAU,MAAOD,EAAM,KAAM,CAAC,EACvD,IACN,EAEFT,EAAK,mBAAmBY,CAAQ,CAClC,CAAC,CACH,CAAC,CACH,KAyBA,gBACEZ,KACA,YACE,IAAM,GAAGA,EAAK,KAAK,IAAIA,EAAK,UAAU,IAAIA,EAAK,UAAU,GACzD,IAAM,CACJA,EAAK,eAAe,IAAI,EACxBA,EAAK,iBAAiB,IAAI,EAC1BA,EAAK,eAAe,IAAI,CAC1B,EACA,CAAE,KAAM,iCAAkC,CAC5C,CACF,EAKA,IAAIe,EAAgB,MACpB,gBACEf,KACA,WAAQ,IAAM,CACZ,GAAM,CAAE,MAAAgB,CAAM,EAAIhB,EACZiB,EAAWC,GAAelB,CAAI,EACpC,GAAIe,EAAe,CACjBA,EAAgB,GAChB,MACF,CACA,IAAMI,KAAQ,aAAU,IAAMnB,EAAK,aAAa,EAC5CmB,GAAO,QAAUH,GAASI,GAASD,EAAM,OAAQF,CAAQ,GAG7DjB,EAAK,sBAAsB,CAC7B,CAAC,CACH,KAIA,gBACEA,KACA,WAAQ,IAAM,CACZ,IAAMI,EAAIJ,EAAK,wBACfqB,GAASrB,EAAK,eAAe,EACzBI,IACFJ,EAAK,gBAAgBI,CAAC,EACtBJ,EAAK,UAAU,EAEnB,CAAC,CACH,CACF,CAKAA,EAAK,uBAAiCC,EAAS,KAAO,CAIpD,OAASG,GAAgB,CAEvB,GADAA,EAAE,OAAOJ,EAAK,UAAWA,EAAK,YAAY,EACtCA,EAAK,cAAc,QACrB,OAAAqB,GAASrB,EAAK,aAAa,EAC3BI,EAAE,eAAekB,EAAW,EAC5BtB,EAAK,mBAAmB,EAAG,EAAG,CAC5B,SAAO,aAAU,IAAMA,EAAK,KAAK,EACjC,UAAQ,aAAU,IAAMkB,GAAelB,CAAI,CAAC,CAC9C,CAAC,EACM,GAET,GAAIA,EAAK,YACP,OAAAqB,GAASrB,EAAK,aAAa,EAC3BI,EAAE,eAAekB,EAAW,EAC5BtB,EAAK,mBAAmB,EAAG,EAAG,CAC5B,SAAO,aAAU,IAAMA,EAAK,KAAK,EACjC,UAAQ,aAAU,IAAMA,EAAK,gBAAgB,CAAC,CAChD,CAAC,EACM,GAET,IAAMuB,EAAgB,YAAY,IAAI,EAChCJ,EAAQnB,EAAK,aACjBA,EAAK,SACLA,EAAK,kBACP,EACA,OAAImB,GACFf,EAAE,eAAee,EAAM,KAAK,EAC5BnB,EAAK,mBACH,YAAY,IAAI,EAAIuB,EACpBJ,EAAM,MAAM,YAAY,OACxB,CACE,SAAO,aAAU,IAAMnB,EAAK,KAAK,EACjC,OAAQmB,EAAM,cAChB,CACF,EACO,IAMF,EACT,EAEA,OAASf,GACFJ,EAAK,eAGVA,EAAK,MAAMI,CAAC,EACZJ,EAAK,YAAY,EACV,IAJE,GAMX,eAAiBI,GAAgB,CAC/BA,EAAE,wBAAwB,CAC5B,CACF,EAAE,CACJ,CACF,EAAE,EACD,QAAQJ,IAAS,CAEhB,aAAawB,EAAuB,CAClC,OAAAxB,EAAK,cAAcwB,CAAI,EAChBxB,EAAK,gBAAgB,CAC9B,EAEA,qBAAsB,CACpB,OAAAA,EAAK,qBAAqB,CAACA,EAAK,iBAAiB,EAC1CA,EAAK,iBAAmBA,EAAK,gBAAgB,EAAI,MAC1D,EAEA,WAAY,CAAC,EACb,aAAc,CAGPA,EAAK,oBACRA,EAAK,cAAgB,OAEzB,CACF,EAAE,EiC7SJ,IAAAyB,GAA+B,SAIzBC,GAAwB,eAmBvB,SAASC,GAAa,CAC3B,QAAAC,EACA,aAAAC,EACA,MAAAC,CACF,EAIG,CACD,IAAMC,EAAkB,CAAC,EACzB,QAAWC,KAASJ,EAAQ,OAAQ,CAClC,IAAMK,KAAgB,mBAAeD,EAAO,MAAM,EAC5CE,KAAyB,mBAAeF,EAAO,eAAe,EAC9DG,KAAmB,mBAAeH,EAAO,SAAS,EAEtDC,IAASP,IACT,MAAM,QAAQQ,CAAa,GAC3BA,EAAc,SAASL,CAAY,GACnC,OAAOM,GAAY,UACnBA,IAAYL,GAEZC,EAAM,KAAKI,CAAO,CAEtB,CACA,OAAOL,EAAQ,CAACA,EAAO,GAAGC,CAAK,EAAIA,CACrC,CChDA,IAAAK,GAA+B,SAC/BC,GAA6B,UAC7BC,GAAwC,UAgBxC,IAAMC,GAAqB,eACrBC,GAA2B,mBAIjC,SAASC,GAAeC,EAA8B,CACpD,MAAI,mBAAeA,EAAO,MAAM,IAAMH,GACpC,MAAO,GAET,IAAMI,EAAuBD,EAAM,SAAS,KAC5C,GAAI,OAAOC,GAAgB,UAAY,IAAC,oBAAgBD,CAAK,EAC3D,MAAO,GAET,GAAM,CAAE,cAAAE,CAAc,KAAI,WAA0CF,CAAK,EACzE,MACE,CAAC,CAACE,GAAe,eAAeD,CAAW,GAC3CC,EAAc,eAAeD,CAAW,EAAE,iBAAiB,WACzDH,EAEN,CAOO,SAASK,GACdC,EACAC,EACA,CACA,IAAMC,EAAS,IAAI,IAAID,CAAa,EAC9BE,EAAkC,CAAC,EACzC,QAAWP,KAASI,EAAQ,OAAQ,CAClC,IAAMI,KAA2B,mBAAeR,EAAO,eAAe,EAChES,KAAmB,mBAAeT,EAAO,SAAS,EACxD,GACED,GAAeC,CAAK,GACpB,OAAOS,GAAY,UACnB,MAAM,QAAQD,CAAe,EAC7B,CACA,IAAME,EAAWF,EAAgB,OAC/BG,GACE,OAAOA,GAAS,UAChBL,EAAO,IAAIM,GAAsBR,EAASO,CAAI,CAAC,CACnD,EAAE,OACED,GAAY,GACdH,EAAM,KAAK,CAAE,QAAAE,EAAS,QAAM,iBAAaT,EAAOI,CAAO,EAAG,SAAAM,CAAS,CAAC,CAExE,CACF,CACA,OAAOH,EAAM,KAAK,CAACM,EAAGC,IAAMA,EAAE,SAAWD,EAAE,QAAQ,CACrD,CCpEO,SAASE,GACdC,EACAC,EACAC,EAAO,gBACP,CACA,IAAMC,EAAM,IAAI,gBAAgB,IAAI,KAAK,CAACH,CAAI,EAAG,CAAE,KAAAE,CAAK,CAAC,CAAC,EACpDE,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOD,EACTC,EAAE,SAAWH,EACbG,EAAE,MAAM,EACR,WAAW,IAAM,CACf,IAAI,gBAAgBD,CAAG,CACzB,EAAG,CAAC,CACN,C9CcO,IAAME,GAAoBC,GAC9B,QAAQC,IAAS,CAWhB,iBAAiBC,EAAuD,CACtE,IAAMC,KAAU,eAAWF,CAAI,EACzBG,EAAcF,EAAO,WAAaD,EAAK,aAAa,aACpDI,EAASC,GAAiB,CAC9B,QAAAH,EACA,SAAUD,EAAO,SACjB,SAAUA,EAAO,SACjB,gBAAiBD,EAAK,gBACtB,OAAQM,GAAa,CACnB,QAAAJ,EACA,aAAcD,EAAO,SACrB,MAAOE,EAAcH,EAAK,cAAgB,MAC5C,CAAC,CACH,CAAC,EACGG,GACFH,EAAK,mBAAmBI,CAAM,CAElC,EAIA,sBAAsBH,EAGnB,CACDM,GAAsB,CACpB,WAAS,eAAWP,CAAI,EACxB,SAAUC,EAAO,SACjB,SAAUA,EAAO,SACjB,gBAAiBD,EAAK,eACxB,CAAC,CACH,EACA,gBAAgBQ,EAAiB,CAC/BC,GAAkB,CAChB,WAAS,eAAWT,CAAI,EACxB,aAAcA,EAAK,qBACnB,QAAAQ,EACA,aAAcR,EAAK,aACrB,CAAC,CACH,CACF,EAAE,EACD,MAAMA,IAAS,CAId,IAAI,qBAAsB,CACxB,IAAMU,EAAUV,EAAK,qBAAqB,IAAIW,GAAKA,EAAE,MAAM,EAC3D,OAAOD,EAAQ,QAAU,EACrBE,MAAwB,eAAWZ,CAAI,EAAGU,CAAO,EACjD,CAAC,CACP,CACF,EAAE,EACD,MAAMV,IAAS,CAOd,wBAAqC,CACnC,GAAM,CAAE,YAAAa,CAAY,EAAIb,EAAK,qBACvBc,EAAQd,EAAK,eACbe,EAAQC,GAAgBA,EAAE,KAAK;AAAA,CAAI,IAAMF,GAAO,KAAK;AAAA,CAAI,EAC/D,MAAO,CACL,CACE,KAAM,QACN,MAAO,eACP,QAASA,IAAU,OACnB,QAAS,IAAM,CACbd,EAAK,kBAAkB,MAAS,CAClC,CACF,EACA,GAAIa,EAAY,OAAS,EACrB,CACE,CACE,KAAM,QACN,MAAO,+BACP,QAASE,EAAKF,CAAW,EACzB,QAAS,IAAM,CACbb,EAAK,kBAAkBa,CAAW,CACpC,CACF,CACF,EACA,CAAC,EACL,CACE,KAAM,QACN,MAAO,oBACP,QAASC,IAAU,QAAa,CAACC,EAAKF,CAAW,EACjD,QAAS,IAAM,IACb,eAAWb,CAAI,EAAE,YAAYiB,GAAW,CACtCC,GACA,CAAE,MAAOlB,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,CACF,EAEA,uBAAoC,CAClC,IAAME,EAAQnB,EAAK,cAAgBA,EAAK,gBAAgB,MAAQ,OAChE,MAAO,CACL,CACE,KAAM,QACN,MAAO,OACP,QAASmB,IAAU,OACnB,QAAS,IAAM,CACbnB,EAAK,kBAAkB,MAAS,CAClC,CACF,EACA,GAAGA,EAAK,mBAAmB,IAAIoB,IAAW,CACxC,KAAM,QACN,MAAOA,EACP,QAASD,IAAUC,EACnB,QAAS,IAAM,CACbpB,EAAK,kBAAkB,CAAE,MAAOoB,CAAO,CAAC,CAC1C,CACF,EAAE,CACJ,CACF,EACA,gBAA6B,CAC3B,IAAMC,EAAQrB,EAAK,YACnB,MAAO,CACL,CACE,MAAO,SACP,QAASsB,GAAa,IAAIC,IAAS,CACjC,KAAM,QACN,MAAOA,EAAK,MACZ,QAASvB,EAAK,mBAAqBuB,EAAK,MACxC,SAAUvB,EAAK,MAAQ,CAACuB,EAAK,UAAUvB,EAAK,KAAK,EAAI,GACrD,QAAS,IAAM,CACRA,EAAK,aAAauB,EAAK,KAAK,CACnC,CACF,EAAE,CACJ,EACA,CACE,MAAO,QACP,QAASC,GAAc,IAAIC,IAAW,CACpC,KAAM,QACN,MAAOA,EAAO,MACd,QAASzB,EAAK,oBAAsByB,EAAO,MAC3C,QAAS,IAAM,CACbzB,EAAK,eAAeyB,EAAO,KAAK,CAClC,CACF,EAAE,CACJ,EACA,GAAIJ,EAAM,OAAS,GAAKrB,EAAK,WACzB,CACE,CACE,MAAO,OACP,QAAS,CACP,CACE,MAAO,OACP,QAAS,IAAM,CACbA,EAAK,cAAc,CAAC,CAAC,CACvB,CACF,EACA,GAAIA,EAAK,WAAW,OAAS,GAAKA,EAAK,eACnC,CACE,CACE,MAAO,eACP,QAAS0B,GAAa,IAAI,CAAC,CAAE,MAAAC,EAAO,MAAAC,CAAM,KAAO,CAC/C,KAAM,QACN,MAAAA,EACA,QAAS5B,EAAK,MAAM,QAAU2B,EAC9B,QAAS,IAAM,CACb3B,EAAK,SAAS2B,CAAK,CACrB,CACF,EAAE,CACJ,CACF,EACA,CAAC,EACL,GAAI3B,EAAK,aACTA,EAAK,MAAM,QAAU,QACrB,CAACA,EAAK,YACF,CACE,CACE,MAAO,UACP,QAAS,CACP,OACA,GAAGA,EAAK,YAAY,IAAI,CAAC6B,EAAGC,IAAMA,EAAI,CAAC,CACzC,EAAE,IAAIC,IAAY,CAChB,KAAM,QACN,MACEA,IAAY,OAAY,OAAS,GAAGA,CAAO,GAC7C,QAAS/B,EAAK,MAAM,UAAY+B,EAChC,QAAS,IAAM,CACb/B,EAAK,gBAAgB+B,CAAO,CAC9B,CACF,EAAE,CACJ,CACF,EACA,CAAC,EACL,GAAIV,EAAM,OAASW,GACf,CACE,CACE,MAAO,kBACP,QAAS,IAAM,IACb,eAAWhC,CAAI,EAAE,YAAYiB,GAAW,CACtCgB,GACA,CAAE,MAAOjC,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,EACA,CAAC,EACL,IAAII,EAAM,OAASW,GACfX,EAAM,OAAOa,GACXlC,EAAK,WAAW,KAAKmC,GAAKA,EAAE,OAASD,EAAK,IAAI,CAChD,EACAb,GACF,IAAIa,IAAS,CACb,KAAM,WACN,MAAOA,EAAK,MACZ,QAASlC,EAAK,WAAW,KAAKmC,GAAKA,EAAE,OAASD,EAAK,IAAI,EACvD,QAAS,IAAM,CACblC,EAAK,WAAWkC,EAAK,IAAI,CAC3B,CACF,EAAE,EACF,GAAGlC,EAAK,WAAW,IAAIoC,IAAW,CAChC,MAAO,UAAUpC,EAAK,UAAUoC,EAAO,IAAI,CAAC,GAC5C,QAAS,CACP,CAAE,KAAM,YAAsB,MAAO,WAAY,EACjD,GAAGC,GAAY,IAAIlB,IAAU,CAC3B,KAAM,QACN,MAAOA,EAAM,MACb,QAASiB,EAAO,SAAS,QAAUjB,EAAM,MACzC,QAAS,IAAM,CACbnB,EAAK,aAAaoC,EAAO,KAAM,CAC7B,MAAOjB,EAAM,KACf,CAAC,CACH,CACF,EAAE,EACF,CAAE,KAAM,YAAsB,MAAO,SAAU,EAE/C,GAAGmB,GAAa,OACdb,GACEA,EAAO,QAAU,WACjBW,EAAO,SAAS,QAAU,WAC9B,EAAE,IAAIX,IAAW,CACf,KAAM,QACN,MAAOA,EAAO,MACd,QAASW,EAAO,SAAS,SAAWX,EAAO,MAC3C,QAAS,IAAM,CACbzB,EAAK,aAAaoC,EAAO,KAAM,CAC7B,OAAQX,EAAO,KACjB,CAAC,CACH,CACF,EAAE,CACJ,CACF,EAAE,CACJ,CACF,CACF,EACA,CAAC,EACL,GAAIc,GAAe,IAAIvC,EAAK,gBAAgB,EACxC,CACE,CACE,MAAO,gBACP,QAASwC,GAAe,IAAI,CAAC,CAAE,GAAAC,EAAI,MAAAb,CAAM,KAAO,CAC9C,KAAM,QACN,MAAAA,EACA,QAAS5B,EAAK,cAAgByC,EAC9B,SAAUA,EAAK,GAAKzC,EAAK,OAAO,QAAU,OAC1C,QAAS,IAAM,CACbA,EAAK,eAAeyC,CAAE,EACjBzC,EAAK,gBAAgB,CAC5B,CACF,EAAE,CACJ,CACF,EACA,CAAC,EACL,GAAIA,EAAK,mBAAqB,YAC9BA,EAAK,cAAc,OAAS,EACxB,CACE,CACE,MAAO,SACP,QAAS,CACP,CACE,KAAM,QACN,MAAO,eACP,QAASA,EAAK,YAAc,GAC5B,QAAS,IAAM,CACbA,EAAK,aAAa,EAAE,CACtB,CACF,EACA,GAAGA,EAAK,cAAc,IAAI,CAAC,CAAE,IAAA0C,EAAK,KAAAC,EAAM,KAAAC,CAAK,KAAO,CAClD,KAAM,QACN,MAAO,GAAGD,CAAI,SAAMC,EAAK,eAAe,CAAC,WACzC,QAAS5C,EAAK,YAAc0C,EAC5B,QAAS,IAAM,CACb1C,EAAK,aAAa0C,CAAG,CACvB,CACF,EAAE,CACJ,CACF,CACF,EACA,CAAC,EACL,GAAI1C,EAAK,mBAAqB,YAAcA,EAAK,YAC7C,CAAC,CAAE,MAAO,UAAW,QAAS,KAAK,uBAAuB,CAAE,CAAC,EAC7D,CAAC,EACL,GAAIA,EAAK,mBAAqB,YAC9BA,EAAK,aACLA,EAAK,mBAAmB,OAAS,EAC7B,CAAC,CAAE,MAAO,iBAAa,QAAS,KAAK,sBAAsB,CAAE,CAAC,EAC9D,CAAC,EACL,GAAIA,EAAK,YACL,CAAC,EACD,CACE,CACE,MAAO,UACP,QAAS,IAAM,CACbA,EAAK,KACH,IACAA,EAAK,QAAQ,MAAQ,EACrBA,EAAK,QAAQ,OAAS,CACxB,CACF,CACF,EACA,CACE,MAAO,WACP,QAAS,IAAM,CACbA,EAAK,KACH,EAAI,IACJA,EAAK,QAAQ,MAAQ,EACrBA,EAAK,QAAQ,OAAS,CACxB,CACF,CACF,EACA,CACE,MAAO,cACP,QAAS,IAAM,CACbA,EAAK,UAAU,CACjB,CACF,CACF,EACJ,CACE,KAAM,WACN,MAAO,eACP,QAASA,EAAK,YACd,QAAS,IAAM,CACbA,EAAK,eAAe,CAACA,EAAK,WAAW,CACvC,CACF,EACA,CACE,KAAM,WACN,MAAO,sBACP,QAASA,EAAK,kBACd,QAAS,IAAM,CACRA,EAAK,oBAAoB,CAChC,CACF,EACA,CACE,KAAM,WACN,MAAO,wBACP,QAASA,EAAK,UACd,QAAS,IAAM,CACbA,EAAK,aAAa,CAACA,EAAK,SAAS,CACnC,CACF,EACA,GAAI,CAACA,EAAK,MACVA,EAAK,iBACJA,EAAK,OAAO,OAAO,QAAU,GAAK,EAC/B,CACE,CACE,KAAM,WACN,MAAO,4BACP,QAASA,EAAK,UACd,QAAS,IAAM,CACbA,EAAK,aAAa,CAACA,EAAK,SAAS,CACnC,CACF,CACF,EACA,CAAC,EACL,GAAIA,EAAK,sBACL,CACE,CACE,KAAM,WACN,MAAO,wBACP,QAASA,EAAK,mBACd,QAAS,IAAM,CACbA,EAAK,sBAAsB,CAACA,EAAK,kBAAkB,CACrD,CACF,CACF,EACA,CAAC,EACL,CACE,MAAO,aACP,SAAUA,EAAK,oBAAsB,OACrC,iBAAkBA,EAAK,kBACvB,QAAS,IAAM,CACb,IAAM6C,EAAM7C,EAAK,OAAO,EACpB6C,GACFC,GACED,EACA,IAAI7C,EAAK,OAAO,MAAQ,SAAS,WAAW,YAAa,GAAG,CAAC,MAC/D,CAEJ,CACF,EACA,CACE,MAAO,mBACP,SAAUA,EAAK,wBAA0B,OACzC,iBAAkBA,EAAK,sBACvB,QAAS,IAAM,CACb,IAAM+C,EAAO/C,EAAK,WAAW,EACvBE,KAAU,eAAWF,CAAI,EAC/B,UAAU,UACP,UAAU,GAAG,KAAK,UAAU+C,EAAM,KAAM,CAAC,CAAC;AAAA,CAAI,EAC9C,KAAK,IAAM,CACV7C,EAAQ,OACN,wHACA,MACF,CACF,CAAC,EACA,MAAO8C,GAAe,CACrB9C,EAAQ,OAAO,mCAAmC,OAAO8C,CAAC,CAAC,EAAE,CAC/D,CAAC,CACL,CACF,CACF,CACF,EACA,iBAA8B,CAC5B,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQC,GAAqB,CACtC,aAAcnD,EAAK,qBACnB,cAAeA,EAAK,oBACpB,aAAcC,GAAU,CACtBD,EAAK,iBAAiBC,CAAM,CAC9B,EACA,cAAeO,GAAW,CACxBR,EAAK,gBAAgBQ,CAAO,CAC9B,CACF,CAAC,KACC,2BAAuByC,EAAOC,CAAI,EAEpC,OAAOD,CACT,CACF,EAAE,E+CjdG,SAASG,IAAiB,CAC/B,OAAOC,EACT,CCdA,IAAAC,GAA+B,SAI/B,SAASC,GAAcC,EAAmC,CACxD,OAAO,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAMC,GAAQ,OAAOA,GAAS,QAAQ,CAC7E,CAIO,SAASC,GAAWC,EAA8B,CACvD,IAAMC,KAAyB,mBAAeD,EAAO,eAAe,EAC9DE,EAAQN,GAAcK,CAAa,EAAIA,EAAc,MAAM,CAAC,EAAI,CAAC,EACvE,OAAOC,EAAM,OAAS,EAAIA,EAAQ,MACpC,CAMO,SAASC,GAAuBH,EAA8B,CACnE,IAAMC,KAAyB,mBAAeD,EAAO,eAAe,EACpE,OAAOJ,GAAcK,CAAa,EAAIA,EAAc,CAAC,EAAI,MAC3D,CAEO,SAASG,GACdC,EACAC,EACA,CACA,OAAOD,IAAsB,QAAaA,IAAsBC,EAC5D,OACA,sCAAsCD,CAAiB,4BAA4BA,CAAiB,EAC1G,CjDZA,SAASE,GAASC,EAAwB,CASxC,OAPE,QAASA,EACLA,EAAS,IAAI,MAAM,MAAM,EAAE,CAAC,EAC5B,cAAeA,EACbA,EAAS,UACT,SAAUA,EACRA,EAAS,KACT,IACE,MAAM,OAAO,EAAE,GAAG,EAAE,GAAK,EACvC,CAEe,SAARC,IAAqC,CAC1C,OAAO,QACJ,QACC,kBACA,iBACAC,GAAe,EACf,QAAM,MAAM,CACV,KAAM,QAAM,QAAQ,iBAAiB,EAGrC,YAAa,QAAM,MAAM,QAAM,OAAqB,CAAC,EAErD,aAAc,QAAM,MAAM,QAAM,OAAuB,CAAC,EAIxD,cAAe,QAAM,SAAS,QAAM,OAAQ,EAAE,EAC9C,gBAAiB,QAAM,SAAS,QAAM,OAAQ,CAAC,EAC/C,mBAAoB,QAAM,MAAM,QAAM,OAAiB,CAAC,EACxD,YAAa,QAAM,SAAS,QAAM,OAAQC,EAAmB,CAC/D,CAAC,CACH,EACC,MAAMC,IAAS,CACd,IAAI,cAAe,CACjB,OAAOA,EAAK,EACd,EAEA,IAAI,WAAY,CACd,OAAOA,EAAK,KACd,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAK,kBACd,EACA,IAAI,mBAAoB,CACtB,OAAOA,EAAK,WACd,EACA,IAAI,aAAiD,CACnD,OAAOA,EAAK,iBACR,eAAWA,CAAI,EAAE,OAAO,KAAK,GAAK,EAAE,UAAYA,EAAK,aAAa,EAClE,MACN,EACA,IAAI,cAAe,CACjB,OACEA,EAAK,cAAgB,QACpBA,EAAK,gBAAkB,IAAMA,EAAK,eAAiB,MAExD,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,kBAAmB,CACrB,OAAOA,EAAK,cAAgB,CAACA,EAAK,OAAS,CAACA,EAAK,YACnD,EACA,WAAY,CACV,OAAOA,EAAK,gBAAgB,CAC9B,CACF,EAAE,EACD,QAAQA,GAAQ,CACf,IAAMC,EAAYD,EAAK,WACvB,MAAO,CAGL,YAAa,CACXC,EAAU,EACVD,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,cAAgB,EACvB,EACA,MAAO,CACL,IAAME,EAASF,EAAK,aACpB,GAAIA,EAAK,YAEP,OAAKA,EAAK,aACRA,EAAK,eAAeL,GAASK,EAAK,WAAW,CAAC,EAEzCA,EAAK,oBAAoBA,EAAK,YAAaE,CAAM,EAE1D,GAAI,CAACF,EAAK,eAAiB,CAACE,EAC1B,OAEF,IAAMC,EAAQH,EAAK,YACbI,EAAOF,EAAO,IAAMA,EAAO,MAC3BG,EAAUF,EACZG,GACEC,GAAuBJ,CAAK,EAC5BD,EAAO,YACT,EACA,OACJ,GAAI,CAACC,EACHH,EAAK,SACH,IAAI,MACF,uCAAuCA,EAAK,aAAa,2BAC3D,CACF,UACSK,EACTL,EAAK,SAAS,IAAI,MAAMK,CAAO,CAAC,UACvBD,EAAOJ,EAAK,YACrBA,EAAK,SACH,IAAI,MACF,qBAAqBQ,GAAaJ,CAAI,CAAC,uCAAkCI,GAAaR,EAAK,WAAW,CAAC,GACzG,CACF,MAEA,QAAOA,EAAK,YAAYS,GAAmBT,EAAMG,CAAK,EAAGD,EAAQ,CAC/D,KAAMF,EAAK,gBACX,WAAYA,EAAK,mBACjB,GAAIA,EAAK,eACL,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CAGL,CACF,CACF,CAAC,EACA,QAAQA,IAAS,CAChB,WAAY,CACLA,EAAK,KAAK,CACjB,EAKA,aAAaU,EAAuB,CAClC,IAAMC,EAASX,EAAK,eACpB,OAAAA,EAAK,cAAcU,CAAI,EAChBV,EAAK,eAAiBA,EAAK,iBAAmBW,EACjDX,EAAK,KAAK,EACVA,EAAK,gBAAgB,CAC3B,EAIA,aAAc,CACPA,EAAK,OACHA,EAAK,KAAK,KAEjB,eACEA,KACA,aACE,IAAMA,EAAK,UACX,IAAM,CAEFA,EAAK,eACL,CAACY,EAAkBZ,EAAK,gBAAgB,EAAE,YAErCA,EAAK,KAAK,CAEnB,CACF,CACF,CACF,CACF,EAAE,CACN,CD5JA,IAAMa,MAAkB,qBAAyB,EAAE,CAAC,CAAC,EAEtC,SAARC,GAAkCC,EAA8B,CACrEA,EAAc,YAAY,IACjB,IAAI,GAAAC,QAAS,CAClB,KAAM,kBACN,YAAa,oBACb,WAAYC,GAAa,EACzB,WAAYJ,GACZ,kBAAgB,SAAK,IAAM,OAAO,sCAA8B,CAAC,CACnE,CAAC,CACF,CACH,CmDxCA,IAAAK,GAAoC,SACpCC,GAIO,UAOMC,GAAmB,CAC9B,yBACA,uBACA,iBACA,qBACF,EAEA,SAASC,GAAgBC,EAA6C,CACpE,IAAMC,EAAWD,EAAc,uBAC7B,SACF,EACME,EAASC,GAAiBF,EAAS,KAAKG,GAAKA,EAAE,OAASD,CAAI,EAC5DE,EAAcC,GAClBA,GACA,OAAO,OAAO,OAAO,OAAOA,CAAO,EAAkB,CACnD,oBAAqB,CAAC,aAAa,CACrC,CAAC,EACH,MAAO,CACLJ,EAAM,oBAAoB,EAC1BA,EAAM,oBAAoB,EAC1B,GAAGJ,GAAiB,IAAIK,GAAQE,EAAWH,EAAMC,CAAI,CAAC,CAAC,CACzD,EAAE,OAAQC,GAAwBA,IAAM,MAAS,CACnD,CAEe,SAARG,GAA6BP,EAA8B,CAChEA,EAAc,aAAa,IAAM,CAC/B,IAAMQ,KAAe,wBACnB,aACA,CAAC,EACD,CACE,qBAAmB,0BAAsBR,CAAa,EACtD,mBAAoB,SACtB,CACF,EACMS,EAAQ,IAAI,aAAU,CAC1B,KAAM,aACN,YAAa,wBACb,aAAAD,EACA,cAAY,yBACVR,EACA,aACAQ,CACF,CACF,CAAC,EACD,QAAWF,KAAWP,GAAgBC,CAAa,EACjDS,EAAM,eAAeH,CAAO,EAE9B,OAAOG,CACT,CAAC,CACH,CCvBe,SAARC,GAAwCC,EAA8B,CAE3EA,EAAc,oBAAoB,6BAA8BC,GAAQ,CACtE,GAAM,CAAE,QAAAC,EAAS,GAAGC,CAAK,EAAIF,EAC7B,OAAAC,EAAQ,QAAQ,kBAAmBC,CAAI,EAChCF,CACT,CAAC,CACH,CC7CA,IAAAG,GAAqB,UAErBC,GAAwB,UCAxB,IAAAC,GAAoC,SACpCC,GAA8C,UAC9CC,GAAsB,UAWf,SAASC,IAAsB,CACpC,SAAO,wBACL,qBACA,CAKE,WAAY,CACV,KAAM,aACN,MAAO,SAAM,YAAY,aAAcC,EAAkB,EACzD,aAAc,MAChB,EAIA,YAAa,CACX,KAAM,aACN,MAAO,SAAM,YAAY,cAAeC,EAAmB,EAC3D,aAAc,MAChB,EACA,MAAG,kCAA8B,CAC/B,cAAe,IACf,OAAQ,+CACV,CAAC,CACH,EACA,CAAE,gBAAiB,GAAM,mBAAoB,WAAY,CAC3D,CACF,CC3CA,IAAAC,GAAqB,UAGrB,IAAAC,GAAgD,SAChDC,GAA4B,UAC5BC,GAAuC,UACvCC,GAA2B,UAC3BC,GAA6B,UAC7BC,EAKO,UACPC,GAGO,UAGP,IAAAC,GAAyB,UCflB,SAASC,GAAiBC,EAAgB,CAC/C,OACEA,aAAiB,QAChBA,EAAM,OAAS,kBACbA,EAAuC,iBAAmB,IAC3D,uEAAuE,KACrEA,EAAM,OACR,EAEN,CAYO,SAASC,GAAYC,EAAgCC,EAAkB,CAC5E,GACED,GAAO,UAAYC,EAAK,SACxBD,EAAM,eAAiBC,EAAK,aAE5B,MAAO,GAET,IAAMC,EAAOF,EAAM,IAAMA,EAAM,MAC/B,OACEC,EAAK,IAAMA,EAAK,OAASC,GACzBD,EAAK,IAAMD,EAAM,MAAQE,GACzBD,EAAK,MAAQD,EAAM,IAAME,CAE7B,CDUA,IAAMC,MAA2B,SAC/B,IAAM,OAAO,+CAAuC,CACtD,EAEO,SAASC,GAAkBC,EAA6C,CAC7E,OACE,QACG,QACC,qBACA,kBACA,GAAAC,SAAiB,EACjBC,GAAe,EACf,QAAM,MAAM,CACV,KAAM,QAAM,QAAQ,oBAAoB,EACxC,iBAAe,2BAAuBF,CAAY,EAIlD,KAAM,QAAM,MAAM,QAAM,OAAO,CAAC,EAIhC,mBAAoB,QAAM,MAAM,QAAM,OAAO,CAAC,EAC9C,iBAAkB,QAAM,MAAM,QAAM,OAAO,CAAC,EAG5C,UAAW,QAAM,MAAM,QAAM,OAAuB,CAAC,EAGrD,UAAW,QAAM,SAAS,QAAM,QAAS,EAAK,EAG9C,YAAa,QAAM,SAAS,QAAM,OAAQG,EAAmB,EAO7D,gBAAiB,QAAM,SAAS,QAAM,OAAQ,CAAC,EAE/C,mBAAoB,QAAM,MAAM,QAAM,OAAiB,CAAC,CAC1D,CAAC,CACH,EAGC,mBAAmBC,GAAY,CAC9B,GAAM,CACJ,KAAAC,EACA,mBAAoBC,EACpB,iBAAkBC,EAClB,GAAGC,CACL,EAAIJ,EAKJ,GAAI,CAACC,EACH,OAAOG,EAET,GAAM,CAAE,KAAMC,EAAO,GAAGC,CAAM,EAAIL,EAClC,MAAO,CAAE,GAAGK,EAAO,GAAGF,CAAK,CAC7B,CAAC,EACA,SAAS,KAAO,CACf,OAAQ,EAER,cAAe,OACf,MAAO,MACT,EAAE,EACD,MAAMG,IAAS,CACd,IAAI,eAAgB,CAClB,OAAOC,GAAmBD,EAAMA,EAAK,YAAY,aAAa,CAChE,EACA,IAAI,mBAAqC,CACvC,SAAO,YAAQA,EAAM,YAAY,CACnC,EACA,IAAI,oBAAkC,CACpC,SAAO,YAAQA,EAAM,aAAa,CACpC,EAEA,IAAI,yBAA0B,CAC5B,OAAOA,EAAK,eAAiB,QAAaA,EAAK,WACjD,EACA,IAAI,cAAe,CACjB,OAAOA,EAAK,MACd,EACA,IAAI,cAAe,CACjB,OAAOA,EAAK,YAAc,MAC5B,EACA,IAAI,eAAgB,CAClB,OAAO,KAAK,gBACd,EACA,IAAI,kBAAmB,CACrB,OACEA,EAAK,oBACLE,GAAWF,EAAK,YAAY,aAAa,CAE7C,EAGA,IAAI,oBAAqB,CAGvB,IAAMG,EAFSH,EAAK,cAAc,QAEZ,aACtB,OAAO,OAAOG,GAAU,SAAWA,EAAQ,MAC7C,CACF,EAAE,EACD,MAAMH,IAAS,CACd,OAAOI,EAA+B,CACpC,IAAMD,EAAQH,EAAK,mBACnB,OAAOG,IAAU,QAAaC,EAAUD,EAAQ,SAAW,MAC7D,EACA,OAAOE,EAAoB,CACzB,OAAOA,IAAS,SAAW,IAAWL,EAAK,WAC7C,EACA,IAAI,SAAwB,CAC1B,OAAOA,EAAK,WAAaA,EAAK,qBAAuB,OACjD,SACA,MACN,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,cAAe,CACjB,IAAMM,EAAON,EAAK,cAClB,OAAOM,EAAON,EAAK,OAAOA,EAAK,OAAOM,EAAK,OAAO,CAAC,EAAI,GACzD,CACF,EAAE,EACD,MAAMN,IAAS,CACd,IAAI,gBAAiB,CACnB,IAAMM,EAAON,EAAK,cAClB,OAAOM,IAAS,QAAaA,EAAK,IAAMA,EAAK,MAAQN,EAAK,YAC5D,EACA,IAAI,sBAAuB,CACzB,IAAMM,EAAON,EAAK,cAClB,OAAOM,EACH,qCAAqCC,GAAaD,EAAK,IAAMA,EAAK,KAAK,CAAC,SAASC,GAAaP,EAAK,YAAY,CAAC,IAChH,EACN,EACA,IAAI,oBAAqB,CACvB,MAAO,EACT,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAK,YACd,CACF,EAAE,EACD,MAAMA,IAAS,CAKd,IAAI,cAAmC,CACrC,SAAO,8BACL,CACE,eAAgBA,EAAK,eACrB,MAAOA,EAAK,OAASA,EAAK,WAC5B,EACA,OACE,yBACE,CACE,YAAaA,EAAK,YAClB,WAAY,GACZ,cACEA,EAAK,MAAM,cAAgB,IAC3BA,EAAK,KAAK,oBAAsB,GAClC,UAAWA,EAAK,WAAa,CAACA,EAAK,SACnC,cAAeA,EAAK,aACpB,sBAAuB,GACvB,cAAe,GACf,YAAaA,EAAK,SAAWA,EAAK,eACpC,EACA,IAAM,GACN,IAAMA,EAAK,MAAM,sBAAwB,EAC3C,CACJ,CACF,CACF,EAAE,EACD,QAAQA,IAAS,CAEhB,mBAAmBQ,EAAc,CAC/BR,EAAK,gBAAkBQ,CACzB,EACA,sBAAsBC,EAAkC,CACtDT,EAAK,mBAAqBS,EAC1BT,EAAK,MAAQ,MACf,EACA,SAASU,EAAiC,CACxCV,EAAK,MAAQU,CACf,EACA,eAAeC,EAAY,CACzBX,EAAK,YAAcW,CACrB,EAIA,KAAM,CACJ,IAAMC,EAASZ,EAAK,UACpB,GAAI,CAACY,EACH,OAEF,IAAMC,EAAUC,GACdC,GAAuBf,EAAK,YAAY,aAAa,EACrDY,EAAO,YACT,EACA,GAAIC,EAAS,CACXb,EAAK,WAAW,EAChBA,EAAK,SAAS,IAAI,MAAMa,CAAO,CAAC,EAChC,MACF,CACA,IAAMG,EAAShB,EAAK,UAAY,SAChC,OAAOA,EAAK,YAAYA,EAAK,cAAeY,EAAQ,CAClD,KAAMI,EAAS,EAAIhB,EAAK,gBACxB,WAAYA,EAAK,iBACjB,KAAMgB,EAAS,SAAW,OAC1B,GAAIC,EAAkBjB,EAAK,gBAAgB,EAAE,WACzC,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CACH,CACF,EAAE,EACD,QAAQA,IAAS,CAChB,QAAQM,EAAkB,CACxB,IAAMD,EAAOL,EAAK,OAAOM,EAAK,OAAO,EACrC,OAAAN,EAAK,UAAYK,IAAS,SAC1BL,EAAK,UAAYkB,GACfZ,EACAN,EAAK,OAAOK,CAAI,EAChBY,EAAkBjB,EAAK,gBAAgB,EAAE,UAC3C,EACAA,EAAK,SACEA,EAAK,IAAI,CAClB,CACF,EAAE,EACD,QAAQA,IAAS,CAOhB,SAASM,EAA2B,CAClCN,EAAK,cAAgBM,EACrB,IAAMa,EAAUF,EAAkBjB,EAAK,gBAAgB,EAAE,WACzD,OACEA,EAAK,gBACLoB,GAAYpB,EAAK,MAAOM,CAAI,GAC3B,CAACN,EAAK,cACLA,EAAK,OAAOM,EAAK,OAAO,IAAMN,EAAK,SACnCqB,GAASrB,EAAK,UAAWM,EAAMa,CAAO,EAEjC,IAIJ,QAAQ,QAAQnB,EAAK,QAAQM,CAAI,CAAC,EAAE,KAAK,IAAM,IAC9C,WAAQN,CAAI,GAAKsB,GAAiBtB,EAAK,KAAK,GAC9C,KAAK,eAAeM,CAAI,CAE5B,CAAC,EACM,GACT,EAGA,eAAeA,EAAkB,CAC/BN,EAAK,SAASM,CAAI,EAClBN,EAAK,UAAY,OACjB,KAAK,SAASA,EAAK,eAAiBM,CAAI,CAC1C,EACA,aAAaiB,EAAuB,CAClC,IAAMC,EAAOP,EAAkBjB,EAAK,gBAAgB,EACpDA,EAAK,cAAcuB,CAAI,EACvB,IAAME,EAAKR,EAAkBM,CAAI,EAC3BjB,EAAON,EAAK,KAAO0B,GAAW1B,EAAK,IAAI,EAAI,OACjD,OACEM,GACA,CAACN,EAAK,iBACLyB,EAAG,aAAeD,EAAK,YACtBC,EAAG,aAAeD,EAAK,YAElBxB,EAAK,QAAQM,CAAI,EAEnBN,EAAK,gBAAgB,CAC9B,EACA,WAAY,CACLA,EAAK,IAAI,CAChB,EACA,QAAS,CACFA,EAAK,IAAI,CAChB,EACA,mBAAoB,CAClBA,EAAK,SAAS,CAChB,CACF,EAAE,EACD,QAAQA,IAAS,CAChB,WAAY,CACV,IAAMM,EAAON,EAAK,cACdM,IACFN,EAAK,eAAe,KAAK,KAAKM,EAAK,IAAMA,EAAK,KAAK,CAAC,EACpDN,EAAK,SAASM,CAAI,EAEtB,EAIA,aAAc,CACRN,EAAK,WAAa,CAACA,EAAK,OACrBA,EAAK,IAAI,KAEhB,eACEA,KACA,aACE,IAAMA,EAAK,YACX2B,GAAU,CACHA,GACH3B,EAAK,YAAY,CAErB,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACEA,KACA,aACE,IAAMA,EAAK,UACX4B,GAAS,CACHA,GACF5B,EAAK,cAAc4B,EAAM,MAAOA,EAAM,UAAU,CAEpD,EACA,CACE,OAAQ,CAACC,EAAGC,IACVD,GAAG,QAAUC,GAAG,OAASD,GAAG,aAAeC,GAAG,WAChD,gBAAiB,GACjB,KAAM,gBACR,CACF,CACF,KAIA,eACE9B,KACA,aACE,IAAM,GAAGA,EAAK,MAAM,KAAK,IAAIA,EAAK,gBAAgB,KAAK,GACvD,IAAM,CACJ,IAAM+B,EAAQ/B,EAAK,YAAYA,EAAK,WAAW,GAAG,OAAS,GACtDA,EAAK,WAAW,OAAS,GAAKA,EAAK,QACtCA,EAAK,UAAU,KAAK,IAAIA,EAAK,OAAQ,KAAK,KAAK+B,CAAK,CAAC,CAAC,CAE1D,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACE/B,KACA,aACE,IAAMA,EAAK,MAAM,oBACjBgC,GAAU,CACR,GAAM,CAAE,KAAAC,CAAK,EAAIjC,EACXM,EAAO0B,GAAUC,EAAOP,GAAWO,CAAI,EAAI,OAC7C3B,GACFN,EAAK,SAASM,CAAI,CAEtB,EACA,CAAE,gBAAiB,GAAM,KAAM,iBAAkB,CACnD,CACF,CACF,CACF,EAAE,EACD,MAAMN,IAAS,CAId,IAAI,eAAgB,CAClB,IAAMM,EAAON,EAAK,KAAO0B,GAAW1B,EAAK,IAAI,EAAI,OAC3CkC,EAAUlC,EAAK,cACrB,GACE,CAACM,GACD,CAAC4B,GACD,CAAClC,EAAK,UACNA,EAAK,WACLA,EAAK,eAEL,OAEF,IAAMmC,EAAQ,KAAK,MAAM7B,EAAK,KAAK,EAC7B8B,EAAM,KAAK,KAAK9B,EAAK,GAAG,EAC9B,MAAO,CACL,cAAe4B,EACf,aAAc,CACZ,QAAS5B,EAAK,QACd,aAAcA,EAAK,aACnB,MAAA6B,EACA,IAAAC,CACF,EACA,gBAAiBpC,EAAK,gBACtB,mBAAoBA,EAAK,iBACzB,YAAa,KAAK,IAAIA,EAAK,YAAaoC,EAAMD,CAAK,EACnD,WAAYnC,EAAK,iBACjB,YAAaA,EAAK,kBAClB,cAAeA,EAAK,cACpB,YAAaA,EAAK,YAClB,UAAWA,EAAK,UAChB,YAAaA,EAAK,YAClB,kBAAmBA,EAAK,kBACxB,WAAYA,EAAK,WACjB,SAAO,eAAYA,EAAK,KAAK,CAC/B,CACF,CACF,EAAE,EACD,QAAQA,IAAS,CAChB,eAAgB,CACd,IAAMqC,EAAOrC,EAAK,cACdqC,MACF,eAAWrC,CAAI,EAAE,QAAQ,kBAAmBqC,CAAI,CAEpD,CACF,EAAE,EACD,MAAMrC,IAAS,CAGd,oBAAiC,CAC/B,GAAIA,EAAK,cAAc,OAAS,wBAC9B,MAAO,CAAC,EAEV,IAAMsC,EAAQpC,GAAWF,EAAK,YAAY,aAAa,EACjDuC,EAASvC,EAAK,mBACdwC,EAAS/B,GAAqC,CAClDT,EAAK,sBAAsBS,CAAU,EAChCT,EAAK,IAAI,CAChB,EACA,MAAO,CACL,CACE,MAAO,aACP,QAAS,CACP,CACE,KAAM,QACN,MAAO,+BACP,QAASuC,EAASA,EAAO,SAAW,EAAI,CAACD,EACzC,QAAS,IAAM,CACbE,EAAM,CAAC,CAAC,CACV,CACF,EACA,GAAIF,EACA,CACE,CACE,KAAM,QACN,MAAO,eAAeA,EAAM,MAAM,cAClC,QAASC,IAAW,OACpB,QAAS,IAAM,CACbC,EAAM,MAAS,CACjB,CACF,CACF,EACA,CAAC,EACL,CACE,KAAM,QACN,MAAO,wBACP,SAAUD,GAAQ,QAAU,GAAK,EACjC,QAAS,IAAM,CACb,KAAK,aAAa,CACpB,CACF,CACF,CACF,CACF,CACF,EACA,cAAe,IACb,eAAWvC,CAAI,EAAE,YAAYyC,GAAW,CACtCtD,GACA,CAAE,MAAOa,EAAM,KAAM,GAAM,QAAAyC,CAAQ,CACrC,CAAC,CACH,EACA,gBAA6B,CAC3B,IAAMC,EAAW1C,EAAK,gBAAgB,EACtC,oCAAuB0C,EAAU,CAC/B,MAAO,oBACP,KAAMC,GACN,SAAU,CAAC3C,EAAK,cAChB,iBAAkB,uCAClB,QAAS,IAAM,CACbA,EAAK,cAAc,CACrB,CACF,CAAC,EACM,CACL,GAAG,KAAK,mBAAmB,EAC3B,GAAGA,EAAK,eAAe,EACvB,CACE,MAAO,WACP,KAAM4C,GACN,QAAS,IAAM,CACb,KAAK,aAAa,CACpB,CACF,EACA,GAAGF,CACL,CACF,CACF,EAAE,CAER,CF1hBe,SAARG,GAAqCC,EAA8B,CACxEA,EAAc,eAAe,IAAM,CACjC,IAAMC,EAAeC,GAAoB,EACzC,OAAO,OAAO,OACZ,IAAI,GAAAC,QAAY,CACd,KAAM,qBACN,YAAa,QACb,aAAAF,EACA,WAAYG,GAAkBH,CAAY,EAG1C,UAAW,CAAC,aAAc,eAAgB,cAAc,EACxD,SAAU,mBACV,kBAAgB,SAAK,IAAM,OAAO,yCAAiC,CAAC,CACtE,CAAC,EACD,CAAE,oBAAqB,CAAC,aAAa,CAAE,CACzC,CACF,CAAC,CACH,CI3BA,IAAAI,GAAwB,UCAxB,IAAAC,GAAoC,SACpCC,GAAsB,UAyBf,SAASC,GAAkBC,EAA+B,CAC/D,GAAM,CAAE,IAAAC,EAAK,QAAAC,EAAS,IAAAC,CAAI,EAAIH,EAC9B,OAAO,OAAOC,GAAQ,SAClB,CACE,GAAGD,EACH,gBAAiB,CAAE,IAAAC,EAAK,QAAAC,CAAQ,EAChC,MAAO,CACL,UAAWC,EAAM,MAAQ,MACzB,SAAU,CAAE,IAAK,GAAGF,CAAG,IAAIE,EAAM,MAAQ,KAAK,GAAI,QAAAD,CAAQ,CAC5D,CACF,EACAF,CACN,CAEA,IAAMI,MAAyB,wBAC7B,yBACA,CAIE,gBAAiB,CACf,KAAM,eACN,aAAc,CACZ,IAAK,2BACL,aAAc,aAChB,CACF,EAIA,SAAO,wBAAoB,uBAAwB,CAIjD,UAAW,CACT,MAAO,SAAM,YAAY,YAAa,CAAC,MAAO,KAAK,CAAC,EACpD,KAAM,aACN,aAAc,KAChB,EAIA,SAAU,CACR,KAAM,eACN,aAAc,CACZ,IAAK,+BACL,aAAc,aAChB,CACF,CACF,CAAC,EASD,oBAAqB,CACnB,KAAM,SACN,aAAc,CAAC,CACjB,CACF,EACA,CACE,gBAAiB,GAUjB,mBAAoBL,EACtB,CACF,EAMOM,GAAQD,GDtGA,SAARE,GAAyCC,EAA8B,CAC5EA,EAAc,eACZ,IACE,IAAI,GAAAC,QAAY,CACd,KAAM,yBACN,YAAa,+BACb,kBAAAC,GACA,aAAAC,GACA,gBAAiB,CACf,SAAU,gBACZ,EACA,gBAAiB,IACf,OAAO,6CAA6B,EAAE,KAAKC,GAAKA,EAAE,OAAO,CAC7D,CAAC,CACL,CACF,CErBA,IAAAC,GAAwB,UCAxB,IAAAC,GAAoC,SACpCC,GAAsB,UA6BtB,SAASC,GAAIC,EAAaC,EAAkBC,EAAc,CACxD,MAAO,CACL,UAAWA,EAAM,MAAQ,MACzB,SAAU,CAAE,IAAK,GAAGF,CAAG,IAAIE,EAAM,MAAQ,KAAK,GAAI,QAAAD,CAAQ,CAC5D,CACF,CAEA,SAASE,GAAgBC,EAA+B,CACtD,GAAM,CAAE,IAAAJ,EAAK,QAAAC,EAAS,IAAAC,CAAI,EAAIE,EAC9B,OAAO,OAAOJ,GAAQ,SAClB,CACE,GAAGI,EACH,iBAAkB,CAAE,IAAK,GAAGJ,CAAG,eAAgB,QAAAC,CAAQ,EACvD,cAAeF,GAAI,GAAGC,CAAG,eAAgBC,EAASC,CAAG,EACrD,cAAe,CAAE,IAAK,GAAGF,CAAG,gBAAiB,QAAAC,CAAQ,EACrD,WAAYF,GAAI,GAAGC,CAAG,gBAAiBC,EAASC,CAAG,CACrD,EACAE,CACN,CAEO,SAASC,GAAkBD,EAA+B,CAC/D,GAAM,CAAE,OAAAE,EAAQ,QAAAL,CAAQ,EAAIG,EAC5B,OAAOD,GACL,OAAOG,GAAW,UAAYA,IAAW,KACrC,CAAE,GAAGF,EAAM,OAAQD,GAAgB,CAAE,QAAAF,EAAS,GAAGK,CAAO,CAAC,CAAE,EAC3DF,CACN,CACF,CAEA,IAAMG,GAAc,CAACC,EAAcC,OACjC,wBAAoBD,EAAM,CAIxB,UAAW,CACT,MAAO,SAAM,YAAY,YAAa,CAAC,MAAO,KAAK,CAAC,EACpD,KAAM,aACN,aAAc,KAChB,EAIA,SAAU,CACR,KAAM,eACN,aAAc,CAAE,IAAKC,EAAY,aAAc,aAAc,CAC/D,CACF,CAAC,EAEGC,MAAsB,wBAAoB,sBAAuB,CASrE,aAAc,CAAE,KAAM,aAAc,EAIpC,iBAAkB,CAChB,KAAM,eACN,aAAc,CACZ,IAAK,kCACL,aAAc,aAChB,CACF,EAIA,cAAeH,GACb,0BACA,qCACF,EAIA,cAAe,CACb,KAAM,eACN,aAAc,CACZ,IAAK,mCACL,aAAc,aAChB,CACF,EAIA,WAAYA,GACV,uBACA,sCACF,CACF,CAAC,EAEKI,MAAmB,wBACvB,mBACA,CAME,iBAAkB,CAChB,KAAM,eACN,aAAc,CACZ,IAAK,6BACL,aAAc,aAChB,CACF,EAIA,cAAeJ,GACb,oBACA,gCACF,EAMA,cAAe,CACb,KAAM,eACN,aAAc,CACZ,IAAK,8BACL,aAAc,aAChB,CACF,EAIA,WAAYA,GACV,iBACA,iCACF,EAcA,oBAAqB,CACnB,KAAM,SACN,aAAc,CAAC,CACjB,EAQA,OAAQG,EACV,EACA,CACE,gBAAiB,GAUjB,mBAAoBL,EACtB,CACF,EAIOO,GAAQD,GD1MA,SAARE,GAAmCC,EAA8B,CACtEA,EAAc,eACZ,IACE,IAAI,GAAAC,QAAY,CACd,KAAM,mBACN,YAAa,uBACb,kBAAAC,GACA,aAAAC,GAEA,oBAAqB,CAAC,aAAa,EACnC,gBAAiB,CACf,SAAU,gBACZ,EACA,gBAAiB,IACf,OAAO,uCAAuB,EAAE,KAAKC,GAAKA,EAAE,OAAO,CACvD,CAAC,CACL,CACF,CELA,IAAMC,GAAiB,IAAI,IAAI,CAAC,mBAAoB,uBAAuB,CAAC,EAErE,SAASC,GAAcC,EAAmB,CAC/C,OAAOC,GAAaD,CAAG,EAAE,YAAY,EAAE,SAAS,SAAS,CAC3D,CAIO,SAASE,GAAcC,EAA2B,CACvD,IAAMC,EAAUD,EAAK,QAErB,OAAOC,GAAS,OAAS,yBACvB,CAACA,EAAQ,eAAe,QACxB,MAAM,QAAQD,EAAK,aAAa,GAChCA,EAAK,cAAc,OAAS,EAC1B,CAAE,GAAGA,EAAM,QAAS,CAAE,GAAGC,EAAS,cAAeD,EAAK,aAAc,CAAE,EACtEA,CACN,CAEO,SAASE,GACdC,EACAC,EACAC,EACA,CACA,IACG,CAACA,GAAeA,IAAgB,0BACjCT,GAAcO,CAAI,EAElB,MAAO,CACL,KAAM,wBACN,cAAeA,EACf,GAAIC,EAAQ,CAAE,uBAAwBA,CAAM,EAAI,CAAC,CACnD,EAEF,IACG,CAACC,GAAeA,IAAgB,qBACjCC,GAAmBH,CAAI,EAEvB,OAAOI,GAAmB,CACxB,OAAQ,mBACR,IAAKJ,EACL,SAAUC,EACV,SAAU,GACV,OAAQ,EACV,CAAC,CAGL,CAEe,SAARI,GAAqCC,EAA8B,CACxEA,EAAc,oBAAoB,6BAA8BV,EAAa,EAC7EU,EAAc,oBACZ,+BACCC,GACC,CAACP,EAAMC,EAAOC,IACZH,GAAkBC,EAAMC,EAAOC,CAAW,GAC1CK,EAAKP,EAAMC,EAAOC,CAAW,CACnC,EACAI,EAAc,oBACZ,iCACCC,GACC,CAACC,EAAaR,IACZR,GAAe,IAAIgB,CAAW,EAC1B,aACAD,EAAKC,EAAaR,CAAI,CAChC,CACF,CCpFA,IAAAS,GAA2B,UAC3BC,GAAsB,UACtBC,GAAyB,UACzBC,GAA2B,UCY3B,SAASC,GAAWC,EAA6C,CAC/D,IAAIC,EACJ,GAAIC,EAASF,CAAK,EAAG,CACnB,GAAM,CAAE,QAAAG,EAAS,MAAAC,EAAO,IAAAC,EAAK,aAAAC,CAAa,EAAIN,EAE5C,OAAOG,GAAY,UACnB,OAAOC,GAAU,UACjB,OAAOC,GAAQ,WAEfJ,EAAS,CACP,QAAAE,EACA,MAAAC,EACA,IAAAC,EACA,aACE,OAAOC,GAAiB,SAAWA,EAAe,MACtD,EAEJ,CACA,OAAOL,CACT,CAWA,SAASM,GACPC,EACAC,EACAC,EACA,CACA,IAAMC,EAAkBH,EAAK,gBAC7B,OACEG,IAAoB,QACpBA,IAAoBF,GACpB,CAACC,EAAY,IAAIC,CAAe,CAEpC,CAkBA,SAASC,GACPX,EACAY,EACA,CACA,OACEZ,EAAO,eAAiB,QACxBY,IAAkB,QAClBA,EAAc,SAASZ,EAAO,YAAY,CAE9C,CAIA,SAASa,GAAYN,EAA+B,CAElD,OADe,MAAM,QAAQA,EAAK,MAAM,EAAIA,EAAK,OAAS,CAAC,GAC7C,QAASO,GACrBb,EAASa,CAAK,GAAK,MAAM,QAAQA,EAAM,QAAQ,EAC3CA,EAAM,SAAS,OACZC,GACCd,EAASc,CAAO,GAAKA,EAAQ,OAAS,oBAC1C,EACA,CAAC,CACP,CACF,CAKO,SAASC,GACdC,EACAT,EAGAU,EACsB,CACtB,IAAMC,EAAmC,CAAC,EACpCC,EAAaC,GAASJ,CAAK,EAC3BR,EAAc,IAAI,IACtBW,EAAW,IAAIb,GAASN,EAASM,CAAI,EAAIA,EAAK,GAAK,MAAU,CAC/D,EACA,QAAWA,KAAQa,EAAY,CAC7B,GAAInB,EAASM,CAAI,GAAKA,EAAK,KAAOC,EAChC,QAAWO,KAAWF,GAAYN,CAAI,EAAG,CACvC,IAAMP,EAASF,GAAWiB,EAAQ,cAAc,EAC5Cf,GAAUW,GAAaX,EAAQkB,CAAmB,GACpDC,EAAW,KAAK,CACd,IAAK,OAAOJ,EAAQ,IAAO,SAAWA,EAAQ,GAAK,cACnD,OAAAf,CACF,CAAC,CAEL,CAEF,GACEC,EAASM,CAAI,GACbA,EAAK,OAAS,mBACdD,GAAYC,EAAMC,EAAcC,CAAW,EAC3C,CACA,IAAMT,EAASF,GAAWS,EAAK,cAAc,EACzCP,GAAUW,GAAaX,EAAQkB,CAAmB,GACpDC,EAAW,KAAK,CACd,IAAK,OAAOZ,EAAK,IAAO,SAAWA,EAAK,GAAK,QAC7C,OAAAP,CACF,CAAC,CAEL,CACF,CACA,OAAOmB,CACT,CDzGI,IAAAG,GAAA,UA1BEC,MAAY,eAAW,EAAEC,IAAU,CACvC,UAAW,CACT,OAAQ,OACR,SAAU,WACV,cAAY,UAAMA,EAAM,QAAQ,QAAQ,KAAM,GAAI,EAClD,WAAY,aAAaA,EAAM,QAAQ,QAAQ,IAAI,GACnD,YAAa,aAAaA,EAAM,QAAQ,QAAQ,IAAI,GACpD,cAAe,OACf,OAAQ,EACV,CACF,EAAE,EAMIC,MAAY,aAAS,SAAmB,CAC5C,MAAAC,EACA,OAAAC,CACF,EAGG,CACD,GAAM,CAAE,QAAAC,CAAQ,EAAIL,GAAU,EACxBM,EAASH,EAAM,mBAAmBC,CAAM,EAC9C,OAAOE,KACL,QAAC,OACC,cAAY,uBACZ,UAAWD,EAAQ,UACnB,MAAO,CAAE,KAAMC,EAAO,KAAM,MAAOA,EAAO,KAAM,EAClD,EACE,IACN,CAAC,EAEKC,MAAqB,aAAS,SAA4B,CAC9D,MAAAJ,CACF,EAEG,CACD,GAAM,CAAE,MAAAK,CAAM,KAAI,eAAWL,CAAK,EAClC,SACE,qBACG,SAAAM,GAAoB,CAAC,GAAGD,CAAK,EAAGL,EAAM,GAAIA,EAAM,aAAa,EAAE,IAC9D,CAAC,CAAE,IAAAO,EAAK,OAAAN,CAAO,OACb,QAACF,GAAA,CAAqC,MAAOC,EAAO,OAAQC,GAA5C,eAAeM,CAAG,EAAkC,CAExE,EACF,CAEJ,CAAC,EAEMC,GAAQJ,GE7CX,IAAAK,GAAA,UAJEC,GAAQ,4CAEC,SAARC,GAAiCC,EAA8B,CACpEA,EAAc,2BAA2BF,GAAO,CAAC,CAAE,MAAAG,CAAM,OACvD,QAACC,GAAA,CAAyD,MAAOD,GAAzC,iCAAgD,CACzE,CACH,CClBA,IAAAE,GAA4B,UAU5B,SAASC,GAAuBC,EAAsB,CACpD,OAAOA,EAAM,MAAMC,IAAS,CAC1B,IAAI,eAAyC,CAC3C,OAAOC,GAAmBD,EAAMA,EAAK,YAAY,aAAa,CAChE,CACF,EAAE,CACJ,CAEe,SAARE,GAA+BC,EAA8B,CAClEA,EAAc,oBAAoB,8BAA+BC,IAE7DA,aAAmB,gBACnBC,GAAiB,SAASD,EAAQ,IAAI,GAEtCA,EAAQ,iBAAiBN,EAAsB,EAE1CM,EACR,CACH,CC1BO,IAAME,GAAc,kBCFpB,IAAMC,GAAU,Q5EwBvB,IAAqBC,GAArB,cAAmD,GAAAC,OAAO,CAA1D,kCACE,UAAOC,GACP,aAAUC,GAEV,QAAQC,EAA8B,CACpCC,GAAiBD,CAAa,EAC9BE,GAAoBF,CAAa,EACjCG,GAAYH,CAAa,EACzBI,GAAuBJ,CAAa,EACpCK,GAAgBL,CAAa,EAC7BM,GAAkBN,CAAa,EAC/BO,GAAwBP,CAAa,EACrCQ,GAAuBR,CAAa,EACpCS,GAAuBT,CAAa,EACpCU,GAAoBV,CAAa,EACjCW,GAAcX,CAAa,EAC3BA,EAAc,aAAa,IAAM,IAAIY,GAAmBZ,CAAa,CAAC,EACtEA,EAAc,aAAa,IAAM,IAAIa,GAAYb,CAAa,CAAC,EAC/DA,EAAc,aAAa,IAAM,IAAIc,GAAcd,CAAa,CAAC,CACnE,CAMA,UAAUA,EAA8B,CACtC,GAAI,IACE,0BAAsBA,EAAc,SAAS,GAC/CA,EAAc,UAAU,gBAAgB,CAAC,KAAK,EAAG,CAC/C,MAAO,oBACP,KAAMe,GACN,QAAUC,GAAkC,CAC1CA,EAAQ,QAAQ,kBAAmB,CAAC,CAAC,CACvC,CACF,CAAC,CAEL,OAASC,EAAG,CACV,QAAQ,KAAK,qDAAsDA,CAAC,CACtE,CACF,CACF",
6
6
  "names": ["require_Plugin", "__commonJSMin", "exports", "module", "require_AdapterType", "__commonJSMin", "exports", "module", "require_configuration", "__commonJSMin", "exports", "module", "require_dataAdapterCache", "__commonJSMin", "exports", "module", "require_pluggableElementTypes", "__commonJSMin", "exports", "module", "require_ViewType", "__commonJSMin", "exports", "module", "require_withLaunchInput", "__commonJSMin", "exports", "module", "require_models", "__commonJSMin", "exports", "module", "require_RenderLifecycleMixin", "__commonJSMin", "exports", "module", "require_serializableFilterChain", "__commonJSMin", "exports", "module", "require_DisplayType", "__commonJSMin", "exports", "module", "require_trackHeightConfigSchemaFields", "__commonJSMin", "exports", "module", "require_TrackHeightMixin", "__commonJSMin", "exports", "module", "require_displayPhase", "__commonJSMin", "exports", "module", "import_Plugin", "import_util", "import_jsx_runtime", "BubbleChart_default", "_jsx", "import_AdapterType", "import_configuration", "import_mobx_state_tree", "GbzBaseSyntenyAdapter", "GBZ_CUT_DEFAULTS", "snap", "uri", "baseUri", "reads", "configSchema_default", "GbzBaseSyntenyAdapterF", "pluginManager", "AdapterType", "configSchema_default", "r", "import_dataAdapterCache", "import_pluggableElementTypes", "isReadsAdapter", "adapter", "isNamed", "location", "key", "value", "namesReads", "adapterConfig", "GetGraphReads", "args", "nodeNames", "sessionId", "signal", "dataAdapter", "import_dataAdapterCache", "import_pluggableElementTypes", "isSubgraphAdapter", "adapter", "GetSubgraph", "args", "adapterConfig", "region", "sessionId", "opts", "signal", "dataAdapter", "import_react", "import_pluggableElementTypes", "import_mobx_state_tree", "GraphAddTrackWidget", "GraphAddTrackWorkflowF", "pluginManager", "cached", "loadBandage", "mod", "import_pluggableElementTypes", "GraphComputeLayout", "args", "graph", "options", "statusCallback", "module", "loadBandage", "startTime", "result", "duration", "import_react", "import_ViewType", "import_withLaunchInput", "import_models", "import_util", "import_mobx_state_tree", "import_mobx", "import_ui", "import_util", "import_react", "LANE_GAP", "referenceSeeds", "graph", "scaling", "opts", "drawn", "node", "drawnNodeLength", "drawnOf", "id", "backbone", "isBackbone", "a", "b", "seeds", "x", "adjacent", "buildNeighbors", "depth", "queue", "at", "next", "neighbour", "unreached", "seededNodes", "orientToReference", "graph", "positions", "backbone", "node", "isBackbone", "points", "segments", "mid", "weight", "sum", "p", "cx", "cy", "cr", "sxr", "syr", "angle", "c", "s", "out", "id", "x", "y", "below", "above", "parseTag", "tag", "tags", "nameEnd", "typeEnd", "name", "type", "val", "parseTags", "fields", "field", "stableCoordinate", "node", "SN", "SO", "SR", "GT", "LT", "parseWalkBody", "body", "segments", "strand", "start", "push", "end", "i", "ch", "parseGFA", "file", "graph", "rawLine", "line", "rest", "len", "seq", "tagfields", "gfa1", "first", "source", "target", "cigar", "strand1", "strand2", "sample", "hap", "contig", "path", "surveySegments", "gfaGraph", "canonical", "traversals", "claim", "id", "strand", "traverse", "link", "gfaPath", "segment", "walk", "seg", "walkStart", "w", "anchorablePaths", "p", "pathOrigin", "s", "carriedSamples", "gfaNode", "sm", "samples", "positive", "v", "statedDepth", "tags", "length", "count", "makeNode", "depth", "stableCoordinate", "convertGFAToGraph", "name", "nodes", "edges", "nodeId", "segmentId", "paths", "edgeToPathsMap", "edgeKey", "a", "recordPathEdges", "nodeIds", "name2", "i", "key", "edge", "pathIds", "lengths", "n", "anchoring", "surveyPaths", "ROUTE_ID", "ROUTE_FRACTION", "withDeletionRoutes", "graph", "deletions", "dropped", "routes", "d", "edges", "edge", "ei", "id", "fromStrand", "toStrand", "routeNodes", "drawnOf", "opts", "lengths", "n", "skipped", "sum", "id2", "drawn", "takeRoutes", "positions", "nodePositions", "deletionRoutes", "edgeIndex", "route", "loadGraph", "text", "name", "opts", "graph", "anchorGraph", "convertGFAToGraph", "parseGFA", "ENGINE_DEFAULTS", "engineSettingsOf", "s", "COMPONENT_SEPARATION", "engineRequest", "scaling", "settings", "anchored", "isBackbone", "spaced", "seededNodes", "engineKey", "forceLayout", "engine", "spread", "spreadFor", "found", "deletionEdges", "dropped", "closableDeletions", "deletions", "d", "routed", "withDeletionRoutes", "merged", "mergeRuns", "runs", "n", "engineScaling", "layoutScaling", "result", "duration", "routeNodes", "drawnLengthOf", "drawn", "drawnNodeLength", "positions", "splitRuns", "id", "nodePositions", "deletionRoutes", "takeRoutes", "orientToReference", "layoutExtent", "minX", "minY", "maxX", "maxY", "segments", "seg", "FIT_PADDING", "MIN_ZOOM", "MAX_ZOOM", "clampZoom", "zoom", "fittedTranslateY", "bounds", "usableHeight", "yScale", "padTop", "leftoverY", "fitTransform", "paneWidth", "paneHeight", "pixelRows", "minScale", "padLeft", "padRight", "padBottom", "usableWidth", "fitX", "fitY", "scale", "leftoverX", "drawingBounds", "layout", "region", "extent", "DEFAULT_SIZE", "createForceLayoutCache", "size", "caches", "cacheOf", "graph", "cache", "settings", "engine", "key", "engineKey", "hit", "started", "entry", "forceLayout", "r", "from", "to", "axisScaleOf", "scale", "pixelRows", "viewportOf", "t", "axis", "width", "height", "padded", "v", "panes", "w", "h", "contains", "outer", "inner", "zoomAbout", "factor", "centerX", "centerY", "clampZoom", "ratio", "import_mobx_state_tree", "import_RenderLifecycleMixin", "import_mobx_state_tree", "knownOrUnset", "values", "value", "lenientMaybeEnum", "lenientOptionalEnum", "fallback", "MAX_CANVAS_HEIGHT", "MIN_CANVAS_HEIGHT", "PAPER_LIGHT", "PAPER_DARK", "paperCss", "r", "g", "b", "v", "MIN_FIT_TUBE_PX", "TUBE_MAP_MODES", "ChooseSamplesDialog", "ChooseWalksDialog", "WALK_MENU_ITEMS", "facetModel", "snap", "facetSettingOf", "TUBE_MAP_FOLDS", "SEGMENTS_SUFFIX", "bubblePrefix", "adapterConfig", "uri", "HOVER_BRIGHTEN", "SELECT_BRIGHTEN", "VIEWPORT_DEBOUNCE_MS", "VIEWPORT_PANES_BUILT", "WALK_GENE_ROWS", "EMPTY_BATCH", "dependOn", "_values", "MAX_GRAPH_REGION_BP", "formatSpanBp", "bp", "DEFAULT_MAX_GRAPH_NODES", "uriOf", "location", "geometryPainted", "model", "paneViewportOf", "width", "height", "viewportOf", "forceLayouts", "createForceLayoutCache", "paneBase", "lenientMaybeEnum", "LAYOUT_MODE_VALUES", "COLOR_SCHEME_VALUES", "lenientOptionalEnum", "BUBBLE_SPREAD_VALUES", "NODE_WIDTH_VALUES", "groupByOf", "import_util", "import_mobx_state_tree", "import_mobx", "bubbleSubgraph", "graph", "segmentIds", "keep", "nodes", "n", "ids", "lengthOf", "kept", "paths", "p", "first", "id", "nodeIds", "before", "sum", "e", "trimOrigins", "trimToWindow", "graph", "window", "inWindow", "n", "isBackbone", "overlapsWindow", "paths", "spans", "path", "first", "last", "id", "i", "span", "kept", "trimmed", "stretches", "nodeIds", "e", "trimVisits", "trimOrigins", "visits", "nameOf", "cursor", "out", "p", "origin", "pathOrigin", "segment", "list", "key", "at", "visit", "keptVisits", "readWalk", "path", "nodeById", "strands", "visitName", "pathOrigin", "seen", "runs", "open", "gaps", "id", "node", "k", "strand", "canonicalStrand", "gap", "last", "isBackbone", "start", "end", "inverted", "joins", "run", "i", "isSmall", "sigma", "strictlyInside", "cuts", "a", "b", "lo", "hi", "mid", "referenceGaps", "backbone", "prev", "findCuts", "walks", "cut", "bp", "cause", "first", "changed", "sorted", "x", "y", "spans", "g", "r", "mergeReference", "merged", "group", "close", "bp0", "bp1", "name", "coarsenTubeMap", "graph", "paths", "n", "visitStrands", "p", "sortedCuts", "starts", "m", "mergedAt", "members", "coarseOf", "routes", "routeFor", "key", "s", "deviations", "coarsePaths", "pathVisits", "edges", "depth", "steps", "devs", "continuing", "append", "structural", "fold", "home", "i0", "i1", "small", "j", "pos", "visits", "next", "edge", "nodes", "import_configuration", "import_util", "import_io", "import_mobx_state_tree", "import_util", "import_mobx_state_tree", "layoutGeometryInputs", "layout", "drawing", "o", "n", "v", "paint", "css", "m", "opacity", "paintAttrs", "kind", "color", "DOT_PX", "DOT_CELL_PX", "svgCanvas", "width", "height", "out", "subpaths", "start", "x", "y", "s", "reach", "points", "i", "pathData", "dots", "seen", "cell", "ctx", "cx0", "cy0", "cx1", "cy1", "w", "h", "canvas", "genePins", "graph", "genes", "positions", "byRefName", "node", "isAnchored", "refName", "entry", "nodes", "a", "b", "pins", "gene", "onRefName", "parts", "exonsByNode", "nodeIds", "at", "atDistance", "covered", "mid", "reach", "i", "firstNodeAtOrAfter", "nodeStart", "nodeEnd", "line", "nodeParts", "exon", "stretch", "polylineSlice", "svgPath", "pinBp", "distance", "p", "isReference", "graph", "name", "pathOrigin", "piecesOf", "p", "a", "b", "walkHighlight", "pieces", "first", "byId", "n", "edgeAt", "e", "i", "lengthOf", "id", "bpOf", "path", "sum", "bp", "piece", "range", "panSNContig", "span", "nodeIds", "edgeIndexes", "progress", "before", "index", "length", "reference", "referencePieces", "laneColors", "walk", "encoding", "ramp", "colors", "node", "mid", "t", "encodedColor", "reversedNodes", "reversed", "referencePath", "walkPath", "visits", "own", "v", "theirs", "walkLift", "layers", "seen", "lifted", "layer", "picked", "walks", "resolveEncoding", "liftOf", "FACET_COLOR", "facetLifts", "lift", "stated", "l", "w", "version", "FONT", "BAR_PX", "SWATCH_PX", "KEY_GAP_PX", "STRIP_KEY_PX", "FADED", "GENE_INK", "esc", "s", "keySvg", "id", "x", "y", "stops", "label", "after", "under", "opacity", "bar", "fill", "defs", "LABEL_CHAR_PX", "exonKeySvg", "EXON_COLOR", "walkKeySvg", "walk", "reference", "key", "walkKey", "encodingStops", "screenPath", "d", "_", "cmd", "chip", "w", "name", "note", "LABEL_PX", "LABEL_PAD", "figureSvg", "graph", "layout", "o", "width", "room", "region", "rampDomain", "rows", "bounds", "drawingBounds", "walkRowsExtent", "pixelRows", "nodeById", "node", "colorScheme", "resolveColorScheme", "referenceRamp", "computeReferenceRamp", "rampInterval", "drawnDeletions", "deletionDrawing", "deletionEdges", "layers", "walkRamp", "l", "lift", "walkLift", "facet", "facetSettingOf", "panels", "facetLifts", "labels", "walkLabelsOf", "pathLegend", "labelOf", "referenceName", "referenceLabel", "contigThickness", "nodeWidth", "pins", "genePins", "ink", "nodeInk", "masks", "overlays", "highlight", "t", "h", "out", "outlines", "exonOutlineTree", "exonStretches", "serializeEl", "screen", "p", "frame", "pin", "cw", "text", "placeLabels", "geneLabelCandidates", "nodesUnderBox", "occupancy", "pinY", "walkRowsTree", "rowLabels", "walkRowLabels", "sy", "drawing", "fit", "fitTransform", "FACET_PAD_PX", "axis", "axisScaleOf", "canvas", "markup", "svgCanvas", "renderer", "Canvas2DRenderer", "buildGeometry", "layoutGeometryInputs", "parts", "height", "place", "facetCells", "grid", "facetGrid", "panel", "i", "cell", "FACET_GAP_PX", "FACET_TITLE_PX", "push", "walkRowsKeyTree", "walkRowsKey", "rangeText", "header", "usable", "FIT_PADDING", "drawn", "strip", "walkStripFrame", "stripGeneGaps", "walkStripLabelsTree", "metadata", "version", "FIGURE_DEFAULTS", "ENGINE_DEFAULTS", "figureSpecSettings", "s", "defaults", "out", "k", "v", "MAX_GAP_PX", "isReal", "c", "referenceKnots", "columns", "bpToScreen", "real", "first", "screen", "i", "left", "right", "short", "capLeft", "capRight", "fromLeft", "fromRight", "knots", "s0", "s1", "trimLeft", "trimRight", "warpX", "tx", "last", "lo", "hi", "mid", "a", "b", "span", "MIN_TUBE_Y_SCALE", "NODE_BOX_PAD", "squeeze", "drawing", "usableHeight", "minY", "maxY", "h", "tubeMapFrame", "view", "scaleX", "translateX", "translateY", "yScale", "y", "ty", "columns", "knots", "referenceKnots", "bp", "tx", "warpX", "tubeMapNodeAt", "x", "sx", "sy", "hit", "node", "import_configuration", "import_util", "import_mobx", "isLinearHost", "view", "v", "widest", "blocks", "best", "b", "hostFrame", "region", "block", "bpPerPx", "left", "hostWindow", "displayed", "hostCut", "window", "capBp", "margins", "visible", "margin", "start", "end", "over", "cutHolds", "cut", "exact", "import_configuration", "import_util", "WHOLE_FRACTION", "NAMED_WALKS", "MIN_CHIPPED_BP", "bubbleHalos", "graph", "bubbles", "positions", "walkLabel", "name", "repeats", "byName", "n", "halos", "bubble", "parts", "minX", "maxX", "minY", "nodeIds", "ends", "bubbleSegmentIds", "node", "line", "isBackbone", "svgPath", "p", "labelAt", "anchor", "s", "sharing", "route", "id", "routes", "rarest", "at", "far", "d", "routeText", "classifyBubble", "names", "shown", "more", "formatBp", "bubblesFromGraph", "graph", "isBackbone", "byId", "n", "order", "referenceOrder", "indexOf", "id", "i", "reach", "succ", "linked", "e", "a", "lo", "hi", "from", "to", "backbone", "b", "ends", "boundaries", "node", "ia", "ib", "walkIndex", "at", "bubbles", "start", "i0", "end", "i1", "interior", "best", "cur", "t", "add", "prev", "SATURATED_PATH_COUNT", "walked", "walkRoutes", "crossed", "routes", "walksLeave", "refStart", "refEnd", "chain", "chainBroken", "k", "partial", "fallback", "startId", "endId", "seen", "min", "max", "left", "p", "steps", "bp", "key", "route", "tubeMapNodeColors", "graph", "colorScheme", "referenceRamp", "range", "computeColorSchemeRange", "node", "index", "abgrToCssRgba", "getNodeColor", "import_configuration", "import_serializableFilterChain", "import_util", "import_configuration", "import_util", "PANSN_HAPLOTYPE", "withPanSNAliases", "adapterConfig", "assemblies", "explicit", "claimed", "fromAliases", "name", "aliases", "prefix", "alias", "trackAdapterConfig", "node", "track", "conf", "mergedIntervals", "intervals", "out", "iv", "a", "b", "last", "mergeOverlappingByName", "genes", "out", "open", "g", "a", "b", "key", "last", "mergedIntervals", "gene", "import_configuration", "GENE_ADAPTER_TYPES", "GENE_TRACK_HINT", "BED_ADAPTER_TYPES", "pickGeneTrack", "tracks", "named", "t", "candidates", "laneFilters", "view", "trackId", "lane", "WHOLE_SEQUENCE_TYPES", "field", "f", "name", "EXON_PARTS", "exonsOf", "into", "type", "children", "child", "merged", "intervals", "sorted", "a", "b", "out", "iv", "last", "geneModelsFrom", "features", "genes", "start", "end", "exons", "mergeOverlappingByName", "REPEAT_ADAPTER_TYPES", "REPEAT_TRACK_HINT", "pickRepeatTrack", "tracks", "named", "t", "own", "f", "name", "PACKED_NAME", "packedName", "pair", "i", "field", "top", "MOTIF_FIELDS", "PERIOD_FIELDS", "NAME_FIELDS", "first", "names", "value", "one", "IUPAC", "repeatUnitOf", "period", "motif", "numbers", "n", "strings", "text", "TANDEM_REPEAT", "tandemAlleleBp", "alts", "rn", "rus", "rul", "ruc", "rb", "k", "alt", "bp", "known", "j", "unitLength", "count", "runBp", "genotyped", "gt", "alleleBp", "referenceBp", "phased", "index", "callsOf", "samples", "called", "sample", "fields", "reads", "lengths", "calls", "spanOf", "tandem", "start", "end", "svlen", "repeatArraysFrom", "features", "arrays", "unit", "refName", "stated", "a", "b", "withGraphViews", "paneBase", "self", "m", "geometryPainted", "modeUsesLayoutEngine", "n", "paths", "pathLegend", "pathColorsLegible", "graph", "layer", "computeReferenceRamp", "layoutModeByValue", "walk", "layers", "walkLift", "lift", "facetLifts", "panel", "TUBE_MAP_MODES", "domain", "walkLabelsOf", "name", "w", "color", "NO_VALUE_COLOR", "walks", "resolveColorScheme", "bubblesFromGraph", "track", "trackAdapterConfig", "region", "t", "GENE_ADAPTER_TYPES", "REPEAT_ADAPTER_TYPES", "pickRepeatTrack", "pickGeneTrack", "r", "graphBackbone", "walkRows", "assemblyName", "assemblyManager", "assembly", "panSN", "names", "view", "filters", "laneFilters", "SerializableFilterChain", "features", "lane", "geneModelsFrom", "f", "backbone", "geneAssembly", "geneFeatures", "binds", "backboneAssembly", "featuresOnBackbone", "buildNeighbors", "nodeInk", "deletionEdges", "repeat", "bars", "reference", "rows", "withCalls", "location", "metadataColumns", "table", "groupBy", "groupWalkRows", "filterSamples", "dependOn", "positions", "genePins", "bubbleHalos", "axisScaleOf", "deletionDrawing", "ramp", "layout", "drawn", "offReference", "unplaced", "node", "tubeMapNodeColors", "colors", "tubes", "_", "pathGreyCssColor", "hovered", "LIFT_BACKDROP_CSS", "nodeId", "nodeById", "neighbors", "nodeReferenceSpan", "tubeMap", "bubble", "span", "import_configuration", "isRecord", "value", "isLinearView", "view", "isRecord", "withRows", "views", "linearViewTarget", "connectedViewId", "assemblyName", "candidates", "canonicalAssemblyName", "session", "name", "manager", "reportFailure", "what", "launch", "error", "MIN_LAUNCH_SPAN_BP", "paddedLocation", "loc", "minSpan", "pad", "withReferenceRegion", "contributors", "region", "c", "showInLinearView", "location", "assembly", "connectedViewId", "tracks", "existing", "linearViewTarget", "viewId", "locLabel", "locString", "highlightInLinearView", "target", "assemblyNamesOfTrack", "trackId", "track", "t", "names", "n", "launchSyntenyView", "graphTrackId", "graphTrackAssemblies", "aligned", "covered", "panels", "snapshot", "withLaunchViews", "withGraphViews", "self", "graph", "backbone", "backboneNodes", "contributingAssemblies", "backboneSpan", "assemblyManager", "panSN", "byPrefix", "asm", "prefix", "loaded", "name", "sample", "byAssembly", "t", "adapterType", "GENE_ADAPTER_TYPES", "track", "canonicalAssemblyName", "tracks", "picked", "pickGeneTrack", "resolveContributors", "withReferenceRegion", "region", "linearViewTarget", "nodeId", "node", "own", "nodeOwnLocation", "ownAssembly", "resolveLocationAssembly", "nodeById", "neighbors", "span", "nodeReferenceSpan", "onReference", "paddedLocation", "view", "isLinearHost", "withWalkRowViews", "withLaunchViews", "self", "walkStripApplies", "bars", "filterSamples", "walkStripFrame", "cutsWholeWalks", "layoutModeByValue", "id", "node", "stripMarks", "nodeAnchor", "p", "reads", "untrackedRows", "unplaced", "row", "assemblyName", "resolveLocationAssembly", "track", "rowSpan", "WALK_GENE_ROWS", "index", "haplotype", "assembly", "byRow", "placeRowGenes", "withHostViews", "withWalkRowViews", "self", "layoutModeByValue", "host", "region", "b", "graphRegion", "hostFrame", "drawing", "tubeMapPicture", "referenceBoxes", "coarse", "layout", "deviationMarks", "referenceNodes", "reference", "tubeMapGenes", "graph", "referenceStripBlocks", "frame", "left", "right", "stripOverhang", "toScreen", "p", "bubble", "halo", "h", "sameBubble", "nodeId", "span", "nodeAnchor", "sx", "sy", "stripBlockAt", "paperCss", "PAPER_DARK", "PAPER_LIGHT", "REFERENCE_STRIP_ZONE_PX", "walkRowGeneKey", "pitch", "hasGenes", "gaps", "boxesGenes", "withFitViews", "withHostViews", "self", "MIN_CANVAS_HEIGHT", "MAX_CANVAS_HEIGHT", "bars", "room", "headersPx", "SECTION_HEADER_PX", "rowPitch", "FIT_PADDING", "sectionPlacement", "place", "labels", "walkRowLabels", "l", "i", "r", "rowLabelBox", "layout", "rowsExtent", "walkRowsExtent", "drawingBounds", "name", "isReference", "row", "walkRowReadout", "screenX", "screenY", "y", "bp", "rows", "tubeMapGeneRows", "GENE_ROW_PX", "bounds", "width", "height", "base", "across", "padRight", "down", "padTop", "beside", "LEGEND_INSET_PX", "tubePx", "MIN_FIT_TUBE_PX", "field", "domain", "columns", "panels", "facetCells", "p", "facetGrid", "usableWidth", "ceiling", "grid", "floor", "fitTransform", "FACET_PAD_PX", "padded", "paneViewportOf", "VIEWPORT_PANES_BUILT", "b", "hoveredNode", "hoveredEdge", "selectedNode", "nodes", "SELECT_BRIGHTEN", "HOVER_BRIGHTEN", "dpr", "getDpr", "PAPER_DARK", "PAPER_LIGHT", "highlight", "drawPaths", "graph", "nodeById", "layoutResult", "deletionDrawing", "dependOn", "viewportBounds", "buildGeometry", "layoutGeometryInputs", "layoutLabels", "walk", "id", "node", "walkPosition", "region", "adapter", "panSN", "window", "gfa", "uriOf", "db", "source", "lane", "geneTrack", "geneConf", "t", "geneAdapter", "genes", "figureSpecSettings", "layoutModeByValue", "figureSvg", "drawing", "tubeMapFrame", "reference", "rulerBoxes", "picture", "frame", "host", "graphRegion", "hostFrame", "tubeMapConnectors", "reads", "shown", "mismatchesLegible", "m", "mismatchOnScreen", "sx", "sy", "tubeMapNodeAt", "connectorAt", "withSettingActions", "withFitViews", "self", "error", "message", "ms", "strokeCount", "built", "quality", "linear", "mode", "name", "graph", "reanchored", "anchorFromPaths", "forceLayouts", "draw", "show", "scheme", "spread", "width", "bp", "trackId", "key", "layers", "names", "had", "l", "walk", "field", "columns", "color", "px", "samples", "groupBy", "table", "viewId", "paired", "withRows", "view", "nodeId", "walks", "bubble", "inside", "hover", "bars", "frame", "row", "r", "node", "segmentAt", "size", "edgeIdx", "panning", "nodeById", "neighbors", "session", "region", "span", "nodeReferenceSpan", "nodeOwnLocation", "s", "tx", "ty", "host", "clampZoom", "factor", "centerX", "centerY", "t", "zoomAbout", "bounds", "faceted", "pad", "FACET_PAD_PX", "FIT_PADDING", "padTop", "usableHeight", "fittedTranslateY", "fit", "scale", "translateX", "engaging", "scheduleViewportDirty", "VIEWPORT_DEBOUNCE_MS", "requestPositionsDirtyFrame", "dx", "dy", "positions", "seg", "withLoadActions", "withSettingActions", "self", "loadController", "sampleTableKey", "callEngine", "request", "rpcManager", "status", "engineSettings", "engineSettingsOf", "computeLayout", "graph", "start", "tubeMap", "TUBE_MAP_MODES", "region", "drawn", "trimToWindow", "coarse", "coarsenTubeMap", "local", "layoutModeByValue", "settings", "hit", "forceLayouts", "liveRequest", "walkGeneCache", "layoutInto", "isLive", "signal", "computed", "e", "live", "loadedReference", "paths", "assemblyWalk", "chooseReferencePath", "parseAndLayout", "text", "name", "keepSelection", "readsOf", "parsed", "loadGraph", "loaded", "anchorFromPaths", "records", "total", "selected", "liveLoad", "beginLoad", "load", "loadBubbles", "adapterConfig", "prefix", "bubblePrefix", "features", "f", "trackFeatures", "trackId", "what", "session", "config", "t", "loadGenes", "loadRepeats", "repeatArraysFrom", "loadWholeGFA", "source", "abortLoad", "dropGraph", "location", "opts", "fetchStart", "gfaText", "locLabel", "namesReads", "n", "key", "parseSamplesTsv", "reads", "fetched", "row", "cacheKey", "genes", "geneModelsFrom", "g", "bubble", "sub", "bubbleSubgraph", "bubbleSegmentIds", "label", "BUBBLE_KIND_NAMES", "classifyBubble", "from", "isFeatureLike", "value", "isRecord", "hoveredName", "feature", "name", "readLgvHover", "hovered", "result", "refName", "coord", "coord0", "assemblyName", "hoverInRegion", "hover", "region", "nodeForLgvHover", "nodes", "byName", "byCoord", "node", "isBackbone", "PHASED_ROW", "DOTTED_ROW", "readings", "row", "phased", "dotted", "haplotypeOf", "pathName", "pathOrigin", "walksForRow", "paths", "names", "p", "sample", "haplotype", "walks", "name", "panSNSample", "withRenderingActions", "withLoadActions", "self", "backend", "grid", "a", "b", "key", "hover", "readLgvHover", "region", "graph", "inRegion", "hoverInRegion", "rowWalks", "walksForRow", "nodeForLgvHover", "firstViewport", "scale", "viewport", "paneViewportOf", "built", "contains", "dependOn", "EMPTY_BATCH", "geometryStart", "mode", "import_configuration", "ANNOTATION_TRACK_TYPE", "launchTracks", "session", "assemblyName", "first", "found", "track", "type", "assemblyNames", "trackId", "import_configuration", "import_tracks", "import_mobx_state_tree", "SYNTENY_TRACK_TYPE", "SYNTENY_ADAPTER_CATEGORY", "isSyntenyTrack", "track", "adapterType", "pluginManager", "launchableSyntenyTracks", "session", "assemblyNames", "wanted", "found", "trackAssemblies", "trackId", "coverage", "name", "canonicalAssemblyName", "a", "b", "downloadText", "text", "name", "type", "url", "a", "withLaunchActions", "withRenderingActions", "self", "target", "session", "onReference", "viewId", "showInLinearView", "launchTracks", "highlightInLinearView", "trackId", "launchSyntenyView", "samples", "c", "launchableSyntenyTracks", "disagreeing", "shown", "same", "a", "onClose", "ChooseSamplesDialog", "field", "column", "walks", "LAYOUT_MODES", "mode", "COLOR_SCHEMES", "scheme", "FACET_FIELDS", "value", "label", "_", "i", "columns", "WALK_MENU_ITEMS", "ChooseWalksDialog", "walk", "l", "lifted", "WALK_FIELDS", "WALK_SCHEMES", "TUBE_MAP_MODES", "TUBE_MAP_FOLDS", "bp", "key", "name", "unit", "svg", "downloadText", "spec", "e", "items", "item", "graphLaunchMenuItems", "GraphPaneMixin", "withLaunchActions", "import_configuration", "isStringArray", "value", "item", "trackLanes", "track", "assemblyNames", "lanes", "graphReferenceAssembly", "offReferenceProblem", "referenceAssembly", "assemblyName", "fileName", "location", "stateModelFactory", "GraphPaneMixin", "MAX_GRAPH_REGION_BP", "self", "clearPane", "region", "track", "span", "problem", "offReferenceProblem", "graphReferenceAssembly", "formatSpanBp", "trackAdapterConfig", "mode", "before", "layoutModeByValue", "graphLaunchKeys", "GraphGenomeViewF", "pluginManager", "ViewType", "stateModelFactory", "import_configuration", "import_pluggableElementTypes", "SYNTENY_DISPLAYS", "displaysInOrder", "pluginManager", "displays", "named", "name", "d", "needsLanes", "display", "GraphTrackF", "configSchema", "track", "LaunchGraphGenomeViewF", "pluginManager", "args", "session", "spec", "import_react", "import_DisplayType", "import_configuration", "import_trackHeightConfigSchemaFields", "import_mobx_state_tree", "configSchemaFactory", "LAYOUT_MODE_VALUES", "COLOR_SCHEME_VALUES", "import_react", "import_configuration", "import_pluggableElementTypes", "import_ui", "import_util", "import_TrackHeightMixin", "import_mobx_state_tree", "import_displayPhase", "import_mobx", "isNodeLimitError", "error", "denseCovers", "dense", "seen", "span", "GraphTrackSettingsDialog", "stateModelFactory", "configSchema", "TrackHeightMixin", "GraphPaneMixin", "MAX_GRAPH_REGION_BP", "snapshot", "pane", "_rows", "_order", "rest", "_type", "props", "self", "trackAdapterConfig", "trackLanes", "above", "bpPerPx", "tier", "seen", "formatSpanBp", "hops", "haplotypes", "window", "bp", "region", "problem", "offReferenceProblem", "graphReferenceAssembly", "coarse", "layoutModeByValue", "hostCut", "margins", "denseCovers", "cutHolds", "isNodeLimitError", "mode", "from", "to", "hostWindow", "places", "frame", "a", "b", "needs", "blocks", "host", "trackId", "start", "end", "spec", "lanes", "chosen", "recut", "onClose", "launches", "BubbleChart_default", "Settings_default", "LinearGraphDisplayF", "pluginManager", "configSchema", "configSchemaFactory", "DisplayType", "stateModelFactory", "import_AdapterType", "import_configuration", "import_mobx_state_tree", "normalizeSnapshot", "snap", "uri", "baseUri", "csi", "MinigraphBubbleAdapter", "configSchema_default", "MinigraphBubbleAdapterF", "pluginManager", "AdapterType", "normalizeSnapshot", "configSchema_default", "r", "import_AdapterType", "import_configuration", "import_mobx_state_tree", "tbi", "uri", "baseUri", "csi", "prefixLocations", "snap", "normalizeSnapshot", "coarse", "indexSchema", "name", "defaultUri", "RgfaTabixCoarseTier", "RgfaTabixAdapter", "configSchema_default", "RgfaTabixAdapterF", "pluginManager", "AdapterType", "normalizeSnapshot", "configSchema_default", "r", "GRAPH_ADAPTERS", "isGbzLocation", "loc", "locationName", "withGbzAnchor", "snap", "adapter", "guessGraphAdapter", "file", "index", "adapterHint", "isSegmentsLocation", "buildAdapterConfig", "GraphTrackDefaultsF", "pluginManager", "next", "adapterName", "import_util", "import_material", "import_mobx_react", "import_mui", "readRegion", "value", "region", "isRecord", "refName", "start", "end", "assemblyName", "isConnected", "view", "linearViewId", "liveViewIds", "connectedViewId", "isOnAssembly", "assemblyNames", "trackGraphs", "track", "display", "graphViewHighlights", "views", "linearAssemblyNames", "highlights", "candidates", "withRows", "import_jsx_runtime", "useStyles", "theme", "Highlight", "model", "region", "classes", "coords", "GraphNodeHighlight", "views", "graphViewHighlights", "key", "GraphNodeHighlight_default", "import_jsx_runtime", "POINT", "GraphHoverSyncF", "pluginManager", "model", "GraphNodeHighlight_default", "import_pluggableElementTypes", "withTrackAdapterConfig", "model", "self", "trackAdapterConfig", "PanSNAliasesF", "pluginManager", "element", "SYNTENY_DISPLAYS", "PLUGIN_NAME", "version", "GraphGenomeViewPlugin", "Plugin", "PLUGIN_NAME", "version", "pluginManager", "GraphGenomeViewF", "LinearGraphDisplayF", "GraphTrackF", "LaunchGraphGenomeViewF", "GraphHoverSyncF", "RgfaTabixAdapterF", "MinigraphBubbleAdapterF", "GbzBaseSyntenyAdapterF", "GraphAddTrackWorkflowF", "GraphTrackDefaultsF", "PanSNAliasesF", "GraphComputeLayout", "GetSubgraph", "GetGraphReads", "BubbleChart_default", "session", "e"]
7
7
  }