jbrowse-plugin-graphgenomeviewer 6.9.0 → 6.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/LinearGraphDisplay-ZJNR2KCT.js +2 -0
- package/dist/chunks/LinearGraphDisplay-ZJNR2KCT.js.map +7 -0
- package/dist/chunks/RgfaTabixAdapter-KOIMYOR3.js +4 -0
- package/dist/chunks/RgfaTabixAdapter-KOIMYOR3.js.map +7 -0
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +1 -1
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +2 -2
- package/package.json +2 -1
- package/src/LinearGraphDisplay/components/GraphStatusChrome.test.tsx +78 -0
- package/src/LinearGraphDisplay/components/GraphStatusChrome.tsx +104 -0
- package/src/LinearGraphDisplay/components/LinearGraphDisplay.tsx +3 -3
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.test.ts +12 -0
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.ts +52 -21
- package/src/RgfaTabixAdapter/configSchema.ts +12 -9
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.links.bed.gz +0 -0
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.links.bed.gz.tbi +0 -0
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.nodes.bed.gz +0 -0
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.nodes.bed.gz.tbi +0 -0
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.walks.bed.gz +0 -0
- package/src/RgfaTabixAdapter/test_data/walks_maxnode.walks.bed.gz.tbi +0 -0
- package/src/RgfaTabixAdapter/walkFiles.test.ts +90 -0
- package/src/RgfaTabixAdapter/walkRows.test.ts +53 -0
- package/src/RgfaTabixAdapter/walkRows.ts +38 -16
- package/src/version.ts +1 -1
- package/dist/chunks/LinearGraphDisplay-HOS4F4V6.js +0 -2
- package/dist/chunks/LinearGraphDisplay-HOS4F4V6.js.map +0 -7
- package/dist/chunks/RgfaTabixAdapter-JUQ64AJS.js +0 -4
- package/dist/chunks/RgfaTabixAdapter-JUQ64AJS.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["global-externals:@jbrowse/core/Plugin", "global-externals:@jbrowse/core/pluggableElementTypes/AdapterType", "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/core/pluggableElementTypes/renderers/util/serializableFilterChain", "global-externals:@jbrowse/core/pluggableElementTypes/DisplayType", "global-externals:@jbrowse/display-kit/trackHeightConfigSchemaFields", "global-externals:@jbrowse/core/svg/svgReady", "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/GetGraphHaplotypes.ts", "../src/GetGraphReads.ts", "../src/GetSubgraph.ts", "../src/GraphAddTrackWorkflow/index.ts", "../src/GraphComputeLayout.ts", "../src/GraphGenomeView/index.ts", "../src/GraphGenomeView/viewModel.ts", "../src/GraphGenomeView/pane/launchActions.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/ContentCopy.mjs", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Hub.mjs", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Palette.mjs", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/PhotoCamera.mjs", "../src/GraphGenomeView/pane/renderingActions.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-VHW7FDHU.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/layout/trimToWindow.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/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.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-LOCJN3BZ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BUBZ32IC.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-MBB7ATM6.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-XNE4UNSJ.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-H5ABLOPB.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-WC3Y3TD2.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-KQFOCDFY.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/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.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-ISEI2FH3.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-4S47XRYA.js", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-FFFQNQUI.js", "../src/GraphGenomeView/pane/graphViews.ts", "../src/panSNAliases/trackAdapterConfig.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@8.0.2/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/GraphGenomeView/pane/keepInView.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/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/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/core/pluggableElementTypes/renderers/util/serializableFilterChain\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"];", "module.exports = JBrowseExports[\"@jbrowse/core/svg/svgReady\"];", "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 GetGraphHaplotypes from './GetGraphHaplotypes'\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 pluginManager.addRpcMethod(() => new GetGraphHaplotypes(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 { splitUri } from '../locationName'\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...\"). 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 ...readsIndexBeside(reads, baseUri),\n }\n : {}),\n }\n },\n },\n)\n\n// a bgzipped GAF's index, before any query string its url carries\nfunction readsIndexBeside(reads: string, baseUri: unknown) {\n const { name, query } = splitUri(reads)\n return name.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${name}.tbi${query}`, baseUri } } }\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 { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The haplotypes a graph names without a cut, for the track's haplotype picker:\n// a walk-indexed rGFA's header lines. Undefined where the graph names none, and\n// the picker falls back to typed names.\n\nexport interface GetGraphHaplotypesArgs {\n adapterConfig: Record<string, unknown>\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphHaplotypes: {\n args: GetGraphHaplotypesArgs\n return: string[] | undefined\n }\n }\n}\n\ninterface HaplotypeNamesAdapter {\n getHaplotypeNames(opts: {\n signal?: AbortSignal\n }): Promise<string[] | undefined>\n}\n\nfunction namesHaplotypes(adapter: object): adapter is HaplotypeNamesAdapter {\n return (\n 'getHaplotypeNames' in adapter &&\n typeof (adapter as HaplotypeNamesAdapter).getHaplotypeNames === 'function'\n )\n}\n\nexport default class GetGraphHaplotypes extends RpcMethodType<'GetGraphHaplotypes'> {\n name = 'GetGraphHaplotypes' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphHaplotypes'>) {\n const { adapterConfig, sessionId, signal } = args\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n return namesHaplotypes(dataAdapter)\n ? dataAdapter.getHaplotypeNames({ signal })\n : undefined\n }\n}\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 the GBZ cut\n// and a walk-indexed rGFA cut read: they keep those walks, the reference's,\n// 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", "import { layoutEngine } from '@jbrowse/bandage-core/layoutEngines'\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?.('Computing layout')\n return layoutEngine({ graph, options })\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 {\n GraphPaneMixin,\n MAX_GRAPH_REGION_BP,\n fileName,\n formatSpanBp,\n} from './model'\nimport {\n configHaplotypes,\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\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 .volatile(() => ({\n widthMeasured: false,\n }))\n .actions(self => {\n const setBaseWidth = self.setWidth\n return {\n setWidth(width: number) {\n setBaseWidth(width)\n self.widthMeasured = true\n },\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 // until then the width is BaseViewModel's 800 px default\n get paneMeasured() {\n return self.widthMeasured\n },\n // the set stated, else the source track's defaultHaplotypes\n get cutHaplotypes() {\n const track = this.sourceTrack\n return (\n self.subgraphHaplotypes ??\n (track\n ? configHaplotypes(trackAdapterConfig(self, track))\n : undefined)\n )\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.exportMenuItems(), ...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.cutHaplotypes,\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 {\n LAYOUT_MODES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy'\nimport HubIcon from '@mui/icons-material/Hub'\nimport PaletteIcon from '@mui/icons-material/Palette'\nimport PhotoCameraIcon from '@mui/icons-material/PhotoCamera'\nimport VisibilityIcon from '@mui/icons-material/Visibility'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n HighlightColorDialog,\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 { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\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 // 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 // `repeat` false where a toolbar already picks the repeat\n layoutOptionMenuItems({ repeat = true } = {}): MenuItem[] {\n return [\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 ...(repeat &&\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.selectedRepeat,\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...', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ]\n },\n showMenuItems(): MenuItem[] {\n return [\n {\n type: 'checkbox',\n label: 'Show bubble halos',\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: 'Show hover highlight',\n checked: self.chosenHighlightOnHover,\n onClick: () => {\n self.setHighlightOnHover(!self.chosenHighlightOnHover)\n },\n },\n {\n type: 'checkbox',\n label: 'Show genes on the backbone',\n checked: self.showGenes,\n onClick: () => {\n self.setShowGenes(!self.showGenes)\n },\n },\n ...(self.referenceStripApplies\n ? [\n {\n type: 'checkbox' as const,\n label: 'Show reference strip',\n checked: self.showReferenceStrip,\n onClick: () => {\n self.setShowReferenceStrip(!self.showReferenceStrip)\n },\n },\n ]\n : []),\n ]\n },\n exportMenuItems(): MenuItem[] {\n return [\n {\n label: 'Export SVG',\n icon: PhotoCameraIcon,\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 icon: ContentCopyIcon,\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 // `picks` false where a toolbar already picks the walks, leaving what is\n // done with those picked\n highlightMenuItems({ picks = true } = {}): MenuItem[] {\n const walks = picks ? self.walkChoices : []\n if (\n self.walkChoices.length === 0 ||\n !self.liftsWalks ||\n (!picks && self.walkLayers.length === 0)\n ) {\n return []\n }\n const lifted = (name: string) =>\n self.walkLayers.some(l => l.walk === name)\n const many = walks.length > WALK_MENU_ITEMS\n return [\n { type: 'subHeader', label: 'Highlight' },\n ...(many\n ? [\n {\n label: 'Choose haplotypes...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(many ? walks.filter(walk => lifted(walk.name)) : walks).map(\n walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: lifted(walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n }),\n ),\n {\n label: 'Clear highlights',\n disabled: self.walkLayers.length === 0,\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.drawnWalks.length > 0\n ? [\n {\n label: 'Color highlighted...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n HighlightColorDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n { type: 'subHeader' as const, label: 'Arrange' },\n ...FACET_FIELDS.map(({ value, label }) => ({\n type: 'radio' as const,\n label: value === 'walk' ? 'A panel per haplotype' : label,\n checked: self.facet.field === value,\n onClick: () => {\n self.setFacet(value)\n },\n })),\n ]\n : []),\n ]\n },\n colorSchemeLabel(value: ColorScheme): string {\n const label = COLOR_SCHEMES.find(s => s.value === value)?.label ?? value\n return value === 'auto'\n ? `${label} (${this.colorSchemeLabel(self.effectiveColorScheme)})`\n : label\n },\n graphMenuItems(): MenuItem[] {\n const options = this.layoutOptionMenuItems()\n return [\n {\n label: `Layout: ${layoutModeByValue(self.chosenLayoutMode).label.replace(/ layout$/, '')}`,\n icon: HubIcon,\n subMenu: [\n ...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 disabledHelpText: mode.description,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n })),\n ...(options.length > 0\n ? [{ type: 'divider' as const }, ...options]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n { type: 'divider' as const },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.refitView()\n },\n },\n ]),\n ],\n },\n {\n label: `Color: ${this.colorSchemeLabel(self.chosenColorScheme)}`,\n icon: PaletteIcon,\n subMenu: COLOR_SCHEMES.map(scheme => ({\n type: 'radio' as const,\n label: this.colorSchemeLabel(scheme.value),\n checked: self.chosenColorScheme === scheme.value,\n onClick: () => {\n self.setColorScheme(scheme.value)\n },\n })),\n },\n {\n label: 'Show...',\n icon: VisibilityIcon,\n subMenu: this.showMenuItems(),\n },\n ]\n },\n // the graph's way out, in the \"Launch view\" submenu every view shares\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", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z\"\n}), 'ContentCopy');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M8.4 18.2c.38.5.6 1.12.6 1.8 0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3c.44 0 .85.09 1.23.26l1.41-1.77c-.92-1.03-1.29-2.39-1.09-3.69l-2.03-.68c-.54.83-1.46 1.38-2.52 1.38-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3c0 .07 0 .14-.01.21l2.03.68c.64-1.21 1.82-2.09 3.22-2.32V5.91C9.96 5.57 9 4.4 9 3c0-1.66 1.34-3 3-3s3 1.34 3 3c0 1.4-.96 2.57-2.25 2.91v2.16c1.4.23 2.58 1.11 3.22 2.32L18 9.71V9.5c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3c-1.06 0-1.98-.55-2.52-1.37l-2.03.68c.2 1.29-.16 2.65-1.09 3.69l1.41 1.77Q17.34 17 18 17c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3c0-.68.22-1.3.6-1.8l-1.41-1.77c-1.35.75-3.01.76-4.37 0z\"\n}), 'Hub');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c1.38 0 2.5-1.12 2.5-2.5 0-.61-.23-1.2-.64-1.67-.08-.1-.13-.21-.13-.33 0-.28.22-.5.5-.5H16c3.31 0 6-2.69 6-6 0-4.96-4.49-9-10-9m5.5 11c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5m-3-4c-.83 0-1.5-.67-1.5-1.5S13.67 6 14.5 6s1.5.67 1.5 1.5S15.33 9 14.5 9M5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S7.33 13 6.5 13 5 12.33 5 11.5m6-4c0 .83-.67 1.5-1.5 1.5S8 8.33 8 7.5 8.67 6 9.5 6s1.5.67 1.5 1.5\"\n}), 'Palette');", "\"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: \"12\",\n cy: \"12\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 2 7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5\"\n}, \"1\")], 'PhotoCamera');", "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 // A narrower or shorter pane can leave a placed drawing off screen\n addDisposer(\n self,\n reaction(\n () => `${self.viewBox.width} ${self.viewBox.height}`,\n () => {\n self.keepDrawingInView()\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...\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 || 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 {\n TUBE_MAP_MODES,\n bubblePrefix,\n fileName,\n forceLayouts,\n} 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 engine: self.layoutEngine,\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 // the error the last failed layout raised, which the next one to land clears\n let layoutError: unknown\n // the graph the layout on screen was computed for\n let laidOutGraph: Graph | undefined\n // a haplotype's genes by track and contig span\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 the node limit in Settings.`,\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 layoutError = e\n throw e\n }\n const live = isLive()\n if (live) {\n if (layoutError !== undefined && self.error === layoutError) {\n self.error = undefined\n }\n layoutError = undefined\n const previous = self.layoutResult\n laidOutGraph = graph\n self.layoutResult = computed.result\n self.setLayoutMs(computed.duration)\n self.followNewLayout(previous)\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 // against the new graph's own nodes: nodeById reads through the layout,\n // which is still the last graph's\n if (selected !== null && graph.nodes.some(n => n.id === 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 // the load still fetching, parsing or reading annotations, whose spinner a\n // layout of the graph already on screen must not clear\n let loadInFlight: number | undefined\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n loadInFlight = load\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n function endLoad() {\n loadInFlight = undefined\n self.finishLoading()\n }\n\n function layoutSettled() {\n if (loadInFlight === undefined) {\n self.finishLoading()\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 signal?: AbortSignal,\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 signal,\n },\n )) as Feature[]\n if (isLive()) {\n const bubbles = 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 // an open bubble derives its own; the index is the window's\n const [outermost, ...popped] = self.popStack\n if (outermost) {\n self.popStack = [{ ...outermost, indexBubbles: bubbles }, ...popped]\n } else {\n self.indexBubbles = bubbles\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 signal?: AbortSignal,\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 signal,\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(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const features = yield* trackFeatures(\n self.geneTrack?.trackId,\n region,\n 'genes',\n signal,\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(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const features = yield* trackFeatures(\n self.repeatTrack?.trackId,\n region,\n 'repeats',\n signal,\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 endLoad()\n }\n }\n return isLive()\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n loadInFlight = 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 // the next graph has nothing to do with where the user left this one\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\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 // a graph that landed ahead of its layout has nothing of its own drawn\n if (self.graph !== laidOutGraph) {\n self.layoutResult = undefined\n }\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 fileName(location) || 'GFA',\n signal => openLocation(location).readFile({ encoding: 'utf8', signal }),\n region,\n )\n if (region && live && self.graph) {\n const isLive = () => self.graphRegion === region\n yield Promise.all([\n flow(loadGenes)(region, isLive),\n flow(loadRepeats)(region, isLive),\n ])\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, signal),\n flow(loadGenes)(region, isLive, signal),\n flow(loadRepeats)(region, isLive, signal),\n ])\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.cutSubgraph]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n endLoad()\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 self.repeatArrays = undefined\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 self.geneTrackFeatures = undefined\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 self.popStack = [\n ...self.popStack,\n {\n graph,\n layoutMode: self.layoutMode,\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 layoutSettled()\n }\n } catch (e) {\n self.error = e\n layoutSettled()\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 layoutSettled()\n }\n } catch (e) {\n self.error = e\n layoutSettled()\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 layoutSettled()\n }\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n layoutSettled()\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 { keepInView, onScreen } from './keepInView'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\n\nimport type { 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 { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\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 { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withFitViews\n .actions(self => ({\n // A pan or zoom never leaves the drawing wholly off screen, where\n // nothing says which way it went. A host's x is its own.\n keepDrawingInView() {\n const bounds = self.layoutBounds\n const view = self.viewBox\n if (\n !bounds ||\n self.viewportOwner === 'fit' ||\n !self.paneMeasured ||\n view.width <= 0 ||\n view.height <= 0\n ) {\n return\n }\n const t = keepInView(bounds, self, view)\n if (self.viewportOwner !== 'host') {\n self.translateX = t.translateX\n }\n self.translateY = t.translateY\n },\n }))\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 setLayoutEngine(engine: LayoutEngineKind) {\n self.layoutEngine = engine\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.layoutMode = mode\n },\n setHighlightOnHover(highlight: boolean) {\n self.highlightOnHover = highlight\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 setMaxGraphNodes(limit: number) {\n self.maxGraphNodes = limit\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 // 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 self.keepDrawingInView()\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 self.keepDrawingInView()\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 // A new layout under a view the user placed. One that replaces a\n // drawing is fitted unless both are on the reference's bp and some of it\n // is still on screen: a force run or a fresh cut draws in coordinates of\n // its own, where the old transform shows nothing in particular. The\n // first layout after a restored session keeps the saved view, pulled\n // into the pane once its width is known.\n followNewLayout(previous: LayoutResult | undefined) {\n const bounds = self.layoutBounds\n if (\n self.viewportOwner !== 'user' ||\n !bounds ||\n previous === self.layoutResult\n ) {\n return\n }\n const keepsAxis = previous?.referenceAxis === true && self.xIsReferenceBp\n if (\n previous === undefined ||\n (keepsAxis &&\n (!self.paneMeasured || onScreen(bounds, self, self.viewBox)))\n ) {\n self.keepDrawingInView()\n } else {\n self.viewportOwner = 'fit'\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", "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-DPV2CUIE.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.2\";\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-O2ANJQVH.js\";\nimport {\n walkRowsKey,\n walkRowsKeyTree,\n walkRowsTree\n} from \"./chunk-V3MD3IZB.js\";\nimport {\n Canvas2DRenderer\n} from \"./chunk-2WNBVB55.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-MBB7ATM6.js\";\nimport {\n encodingStops\n} from \"./chunk-DPV2CUIE.js\";\nimport {\n rangeText,\n walkKey\n} from \"./chunk-2LQ5BWT7.js\";\nimport {\n buildGeometry,\n computeReferenceRamp\n} from \"./chunk-HBEKUQO4.js\";\nimport {\n version\n} from \"./chunk-XNE4UNSJ.js\";\nimport {\n axisScaleOf\n} from \"./chunk-AO2VAMA4.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-XRPU24OP.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(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\");\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-XRPU24OP.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 { litNode, hoveredEdge, selectedNode } = self\n const nodes = new Map<string, number>()\n if (selectedNode !== null) {\n nodes.set(selectedNode, SELECT_BRIGHTEN)\n }\n if (litNode !== null && litNode !== selectedNode) {\n nodes.set(litNode, HOVER_BRIGHTEN)\n }\n b.setNodeHighlights(nodes)\n b.setEdgeHighlight(\n self.chosenHighlightOnHover ? hoveredEdge : null,\n HOVER_BRIGHTEN,\n )\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 engine: self.layoutEngine,\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... 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 // 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-HBEKUQO4.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-G2FD7S3C.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 get defaultHighlightOnHover(): boolean {\n return true\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 get chosenHighlightOnHover() {\n return self.highlightOnHover ?? self.defaultHighlightOnHover\n },\n // the hovered node, where hovering is to light it\n get litNode() {\n return this.chosenHighlightOnHover ? self.hoveredNode : null\n },\n }))\n .views(self => ({\n get paneWidth() {\n return getContainingView(self).width\n },\n // a linear view knows its width before its tracks draw\n get paneMeasured() {\n return true\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 && !this.geometryPainted))\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 highlighted haplotype colours its own lane: set it under Haplotypes, Color highlighted...',\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 && self.chosenHighlightOnHover\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", "// How much of the drawing a pan or zoom leaves on screen in each axis, or\n// all of it when it is smaller\nexport const KEEP_IN_VIEW_PX = 48\n\n// The shift that brings a span starting at `lo`, `size` px long, back to\n// overlapping [0, extent] by `margin` px\nfunction shiftIntoView(lo: number, size: number, extent: number) {\n const margin = Math.min(KEEP_IN_VIEW_PX, size, extent)\n return Math.max(0, margin - (lo + size)) - Math.max(0, lo - (extent - margin))\n}\n\ninterface DrawingBox {\n minX: number\n minY: number\n w: number\n h: number\n}\n\ninterface Placement {\n scaleX: number\n scaleY: number\n translateX: number\n translateY: number\n}\n\nexport function keepInView(\n bounds: DrawingBox,\n t: Placement,\n view: { width: number; height: number },\n) {\n return {\n translateX:\n t.translateX +\n shiftIntoView(\n bounds.minX * t.scaleX + t.translateX,\n bounds.w * t.scaleX,\n view.width,\n ),\n translateY:\n t.translateY +\n shiftIntoView(\n bounds.minY * t.scaleY + t.translateY,\n bounds.h * t.scaleY,\n view.height,\n ),\n }\n}\n\nexport function onScreen(\n bounds: DrawingBox,\n t: Placement,\n view: { width: number; height: number },\n) {\n const left = bounds.minX * t.scaleX + t.translateX\n const top = bounds.minY * t.scaleY + t.translateY\n return (\n left < view.width &&\n left + bounds.w * t.scaleX > 0 &&\n top < view.height &&\n top + bounds.h * t.scaleY > 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 { canonicalAssemblyName } from './launchFromGraph'\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 wanted = canonicalAssemblyName(session, assemblyName)\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.some(\n name =>\n typeof name === 'string' &&\n canonicalAssemblyName(session, name) === wanted,\n ) &&\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 fileName,\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 { 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 /**\n * #slot\n * whether hovering a node lightens it and bands its span on the view\n */\n highlightOnHover: {\n type: 'boolean',\n defaultValue: true,\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'\nimport type { ReactNode } from 'react'\n\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationReference, getConf } from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { computeSvgReady } from '@jbrowse/core/svg/svgReady'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getRpcSessionId, 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 RouteIcon from '@mui/icons-material/Route'\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 configHaplotypes,\n cutsByHaplotype,\n graphReferenceAssembly,\n offReferenceProblem,\n trackLanes,\n walkIndexed,\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 { ExportSvgDisplayOptions } from '@jbrowse/display-kit/types'\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 or walk-indexed cut is for; unset is the\n // config's defaultHaplotypes, else 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 // the haplotypes a walk-indexed graph's header names, once read\n haplotypeNames: undefined as string[] | 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 get defaultHighlightOnHover(): boolean {\n return getConf(self, 'highlightOnHover')\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 configHaplotypes(this.adapterConfig) ??\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 get svgReady() {\n return computeSvgReady(\n {\n error: self.error,\n regionTooLarge: self.regionTooLarge,\n extraTerminal: false,\n fetchCanceled: self.loadCanceled,\n },\n () => !self.isLoading && self.hasGraph && !!self.layoutResult,\n )\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 setHaplotypeNames(names: string[] | undefined) {\n self.haplotypeNames = names\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 // A failed read leaves the picker taking typed names\n async fetchHaplotypeNames(adapterConfig: Record<string, unknown>) {\n try {\n const names = await getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphHaplotypes',\n { adapterConfig },\n )\n if (isAlive(self)) {\n self.setHaplotypeNames(names)\n }\n } catch (e) {\n console.warn('[LinearGraphDisplay] no haplotype names', e)\n }\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 () =>\n walkIndexed(self.adapterConfig)\n ? self.adapterConfig\n : undefined,\n adapterConfig => {\n self.setHaplotypeNames(undefined)\n if (adapterConfig) {\n void self.fetchHaplotypeNames(adapterConfig)\n }\n },\n { fireImmediately: true, name: 'GraphHaplotypeNames' },\n ),\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 or walk-indexed cut is for: every one in the\n // graph, the config's default set or the assemblies the track names,\n // or a list chosen in Settings\n cutMenuItems(): MenuItem[] {\n if (!cutsByHaplotype(self.adapterConfig)) {\n return []\n }\n const defaults = configHaplotypes(self.adapterConfig)\n const lanes = trackLanes(self.parentTrack.configuration)\n const names = self.haplotypeNames\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n void self.cut()\n }\n return [\n { type: 'subHeader', label: 'Load' },\n {\n type: 'radio',\n label: names\n ? `Every haplotype in the graph (${names.length.toLocaleString()})`\n : 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !defaults && !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(defaults || lanes\n ? [\n {\n type: 'radio' as const,\n label: defaults\n ? \"The track's default haplotypes\"\n : `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 openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, open: true, onClose },\n ])\n },\n async renderSvg(opts?: ExportSvgDisplayOptions): Promise<ReactNode> {\n const { renderGraphTrackSvg } = await import('./renderSvg')\n return renderGraphTrackSvg(\n self as unknown as LinearGraphDisplayModel,\n opts,\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 const haplotypes = [\n ...this.cutMenuItems(),\n ...self.highlightMenuItems(),\n ]\n return [\n ...(haplotypes.length > 0\n ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]\n : []),\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' | 'cutMenuItems' | 'openSettings' | 'renderSvg'\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 GFA | Built by `gfa-to-tabix`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED files, one of a graph's segments and one of its links,\n * written by [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) from an rGFA\n * or from a plain GFA with paths. Both of its layouts are read: `anchored`,\n * where one query per file returns the graph under a region, and `contig`,\n * where the adapter follows links onto other contigs.\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 * `walksUri` takes the prefix `gfa-to-tabix --walks -o <prefix>` was given, in\n * place of `uri`, and resolves `<prefix>.walks.bed.gz`, `<prefix>.nodes.bed.gz`,\n * `<prefix>.links.bed.gz` and their `.tbi` indexes. Such a graph's cut carries\n * the haplotypes' walks, and `defaultHaplotypes` names the ones it is cut for\n * until the user picks others.\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 * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * walksUri: 'https://example.com/hprc-v2.1.chr22',\n * assemblyNameToPanSN: { hg38: 'GRCh38', hs1: 'CHM13' },\n * defaultHaplotypes: ['HG002', 'HG00733', 'HG02257', 'NA19240'],\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\nfunction walksLocations(snap: Record<string, unknown>) {\n const { walksUri, baseUri, csi } = snap\n if (typeof walksUri !== 'string') {\n return snap\n }\n const file = (kind: string) => `${walksUri}.${kind}.bed.gz`\n return {\n ...snap,\n walksLocation: { uri: file('walks'), baseUri },\n walksIndex: tbi(file('walks'), baseUri, csi),\n segmentsLocation: { uri: file('nodes'), baseUri },\n segmentsIndex: tbi(file('nodes'), baseUri, csi),\n linksLocation: { uri: file('links'), baseUri },\n linksIndex: tbi(file('links'), baseUri, csi),\n }\n}\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri, csi } = snap\n return walksLocations(\n prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, csi, ...coarse }) }\n : snap,\n ),\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 * one row per haplotype path per reference chunk, its steps through that\n * chunk, written beside node and link files filed under the same chunks.\n * Unset means the graph has no walks.\n */\n walksLocation: {\n type: 'fileLocation',\n defaultValue: { uri: '', locationType: 'UriLocation' },\n },\n /**\n * #slot\n */\n walksIndex: indexSchema('RgfaWalksIndex', ''),\n /**\n * #slot\n * the reference chunk the walk file's rows are filed under, in bp, when\n * its header has no `chunk:i:` line to say so\n */\n walkChunk: {\n type: 'integer',\n defaultValue: 65536,\n },\n /**\n * #slot\n * the most haplotype steps a cut decodes; a window whose walk rows hold\n * more shows a zoom-in notice instead. Counts only the haplotypes the cut\n * is for, so fewer haplotypes draw a wider window.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: 4_000_000,\n },\n /**\n * #slot\n * the most compressed bytes a cut of a walk-indexed graph fetches from its\n * three files, as their Tabix indexes estimate it before any row is read;\n * a window over it shows a zoom-in notice instead. On HPRC v2.1 chr22 a 1\n * Mb window fetches about 3 to 5 MB, and the dense 64 kb chunks at 11.80 to\n * 12.06 Mb on GRCh38 fetch 15 MB or more for a 10 kb window. The budget\n * covers every haplotype, since node and link rows are filed for all of\n * them.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: 8_000_000,\n },\n /**\n * #slot\n * the haplotypes a walk-indexed graph is cut for until the user picks\n * others in the track's Haplotypes menu or Settings, as PanSN prefixes\n * (`HG002#1`, or `HG002` for both of its haplotypes). Empty means every\n * haplotype, or the lanes the track's `assemblyNames` lists after its\n * reference.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\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 * or, for a graph built by `gfa-to-tabix --walks -o chr22`,\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"walksUri\": \"chr22\" }\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} from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport { locationName } from '../locationName'\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.08),\n borderLeft: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n borderRight: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\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.9.0'\n"],
|
|
5
|
-
"mappings": "47EAAA,IAAAA,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,sBAAsB,ICAtD,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,qCAAqC,ICArE,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oCAAoC,ICApE,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4CAA4C,ICA5E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4EAA4E,ICA5G,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oDAAoD,ICApF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4BAA4B,ICA5D,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,uCAAuC,ICAvE,IAAAC,GAAAC,EAAA,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,UAkCtB,IAAMC,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,GAAGE,GAAiBD,EAAOD,CAAO,CACpC,EACA,CAAC,CACP,CACF,CACF,CACF,EAGA,SAASE,GAAiBD,EAAeD,EAAkB,CACzD,GAAM,CAAE,KAAAG,EAAM,MAAAC,CAAM,EAAIC,GAASJ,CAAK,EACtC,OAAOE,EAAK,SAAS,KAAK,EACtB,CAAE,WAAY,CAAE,SAAU,CAAE,IAAK,GAAGA,CAAI,OAAOC,CAAK,GAAI,QAAAJ,CAAQ,CAAE,CAAE,EACpE,CAAC,CACP,CAIA,IAAOM,GAAQV,GD/OA,SAARW,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,UA2B9B,SAASC,GAAgBC,EAAmD,CAC1E,MACE,sBAAuBA,GACvB,OAAQA,EAAkC,mBAAsB,UAEpE,CAEA,IAAqBC,GAArB,cAAgD,gBAAoC,CAApF,kCACE,UAAO,qBAEP,MAAM,QAAQC,EAA4C,CACxD,GAAM,CAAE,cAAAC,EAAe,UAAAC,EAAW,OAAAC,CAAO,EAAIH,EACvC,CAAE,YAAAI,CAAY,EAAI,QAAM,eAC5B,KAAK,cACLF,EACAD,CACF,EACA,OAAOJ,GAAgBO,CAAW,EAC9BA,EAAY,kBAAkB,CAAE,OAAAD,CAAO,CAAC,EACxC,MACN,CACF,ECjDA,IAAAE,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,UA6D9C,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,EC3GA,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,IAAAG,GAA8B,UAqBTC,GAArB,cAAgD,gBAAoC,CAApF,kCACE,UAAO,qBAEP,MAAM,QAAQC,EAA4C,CACxD,GAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,eAAAC,CAAe,EAAIH,EAE3C,OAAAG,IAAiB,kBAAkB,EAC5BC,GAAa,CAAE,MAAAH,EAAO,QAAAC,CAAQ,CAAC,CACxC,CACF,EC/BA,IAAAG,GAAqB,UAErBC,GAAqB,UACrBC,GAAiC,UCFjC,IAAAC,GAA8B,UAC9BC,GAA2B,UAC3BC,EAAmC,UACnCC,GAAyB,UCEzB,IAAAC,GAAuC,UACvCC,GAA2B,UCJ3B,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,2HACL,CAAC,EAAG,aAAa,ECHjB,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,qmBACL,CAAC,EAAG,KAAK,ECHT,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,ycACL,CAAC,EAAG,SAAS,ECHb,IAAAC,GAA4B,UACrBC,MAAQ,kBAAc,IAAc,GAAAC,KAAK,SAAU,CACxD,GAAI,KACJ,GAAI,KACJ,EAAG,KACL,EAAG,GAAG,KAAgB,GAAAA,KAAK,OAAQ,CACjC,EAAG,wJACL,EAAG,GAAG,CAAC,EAAG,aAAa,ECTvB,IAAAC,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,EAAM,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,EACP,OAAA3E,CACF,CAAC,EACD6D,EAAW,IAAI/D,EAAK,KAAM8E,CAAM,EAChCD,GAAO7E,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,CCGA,SAASE,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,EACJ,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,EAASG,EAAK,KAChB,KAAO,CACL,IAAI,EAAI,EACFO,EAAQ1G,GAAQ,CACpB+F,EAAM,KAAK/F,EAAI,MAAM,EACrB,GAAKA,EAAI,MAAQxB,EACnB,EAkBA,GAjBI+D,IACFA,EAAK,MAAM,QAAQ,CAACzC,EAAMwG,KAAM,CAC9BI,EAAK7G,GAAW,MAAMyG,EAAC,GAAI,EAAG,EAAGxG,EAAMkD,EAAQlD,EAAK,IAAI,EAAGC,CAAS,CAAC,CACvE,CAAC,EACD2G,EACE5H,GACE,QACA,EACA,EACA,CAAC,CAAE,OAAQ,EAAG,MAAOJ,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,EACD,EACA,EACA,UACF,EACA0F,EAAK,CAAE,MAAO1G,EAAI,MAAO,OAAQkE,GAAYlE,EAAI,IAAI,CAAE,CAAC,CAC1D,KAAW,CAACuC,GAAQT,GAClB4E,EACE5H,GACE,OACA,EACA,EACAoB,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,GAAW,EAAG,CAAC,CAAC,EAEvB,IAAMmH,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,EAASc,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,EAAS3B,EAAM,OACf,WACF,EACA0B,EAAM,KACJ,oBAAoB9E,CAAK,SAAS+E,EAAS,EAAG,SAASA,EAAS,EAAG,oBACnE,WAAWA,CAAM,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,GAAU3B,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,CAAM,kBAAkB/E,CAAK,IAAI+E,CAAM,eAAepH,GAAI0I,CAAQ,CAAC,2BAA2BrG,CAAK,aAAa+E,CAAM,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,UCvBnB,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,CCxJA,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,EACtBE,EAAIR,EAAQ,IAAIM,EAAE,EAAE,EAC1B,GAAIC,IAAM,QAAUC,IAAM,QAAUD,IAAMC,EACxC,SAEFH,EAAO,IAAI,GAAGC,EAAE,IAAI,IAAIA,EAAE,EAAE,EAAE,EAAE,IAAI,GAAGA,EAAE,EAAE,IAAIA,EAAE,IAAI,EAAE,EACvD,GAAM,CAACG,EAAIC,CAAE,EAAIH,EAAIC,EAAI,CAACD,EAAGC,CAAC,EAAI,CAACA,EAAGD,CAAC,EACvCJ,EAAMM,EAAK,CAAC,IACZN,EAAMO,CAAE,IACR,GAAM,CAACC,EAAMC,CAAE,EAAIL,EAAIC,EAAI,CAACF,EAAE,KAAMA,EAAE,EAAE,EAAI,CAACA,EAAE,GAAIA,EAAE,IAAI,GACxDF,EAAK,IAAIO,CAAI,GAAKP,EAAK,IAAIO,EAAsB,IAAI,GAAK,EAAE,IAAIA,CAAI,GAAG,IAAIC,CAAE,CAChF,CACA,QAASV,EAAI,EAAGA,EAAIC,EAAM,OAAQD,IAChCC,EAAMD,CAAC,GAAKC,EAAMD,EAAI,CAAC,EAEzB,IAAMW,EAAWnB,EAAM,MAAM,OAAOC,CAAU,EAAE,KAAK,CAACY,EAAGC,IAAMD,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EACxFM,EAAuB,IAAI,IAAI,CAACD,EAAS,CAAC,EAAE,GAAIA,EAAS,GAAG,EAAE,EAAE,EAAE,CAAC,EACnEE,EAAaF,EAAS,IAAKG,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,CAACT,EAAGU,CAAE,IAAMD,EAAKC,GAAMX,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EAClMW,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,EACA,IAAI,yBAAmC,CACrC,MAAO,EACT,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,EACA,IAAI,wBAAyB,CAC3B,OAAOA,EAAK,kBAAoBA,EAAK,uBACvC,EAEA,IAAI,SAAU,CACZ,OAAO,KAAK,uBAAyBA,EAAK,YAAc,IAC1D,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,WAAY,CACd,SAAO,sBAAkBA,CAAI,EAAE,KACjC,EAEA,IAAI,cAAe,CACjB,MAAO,EACT,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,CAAC,KAAK,gBAEzC,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,gGACP,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,GAAQjG,EAAK,uBAC1B,CACE,QAAS8B,EAAO,QAChB,aAAcA,EAAO,aACrB,GAAGmE,CACL,EACA,MACN,CACF,EAAE,EKr4BJ,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,QAAAC,EAAS,YAAAC,EAAa,aAAAC,CAAa,EAAI/D,EACzCgE,EAAQ,IAAI,IACdD,IAAiB,MACnBC,EAAM,IAAID,EAAcE,EAAe,EAErCJ,IAAY,MAAQA,IAAYE,GAClCC,EAAM,IAAIH,EAASK,EAAc,EAEnCN,EAAE,kBAAkBI,CAAK,EACzBJ,EAAE,iBACA5D,EAAK,uBAAyB8D,EAAc,KAC5CI,EACF,CACF,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,OAAQpG,EAAK,aACb,QAASA,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,2EACAA,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,EgBrvBJ,SAASG,GAAcC,EAAYC,EAAcC,EAAgB,CAC/D,IAAMC,EAAS,KAAK,IAAI,GAAiBF,EAAMC,CAAM,EACrD,OAAO,KAAK,IAAI,EAAGC,GAAUH,EAAKC,EAAK,EAAI,KAAK,IAAI,EAAGD,GAAME,EAASC,EAAO,CAC/E,CAgBO,SAASC,GACdC,EACA,EACAC,EACA,CACA,MAAO,CACL,WACE,EAAE,WACFP,GACEM,EAAO,KAAO,EAAE,OAAS,EAAE,WAC3BA,EAAO,EAAI,EAAE,OACbC,EAAK,KACP,EACF,WACE,EAAE,WACFP,GACEM,EAAO,KAAO,EAAE,OAAS,EAAE,WAC3BA,EAAO,EAAI,EAAE,OACbC,EAAK,MACP,CACJ,CACF,CAEO,SAASC,GACdF,EACA,EACAC,EACA,CACA,IAAME,EAAOH,EAAO,KAAO,EAAE,OAAS,EAAE,WAClCI,EAAMJ,EAAO,KAAO,EAAE,OAAS,EAAE,WACvC,OACEG,EAAOF,EAAK,OACZE,EAAOH,EAAO,EAAI,EAAE,OAAS,GAC7BI,EAAMH,EAAK,QACXG,EAAMJ,EAAO,EAAI,EAAE,OAAS,CAEhC,CzB3BO,IAAMK,GAAqBC,GAC/B,QAAQC,IAAS,CAGhB,mBAAoB,CAClB,IAAMC,EAASD,EAAK,aACdE,EAAOF,EAAK,QAClB,GACE,CAACC,GACDD,EAAK,gBAAkB,OACvB,CAACA,EAAK,cACNE,EAAK,OAAS,GACdA,EAAK,QAAU,EAEf,OAEF,IAAMC,EAAIC,GAAWH,EAAQD,EAAME,CAAI,EACnCF,EAAK,gBAAkB,SACzBA,EAAK,WAAaG,EAAE,YAEtBH,EAAK,WAAaG,EAAE,UACtB,CACF,EAAE,EACD,QAAQH,IAAS,CAChB,SAASK,EAAgB,CACvBL,EAAK,MAAQK,EACbL,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,eAAgB,CACdA,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,iBAAiBM,EAAiB,CAChCN,EAAK,cAAgBM,CACvB,EACA,WAAWC,EAAY,CACrBP,EAAK,YAAcO,CACrB,EACA,YAAYA,EAAY,CACtBP,EAAK,aAAeO,CACtB,EACA,mBACEA,EACAC,EACAC,EACA,CACAT,EAAK,eAAiBO,EACtBP,EAAK,wBAA0BQ,EAC/BR,EAAK,cAAgB,CAAE,GAAGS,EAAO,cAAeT,EAAK,aAAc,EACnEA,EAAK,iBACP,EACA,aAAc,CACZA,EAAK,gBAAkBA,EAAK,aAC9B,EACA,iBAAiBU,EAAiB,CAChCV,EAAK,cAAgBU,CACvB,EACA,gBAAgBC,EAA0B,CACxCX,EAAK,aAAeW,CACtB,EACA,gBAAgBC,EAAiB,CAC/BZ,EAAK,aAAeY,CACtB,EACA,cAAcC,EAAuB,CACnCb,EAAK,WAAaa,CACpB,EACA,oBAAoBC,EAAoB,CACtCd,EAAK,iBAAmBc,CAC1B,EAKA,iBAAiBC,EAAc,CAC7Bf,EAAK,cAAgBe,EACrB,IAAMC,EAAQhB,EAAK,MACnB,GAAIgB,GAAO,aAAe,QAAS,CACjC,IAAMC,EAAaC,GAAgBF,EAAOD,CAAI,EAC9CI,GAAa,QAAQH,EAAOC,CAAU,EACtCjB,EAAK,MAAQiB,CACf,CACF,EACA,aAAaG,EAAe,CAC1BpB,EAAK,UAAYoB,CACnB,EACA,YAAYC,EAAe,CACzBrB,EAAK,SAAWqB,CAClB,EACA,eAAeC,EAAqB,CAClCtB,EAAK,YAAcsB,CACrB,EACA,gBAAgBC,EAAsB,CACpCvB,EAAK,aAAeuB,CACtB,EACA,iBAAiBC,EAAe,CAC9BxB,EAAK,cAAgBwB,CACvB,EACA,aAAaC,EAAkB,CAC7BzB,EAAK,UAAYyB,CACnB,EACA,eAAeJ,EAAe,CAC5BrB,EAAK,YAAcqB,CACrB,EACA,qBAAqBA,EAAe,CAClCrB,EAAK,kBAAoBqB,CAC3B,EACA,aAAaA,EAAe,CAC1BrB,EAAK,UAAYqB,CACnB,EACA,sBAAsBA,EAAe,CACnCrB,EAAK,mBAAqBqB,CAC5B,EACA,eAAeK,EAAY,CACzB1B,EAAK,YAAc0B,CACrB,EACA,eAAeC,EAAiB,CAC9B3B,EAAK,YAAc2B,CACrB,EACA,iBAAiBA,EAAiB,CAChC3B,EAAK,cAAgB2B,CACvB,EACA,aAAaC,EAAa,CACxB5B,EAAK,UAAY4B,CACnB,EACA,cAAcC,EAAqB,CACjC7B,EAAK,WAAa6B,CACpB,EAGA,UAAUC,EAAiB,CACzB,IAAMC,EAAM,IAAI,IAAI/B,EAAK,WAAW,IAAIgC,GAAK,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACzDhC,EAAK,WAAa8B,EAAM,IAAIG,GAAQF,EAAI,IAAIE,CAAI,GAAK,CAAE,KAAAA,CAAK,CAAC,CAC/D,EAGA,SAASC,EAA8B,CACjCA,IAAUlC,EAAK,MAAM,QACvBA,EAAK,MAAM,OAAS,CAAC,GAEvBA,EAAK,MAAM,MAAQkC,CACrB,EACA,gBAAgBC,EAA6B,CAC3CnC,EAAK,MAAM,QAAUmC,CACvB,EACA,WAAWF,EAAc,CACvB,IAAMJ,EAAS7B,EAAK,WACpBA,EAAK,WAAa6B,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,CACvDpC,EAAK,WAAaA,EAAK,WAAW,IAAIgC,GACpCA,EAAE,OAASC,EAAO,CAAE,GAAGD,EAAG,MAAO,CAAE,GAAGA,EAAE,MAAO,GAAGI,CAAM,CAAE,EAAIJ,CAChE,CACF,EAKA,cAAcK,EAAwB,CACpCrC,EAAK,WAAaqC,CACpB,EACA,kBAAkBC,EAA+B,CAC/CtC,EAAK,eAAiBsC,CACxB,EACA,kBAAkBC,EAAqC,CACrDvC,EAAK,eAAiBuC,CACxB,EASA,mBAAmBC,EAAgB,CACjC,IAAMC,EAASzC,EAAK,gBAElByC,IAAW,QACXC,GAAS,CAAC,MAAG,eAAW1C,CAAI,EAAE,KAAK,CAAC,EAAE,KACpCE,GAASA,EAA0B,KAAOuC,CAC5C,IAEAzC,EAAK,gBAAkBwC,EAE3B,EACA,eAAeG,EAAuB,CACpC3C,EAAK,YAAc2C,CACrB,EACA,mBAAmBC,EAAiB,CAC9BA,EAAM,KAAK;AAAA,CAAI,IAAM5C,EAAK,gBAAgB,KAAK;AAAA,CAAI,IACrDA,EAAK,gBAAkB4C,EAE3B,EACA,kBAAkB7B,EAAqB,CACrCf,EAAK,eAAiBe,CACxB,EACA,iBAAiB8B,EAAgC,CAC/C7C,EAAK,cAAgB6C,CACvB,EACA,iBAAiBC,EAAiB,CAChC9C,EAAK,cAAgB8C,CACvB,EACA,aAAazB,EAAe,CAC1BrB,EAAK,UAAYqB,EACjBrB,EAAK,WAAa,IACpB,EAGA,cAAc+C,EAA+C,CAC3D/C,EAAK,WAAa+C,EAClB,IAAMC,EAAOhD,EAAK,cACZiD,EAAQjD,EAAK,eACbkD,EACJH,GAASC,EACL,CAACA,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAE,KAAKG,GAAKA,EAAE,OAASJ,EAAM,GAAG,EAC7D,OACAK,EACJF,GAAOD,GAASjD,EAAK,MACjBqD,GAAUrD,EAAK,MAAOkD,EAAKH,EAAO,OAAQE,EAAM,MAAM,EACtD,OACNjD,EAAK,YAAcoD,GAAQ,IAC7B,EACA,cAAcE,EAAyC,CACrDtD,EAAK,WAAasD,CACpB,EACA,eAAeC,EAAwB,CACrCvD,EAAK,YAAcuD,CACrB,EACA,gBAAgBZ,EAAuB,CACrC3C,EAAK,aAAe2C,CACtB,EACA,gBAAgBA,EAAuB,CACrC3C,EAAK,aAAe2C,CACtB,EACA,WAAWa,EAAkB,CAC3BxD,EAAK,UAAYwD,CACnB,EACA,cAAe,CACbxD,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,gBAAgB2C,EAAgB,CAC9B,IAAMS,EAAOpD,EAAK,UAAU,IAAI2C,CAAM,EAChCc,EAAWzD,EAAK,SAChB0D,EAAY1D,EAAK,cACvB,GAAIoD,GAAQK,GAAYC,EAAW,CACjC,IAAMC,KAAU,eAAW3D,CAAI,EACzB4D,EAAS5D,EAAK,YAId6D,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,EAAInE,EACbA,EAAK,gBAAkB,QAAUmE,EACnCA,EAAK,iBAAiBnE,EAAK,WAAaiE,CAAE,GAE1CjE,EAAK,cAAgB,OACrBA,EAAK,MAAQoE,GAAUJ,CAAC,EACxBhE,EAAK,WAAaiE,GAEpBjE,EAAK,WAAakE,EAClBlE,EAAK,kBAAkB,CACzB,EACA,KAAKqE,EAAgBC,EAAiBC,EAAiB,CACrD,GAAM,CAAE,KAAAJ,CAAK,EAAInE,EACjB,GAAIA,EAAK,gBAAkB,QAAUmE,EAAM,CACzCA,EAAK,OAAOA,EAAK,QAAUE,EAAQC,CAAO,EAC1C,MACF,CACAtE,EAAK,cAAgB,OACrB,IAAMG,EAAIqE,GAAUxE,EAAMqE,EAAQC,EAASC,EAASvE,EAAK,SAAS,EAClEA,EAAK,MAAQG,EAAE,MACfH,EAAK,WAAaG,EAAE,WACpBH,EAAK,WAAaG,EAAE,WACpBH,EAAK,kBAAkB,CACzB,EACA,kBAAmB,CACjBA,EAAK,uBAAyB,GAC9BA,EAAK,eACP,EAEA,mBAAoB,CAClBA,EAAK,kBACP,EACA,WAAY,CAEV,GAAIA,EAAK,gBAAkB,OAAQ,CACjC,IAAMC,EAASD,EAAK,aACdyE,EAAUzE,EAAK,YAAc,OAC7B0E,EAAMD,EAAUE,GAAeC,EAC/BC,EAASJ,EAAUE,GAAe3E,EAAK,UACvC8E,EAAe9E,EAAK,QAAQ,OAAS6E,EAASH,EAChDzE,GAAU6E,EAAe,IAC3B9E,EAAK,WAAa+E,GAChB9E,EACA6E,EACA9E,EAAK,OACL6E,CACF,GAEF,MACF,CAIA,IAAMG,EAAMhF,EAAK,gBACbgF,IACFhF,EAAK,MAAQgF,EAAI,MACjBhF,EAAK,WAAagF,EAAI,WACtBhF,EAAK,WAAagF,EAAI,WAE1B,EACA,kBAAmB,CACjBhF,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,eAAiB,OACtBA,EAAK,wBAA0B,OAC/BA,EAAK,cAAgB,MACvB,CACF,EAAE,EACD,QAAQA,IAAS,CAIhB,cAAciF,EAAeC,EAAoB,CAC/C,IAAMC,EAAWnF,EAAK,gBAAkB,OACpCmF,IACFnF,EAAK,cAAgB,QAEvBA,EAAK,MAAQiF,EACbjF,EAAK,WAAakF,EACdC,GACFnF,EAAK,UAAU,CAEnB,EAOA,gBAAgBoF,EAAoC,CAClD,IAAMnF,EAASD,EAAK,aACpB,GACEA,EAAK,gBAAkB,QACvB,CAACC,GACDmF,IAAapF,EAAK,aAElB,OAEF,IAAMqF,EAAYD,GAAU,gBAAkB,IAAQpF,EAAK,eAEzDoF,IAAa,QACZC,IACE,CAACrF,EAAK,cAAgBsF,GAASrF,EAAQD,EAAMA,EAAK,OAAO,GAE5DA,EAAK,kBAAkB,GAEvBA,EAAK,cAAgB,MACrBA,EAAK,UAAU,EAEnB,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,SAASuF,GAAwB,CAC/B,aAAavF,EAAK,kBAAkB,EACpCA,EAAK,uBAAyB,GAC9BA,EAAK,mBAAqB,WAAW,IAAM,IACrC,YAAQA,CAAI,GACdA,EAAK,iBAAiB,CAE1B,EAAGwF,EAAoB,CACzB,CAQA,SAASC,GAA6B,CACpC,qBAAqBzF,EAAK,mBAAmB,EAC7CA,EAAK,oBAAsB,sBAAsB,IAAM,IACjD,YAAQA,CAAI,GACdA,EAAK,kBAAkB,CAE3B,CAAC,CACH,CAEA,MAAO,CAsBL,SAAS2C,EAAgB+C,EAAYC,EAAY,CAC/C,IAAMC,EAAY5F,EAAK,cAAc,cACrC,GAAI4F,IAAYjD,CAAM,EAAG,CACvB,QAAWkD,KAAOD,EAAUjD,CAAM,EAChCkD,EAAI,GAAKH,EACTG,EAAI,GAAKF,EAEXF,EAA2B,CAC7B,CACF,EACA,sBAAAF,CACF,CACF,CAAC,ED3eI,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,OAAQR,EAAK,aACb,QAASA,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,EAEdC,EAEAC,EAEEC,EAAgB,IAAI,IAK1B,SAAUC,EAAWlB,EAAc,CACjC,IAAMN,EAAU,EAAEoB,EACZK,EAAS,IAAM7B,EAAK,QAAUU,GAASN,IAAYoB,EACnDM,EAAS7B,GAAgB,OAC3B8B,EACJ,GAAI,CAEF,GAAI/B,EAAK,gBAAkBU,EAAM,MAAM,OAASV,EAAK,cACnD,MAAM,IAAI,MACR,4BAA4BU,EAAM,MAAM,OAAO,eAAe,CAAC,iBAAiBV,EAAK,cAAc,eAAe,CAAC,oGACrH,EAEF+B,EAAW,MAAOtB,EAAcC,CAAK,CACvC,OAASsB,EAAG,CAMV,GAAI,CAACH,EAAO,GAAKC,GAAQ,QACvB,MAAO,GAET,MAAAL,EAAcO,EACRA,CACR,CACA,IAAMC,EAAOJ,EAAO,EACpB,GAAII,EAAM,CACJR,IAAgB,QAAazB,EAAK,QAAUyB,IAC9CzB,EAAK,MAAQ,QAEfyB,EAAc,OACd,IAAMS,EAAWlC,EAAK,aACtB0B,EAAehB,EACfV,EAAK,aAAe+B,EAAS,OAC7B/B,EAAK,YAAY+B,EAAS,QAAQ,EAClC/B,EAAK,gBAAgBkC,CAAQ,CAC/B,CACA,OAAOD,CACT,CAIA,SAASE,EAAgBzB,EAAcI,EAAwB,CAC7D,IAAMsB,EAAQ1B,EAAM,YACpB,OAAOA,EAAM,aAAe,SAAW0B,GAEjCC,GAAa3B,EAAOV,EAAK,kBAAkBc,EAAO,YAAY,CAAC,GAC/DwB,GAAoBF,EAAOtB,EAAO,YAAY,IAC7C,KACH,MACN,CAMA,SAAUyB,EACRC,EACAC,EACA3B,EACA4B,EAAgB,GAChBC,EACA,CACA,IAAMb,EAAS7B,GAAgB,OAC/BD,EAAK,iBAAiB,aAAa,EACnC,IAAM4C,EAASC,GAAUL,EAAMC,EAAM,CACnC,cAAezC,EAAK,eAAiBc,GAAQ,YAC/C,CAAC,EACKgC,EAAShC,EAASqB,EAAgBS,EAAQ9B,CAAM,EAAI,OACpDJ,EACJ,CAACV,EAAK,eACN8C,IAAW,QACXA,IAAWF,EAAO,cACdG,GAAgBH,EAAQE,CAAM,EAC9BF,EACN,GAAID,EAAS,CACX3C,EAAK,iBAAiB,oBAAoB,EAC1C,GAAI,CACF,GAAM,CAAE,QAAAgD,EAAS,MAAAC,CAAM,EAAK,MAAMN,EAAQjC,CAAK,EAC/CA,EAAM,MAAQsC,EACdhD,EAAK,WAAa,CAAE,MAAOgD,EAAQ,OAAQ,MAAAC,CAAM,CACnD,OAASjB,EAAG,CACV,GAAIF,GAAQ,QACV,OAEF,QAAQ,KAAK,4CAA6CE,CAAC,EAC3DhC,EAAK,WAAa,MACpB,CACA,GAAI8B,GAAQ,QACV,MAEJ,MACE9B,EAAK,WAAa,OAEpB,IAAMkD,EAAWR,EAAgB1C,EAAK,aAAe,KACrDA,EAAK,MAAQU,EACbV,EAAK,YAAcc,EACnBd,EAAK,oBAAsB8C,EAC3B9C,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxB2B,EAAc,MAAM,EACpB3B,EAAK,aAAe,OACpBA,EAAK,SAAW,CAAC,EAKjBA,EAAK,sBAAsB,EAGvBkD,IAAa,MAAQxC,EAAM,MAAM,KAAKyC,GAAKA,EAAE,KAAOD,CAAQ,IAC9DlD,EAAK,aAAekD,GAEtBlD,EAAK,iBAAiB,kBAAkB,EACxC,MAAO4B,EAAWlB,CAAK,CACzB,CAKA,IAAI0C,EAAW,EAGXC,EAEJ,SAASC,GAAY,CACnB,IAAMC,EAAO,EAAEH,EACf,OAAAnD,GAAgB,MAAM,EACtBA,EAAiB,IAAI,gBACrBoD,EAAeE,EACfvD,EAAK,aAAe,GACb,CACL,OAAQ,IAAMuD,IAASH,EACvB,OAAQnD,EAAe,MACzB,CACF,CAEA,SAASuD,GAAU,CACjBH,EAAe,OACfrD,EAAK,cAAc,CACrB,CAEA,SAASyD,GAAgB,CACnBJ,IAAiB,QACnBrD,EAAK,cAAc,CAEvB,CAQA,SAAU0D,EACRC,EACA7C,EACAe,EACAC,EACA,CAGA,IAAM8B,EAASC,GAAaF,CAAa,EACzC,GAAI,EAAAA,EAAc,OAAS,oBAAsBC,IAAW,QAG5D,GAAI,CACF,IAAME,EAAY,QAAM,cAAW9D,CAAI,EAAE,WAAW,QAClD,mBAAgBA,CAAI,EACpB,kBACA,CACE,cAAe,CACb,KAAM,yBACN,IAAK,GAAG4D,CAAM,kBACd,QAASD,EAAc,QACvB,oBAAqBA,EAAc,mBACrC,EACA,QAAS,CAAC7C,CAAM,EAChB,OAAAgB,CACF,CACF,EACA,GAAID,EAAO,EAAG,CACZ,IAAMkC,EAAUD,EAAS,IAAIE,IAAM,CACjC,QAASlD,EAAO,QAChB,MAAOkD,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,EAEI,CAACC,EAAW,GAAGC,CAAM,EAAIlE,EAAK,SAChCiE,EACFjE,EAAK,SAAW,CAAC,CAAE,GAAGiE,EAAW,aAAcF,CAAQ,EAAG,GAAGG,CAAM,EAEnElE,EAAK,aAAe+D,CAExB,CACF,OAAS/B,EAAG,CACV,QAAQ,KAAK,mDAAoDA,CAAC,CACpE,CACF,CAKA,SAAUmC,EACRC,EACAtD,EACAuD,EACAvC,EACA,CACA,IAAMwC,KAAU,cAAWtE,CAAI,EACzBuE,EAASH,EACXE,EAAQ,OAAO,KAAKE,GAAKA,EAAE,UAAYJ,CAAO,EAC9C,OACJ,GAAKG,EAGL,GAAI,CACF,OAAQ,MAAMD,EAAQ,WAAW,QAC/B,mBAAgBtE,CAAI,EACpB,kBACA,CACE,iBAAe,mBAAeuE,EAAQ,SAAS,EAC/C,QAAS,CAACzD,CAAM,EAChB,OAAAgB,CACF,CACF,CACF,OAASE,EAAG,CACV,QAAQ,KAAK,wBAAwBqC,CAAI,kBAAmBrC,CAAC,EAC7D,MACF,CACF,CAIA,SAAUyC,EACR3D,EACAe,EACAC,EACA,CACA,IAAMgC,EAAW,MAAOK,EACtBnE,EAAK,WAAW,QAChBc,EACA,QACAgB,CACF,EACIgC,GAAYjC,EAAO,IACrB7B,EAAK,kBAAoB8D,EAE7B,CAIA,SAAUY,EACR5D,EACAe,EACAC,EACA,CACA,IAAMgC,EAAW,MAAOK,EACtBnE,EAAK,aAAa,QAClBc,EACA,UACAgB,CACF,EACIgC,GAAYjC,EAAO,IACrB7B,EAAK,aAAe2E,GAAiBb,CAAQ,EAEjD,CAMA,SAAUc,EACRnC,EACAoC,EACA/D,EACA,CACA,GAAM,CAAE,OAAAe,EAAQ,OAAAC,CAAO,EAAIwB,EAAU,EACrCtD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACb,GAAI,CACF,IAAMwC,EACJ,OAAOqC,GAAW,SAAWA,EAAW,MAAMA,EAAO/C,CAAM,EACzDD,EAAO,IACT,MAAOU,EAAeC,EAAMC,EAAM3B,CAAM,EAE5C,OAASkB,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,iCAAkCG,CAAC,EACjDhC,EAAK,MAAQgC,EAEjB,QAAE,CACIH,EAAO,GACT2B,EAAQ,CAEZ,CACA,OAAO3B,EAAO,CAChB,CAEA,SAASiD,GAAY,CACnB7E,GAAgB,MAAM,EACtBA,EAAiB,OACjBoD,EAAe,OACfD,IACA5B,GACF,CAIA,SAASuD,GAAY,CACnBD,EAAU,EACV9E,EAAK,MAAQ,OACbA,EAAK,YAAc,OACnBA,EAAK,oBAAsB,OAC3BA,EAAK,aAAe,OACpBA,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxB2B,EAAc,MAAM,EACpB3B,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,EAElBA,EAAK,gBAAkB,SACzBA,EAAK,cAAgB,MAEzB,CAEA,MAAO,CAEL,YAAa,CACX+E,EAAU,CACZ,EAGA,YAAa,CACP/E,EAAK,gBACP+E,EAAU,EACV/E,EAAK,aAAe,GAExB,EAEA,UAAW,CACT8E,EAAU,EAEN9E,EAAK,QAAU0B,IACjB1B,EAAK,aAAe,QAEtBA,EAAK,UAAY,GACjBA,EAAK,cAAgB,GACrBA,EAAK,aAAe,EACtB,EACA,eAAgB,CACd8E,EAAU,CACZ,EACA,WAAS,QAAK,UAAWtC,EAAcC,EAAO,eAAgB,CAC5D,MAAOmC,EAAanC,EAAMD,CAAI,CAChC,CAAC,EACD,uBAAqB,QAAK,UACxBwC,EACAlE,EACA,CACAd,EAAK,iBAAiB,cAAc,EACpC,IAAMiC,EAAO,MAAO2C,EAClBK,GAASD,CAAQ,GAAK,MACtBlD,MAAU,iBAAakD,CAAQ,EAAE,SAAS,CAAE,SAAU,OAAQ,OAAAlD,CAAO,CAAC,EACtEhB,CACF,EACA,GAAIA,GAAUmB,GAAQjC,EAAK,MAAO,CAChC,IAAM6B,EAAS,IAAM7B,EAAK,cAAgBc,EAC1C,MAAM,QAAQ,IAAI,IAChB,QAAK2D,CAAS,EAAE3D,EAAQe,CAAM,KAC9B,QAAK6C,CAAW,EAAE5D,EAAQe,CAAM,CAClC,CAAC,CACH,CACF,CAAC,EAID,eAAa,QAAK,UAChB8B,EACA7C,EACAoE,EAA2B,CAAC,EAC5B,CACA,GAAM,CAAE,OAAArD,EAAQ,OAAAC,CAAO,EAAIwB,EAAU,EACrCtD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACbA,EAAK,iBAAiB,mBAAmB,EACzC,GAAI,CACF,IAAMmF,EAAa,YAAY,IAAI,EAC7BC,EAAW,QAAM,cAAWpF,CAAI,EAAE,WAAW,QACjD,mBAAgBA,CAAI,EACpB,cACA,CAAE,cAAA2D,EAAe,OAAA7C,EAAQ,KAAAoE,EAAM,OAAApD,CAAO,CACxC,EACA,GAAI,CAACD,EAAO,EACV,OAGF,GADA7B,EAAK,WAAW,YAAY,IAAI,EAAImF,CAAU,EAC1C,CAACC,EACH,MAAM,IAAI,MACR,iHACF,EAoBF,GAlBA,MAAO7C,EACL6C,EACAC,GAASvE,CAAM,EACfA,EACA,GACAwE,GAAW3B,CAAa,EACpBjD,MACE,cAAWV,CAAI,EAAE,WAAW,QAC1B,mBAAgBA,CAAI,EACpB,gBACA,CACE,cAAA2D,EACA,UAAWjD,EAAM,MAAM,IAAIyC,GAAKA,EAAE,IAAI,EACtC,OAAArB,CACF,CACF,EACF,MACN,EACI,CAACD,EAAO,EACV,OAKF7B,EAAK,iBAAiB,qBAAqB,EAC3C,MAAM,QAAQ,IAAI,CAChBkF,EAAK,OAAS,SACV,UACA,QAAKxB,CAAW,EAAEC,EAAe7C,EAAQe,EAAQC,CAAM,KAC3D,QAAK2C,CAAS,EAAE3D,EAAQe,EAAQC,CAAM,KACtC,QAAK4C,CAAW,EAAE5D,EAAQe,EAAQC,CAAM,CAC1C,CAAC,CACH,OAASE,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,gCAAiCG,CAAC,EAChDhC,EAAK,MAAQgC,EAEjB,QAAE,CACIH,EAAO,GACT2B,EAAQ,CAEZ,CACF,CAAC,EAKD,iBAAe,QAAK,WAAa,CAC/B,IAAM1C,EAASd,EAAK,YACdoE,EAAUpE,EAAK,aAAa,QAC9Bc,IACFd,EAAK,aAAe,OACpB,MAAO0E,EACL5D,EACA,IACEd,EAAK,cAAgBc,GACrBd,EAAK,aAAa,UAAYoE,CAClC,EAEJ,CAAC,EAGD,0BAAwB,QAAK,WAAa,CACxC,IAAMY,EAAWhF,EAAK,kBAChBuF,EAAMP,EAAW,KAAK,UAAUA,CAAQ,EAAI,OAClD,GAAIO,IAAQrF,IAGZA,EAAiBqF,EACjBvF,EAAK,mBAAqB,OACtB,EAACgF,GAGL,GAAI,CACF,IAAMxC,EAAQ,QAAM,iBAAawC,CAAQ,EAAE,SAAS,MAAM,KACtD,WAAQhF,CAAI,GAAKuF,IAAQrF,IAC3BF,EAAK,mBAAqBwF,GAAgBhD,CAAI,EAElD,OAASR,EAAG,IACN,WAAQhC,CAAI,GAAKuF,IAAQrF,MAC3B,cAAWF,CAAI,EAAE,OACf,gEAAgE,OAAOgC,CAAC,CAAC,IACzE,SACF,CAEJ,CACF,CAAC,EAID,iBAAe,QAAK,WAAa,CAC/B,IAAMyD,EAAQzF,EAAK,eAAe,OAAS,CAAC,EACtCuF,EAAM,KAAK,UAAUE,CAAK,EAC1B/E,EAAQV,EAAK,MACb0F,EAAU,IAAI,IACpB,MAAM,QAAQ,IACZD,EAAM,IAAI,CAAC,CAAE,IAAAE,EAAK,QAAAvB,EAAS,OAAAtD,CAAO,OAChC,QAAK,WAAa,CAChB,IAAM8E,EAAW,GAAGxB,CAAO,IAAItD,EAAO,OAAO,IAAIA,EAAO,KAAK,IAAIA,EAAO,GAAG,GACvE+E,EAAQlE,EAAc,IAAIiE,CAAQ,EACtC,GAAI,CAACC,EAAO,CACV,IAAM/B,EAAW,MAAOK,EACtBC,EACAtD,EACA,iBACF,EACA,GAAI,CAACgD,EACH,OAEF+B,EAAQC,GAAehC,CAAQ,EAAE,IAAIiC,IAAM,CACzC,GAAGA,EACH,QAASjF,EAAO,OAClB,EAAE,EACFa,EAAc,IAAIiE,EAAUC,CAAK,CACnC,CACAH,EAAQ,IAAIC,EAAKE,CAAK,CACxB,CAAC,EAAE,CACL,CACF,KAEE,WAAQ7F,CAAI,GACZA,EAAK,QAAUU,GACf,KAAK,UAAUV,EAAK,eAAe,OAAS,CAAC,CAAC,IAAMuF,IAEpDvF,EAAK,iBAAmByF,EAAM,OAASC,EAAU,OAErD,CAAC,EACD,eAAa,QAAK,WAAa,CAC7B/D,EAAc,MAAM,EACpB,IAAMb,EAASd,EAAK,YACdoE,EAAUpE,EAAK,WAAW,QAC5Bc,IACFd,EAAK,kBAAoB,OACzB,MAAOyE,EACL3D,EACA,IACEd,EAAK,cAAgBc,GAAUd,EAAK,WAAW,UAAYoE,CAC/D,EAEJ,CAAC,EAKD,aAAW,QAAK,UAAW4B,EAAyB,CAClD,IAAMtF,EAAQV,EAAK,MACnB,GAAI,CAACU,EACH,OAEF,IAAMuF,EAAMC,GAAexF,EAAOyF,GAAiBH,CAAM,CAAC,EAC1D,GAAIC,EAAI,MAAM,SAAW,EAAG,IAC1B,cAAWjG,CAAI,EAAE,OACf,yFACA,MACF,EACA,MACF,CACAA,EAAK,SAAW,CACd,GAAGA,EAAK,SACR,CACE,MAAAU,EACA,WAAYV,EAAK,WACjB,MAAOU,EAAM,KACb,aAAcV,EAAK,YACrB,CACF,EACAA,EAAK,aAAe,OACpB,IAAMoG,EAAQ,GAAGC,GAAkBC,GAAeN,EAAQhG,EAAK,YAAY,EAAE,IAAI,CAAC,OAAOgG,EAAO,OAAO,IAAIA,EAAO,MAAM,eAAe,CAAC,GACxIhG,EAAK,MAAQ,CAAE,GAAGiG,EAAK,KAAMG,CAAM,EACnCpG,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO4B,EAAW5B,EAAK,KAAK,IAC9ByD,EAAc,CAElB,OAASzB,EAAG,CACVhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,CACF,CAAC,EACD,eAAa,QAAK,WAAa,CAC7B,IAAM8C,EAAOvG,EAAK,WAClB,GAAKuG,EAGL,CAAAvG,EAAK,SAAWA,EAAK,SAAS,MAAM,EAAG,EAAE,EACzCA,EAAK,MAAQuG,EAAK,MAClBvG,EAAK,WAAauG,EAAK,WACvBvG,EAAK,aAAeuG,EAAK,aACzBvG,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO4B,EAAW2E,EAAK,KAAK,IAC9B9C,EAAc,CAElB,OAASzB,EAAG,CACVhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,EACF,CAAC,EACD,mBAAiB,QAAK,WAAa,CACjC,IAAM/C,EAAQV,EAAK,MACnB,GAAKU,EAGL,CAAAV,EAAK,UAAY,GACjBA,EAAK,iBAAiB,kBAAkB,EAExC,GAAI,EAKE,MAAO4B,EAAWlB,CAAK,IACzB+C,EAAc,CAElB,OAASzB,EAAG,CACV,QAAQ,MAAM,oCAAqCA,CAAC,EACpDhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,EACF,CAAC,CACH,CACF,CAAC,E2BpuBD,SAAS+C,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,KAGA,gBACEA,KACA,YACE,IAAM,GAAGA,EAAK,QAAQ,KAAK,IAAIA,EAAK,QAAQ,MAAM,GAClD,IAAM,CACJA,EAAK,kBAAkB,CACzB,CACF,CACF,KACA,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,SAAWA,EAAK,YACrC,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,EiC9SJ,IAAAyB,GAA+B,SAM/B,IAAMC,GAAwB,eAmBvB,SAASC,GAAa,CAC3B,QAAAC,EACA,aAAAC,EACA,MAAAC,CACF,EAIG,CACD,IAAMC,EAASC,GAAsBJ,EAASC,CAAY,EACpDI,EAAkB,CAAC,EACzB,QAAWC,KAASN,EAAQ,OAAQ,CAClC,IAAMO,KAAgB,mBAAeD,EAAO,MAAM,EAC5CE,KAAyB,mBAAeF,EAAO,eAAe,EAC9DG,KAAmB,mBAAeH,EAAO,SAAS,EAEtDC,IAAST,IACT,MAAM,QAAQU,CAAa,GAC3BA,EAAc,KACZE,GACE,OAAOA,GAAS,UAChBN,GAAsBJ,EAASU,CAAI,IAAMP,CAC7C,GACA,OAAOM,GAAY,UACnBA,IAAYP,GAEZG,EAAM,KAAKI,CAAO,CAEtB,CACA,OAAOP,EAAQ,CAACA,EAAO,GAAGG,CAAK,EAAIA,CACrC,CCvDA,IAAAM,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,CxCuBO,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,CAGd,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,EAEA,sBAAsB,CAAE,OAAAC,EAAS,EAAK,EAAI,CAAC,EAAe,CACxD,MAAO,CACL,GAAIC,GAAe,IAAItB,EAAK,gBAAgB,EACxC,CACE,CACE,MAAO,gBACP,QAASuB,GAAe,IAAI,CAAC,CAAE,GAAAC,EAAI,MAAAC,CAAM,KAAO,CAC9C,KAAM,QACN,MAAAA,EACA,QAASzB,EAAK,cAAgBwB,EAC9B,SAAUA,EAAK,GAAKxB,EAAK,OAAO,QAAU,OAC1C,QAAS,IAAM,CACbA,EAAK,eAAewB,CAAE,EACjBxB,EAAK,gBAAgB,CAC5B,CACF,EAAE,CACJ,CACF,EACA,CAAC,EACL,GAAIqB,GACJrB,EAAK,mBAAqB,YAC1BA,EAAK,cAAc,OAAS,EACxB,CACE,CACE,MAAO,SACP,QAAS,CACP,CACE,KAAM,QACN,MAAO,eACP,QAAS,CAACA,EAAK,eACf,QAAS,IAAM,CACbA,EAAK,aAAa,EAAE,CACtB,CACF,EACA,GAAGA,EAAK,cAAc,IAAI,CAAC,CAAE,IAAA0B,EAAK,KAAAC,EAAM,KAAAC,CAAK,KAAO,CAClD,KAAM,QACN,MAAO,GAAGD,CAAI,SAAMC,EAAK,eAAe,CAAC,WACzC,QAAS5B,EAAK,YAAc0B,EAC5B,QAAS,IAAM,CACb1B,EAAK,aAAa0B,CAAG,CACvB,CACF,EAAE,CACJ,CACF,CACF,EACA,CAAC,EACL,GAAI1B,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,cAAe,QAAS,KAAK,sBAAsB,CAAE,CAAC,EAChE,CAAC,CACP,CACF,EACA,eAA4B,CAC1B,MAAO,CACL,CACE,KAAM,WACN,MAAO,oBACP,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,uBACP,QAASA,EAAK,uBACd,QAAS,IAAM,CACbA,EAAK,oBAAoB,CAACA,EAAK,sBAAsB,CACvD,CACF,EACA,CACE,KAAM,WACN,MAAO,6BACP,QAASA,EAAK,UACd,QAAS,IAAM,CACbA,EAAK,aAAa,CAACA,EAAK,SAAS,CACnC,CACF,EACA,GAAIA,EAAK,sBACL,CACE,CACE,KAAM,WACN,MAAO,uBACP,QAASA,EAAK,mBACd,QAAS,IAAM,CACbA,EAAK,sBAAsB,CAACA,EAAK,kBAAkB,CACrD,CACF,CACF,EACA,CAAC,CACP,CACF,EACA,iBAA8B,CAC5B,MAAO,CACL,CACE,MAAO,aACP,KAAM6B,GACN,SAAU7B,EAAK,oBAAsB,OACrC,iBAAkBA,EAAK,kBACvB,QAAS,IAAM,CACb,IAAM8B,EAAM9B,EAAK,OAAO,EACpB8B,GACFC,GACED,EACA,IAAI9B,EAAK,OAAO,MAAQ,SAAS,WAAW,YAAa,GAAG,CAAC,MAC/D,CAEJ,CACF,EACA,CACE,MAAO,mBACP,KAAMgC,GACN,SAAUhC,EAAK,wBAA0B,OACzC,iBAAkBA,EAAK,sBACvB,QAAS,IAAM,CACb,IAAMiC,EAAOjC,EAAK,WAAW,EACvBE,KAAU,eAAWF,CAAI,EAC/B,UAAU,UACP,UAAU,GAAG,KAAK,UAAUiC,EAAM,KAAM,CAAC,CAAC;AAAA,CAAI,EAC9C,KAAK,IAAM,CACV/B,EAAQ,OACN,wHACA,MACF,CACF,CAAC,EACA,MAAOgC,GAAe,CACrBhC,EAAQ,OAAO,mCAAmC,OAAOgC,CAAC,CAAC,EAAE,CAC/D,CAAC,CACL,CACF,CACF,CACF,EAGA,mBAAmB,CAAE,MAAAC,EAAQ,EAAK,EAAI,CAAC,EAAe,CACpD,IAAMC,EAAQD,EAAQnC,EAAK,YAAc,CAAC,EAC1C,GACEA,EAAK,YAAY,SAAW,GAC5B,CAACA,EAAK,YACL,CAACmC,GAASnC,EAAK,WAAW,SAAW,EAEtC,MAAO,CAAC,EAEV,IAAMqC,EAAUV,GACd3B,EAAK,WAAW,KAAKsC,GAAKA,EAAE,OAASX,CAAI,EACrCY,EAAOH,EAAM,OAASI,GAC5B,MAAO,CACL,CAAE,KAAM,YAAa,MAAO,WAAY,EACxC,GAAID,EACA,CACE,CACE,MAAO,uBACP,QAAS,IAAM,IACb,eAAWvC,CAAI,EAAE,YAAYiB,GAAW,CACtCwB,GACA,CAAE,MAAOzC,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,EACA,CAAC,EACL,IAAIsB,EAAOH,EAAM,OAAOM,GAAQL,EAAOK,EAAK,IAAI,CAAC,EAAIN,GAAO,IAC1DM,IAAS,CACP,KAAM,WACN,MAAOA,EAAK,MACZ,QAASL,EAAOK,EAAK,IAAI,EACzB,QAAS,IAAM,CACb1C,EAAK,WAAW0C,EAAK,IAAI,CAC3B,CACF,EACF,EACA,CACE,MAAO,mBACP,SAAU1C,EAAK,WAAW,SAAW,EACrC,QAAS,IAAM,CACbA,EAAK,cAAc,CAAC,CAAC,CACvB,CACF,EACA,GAAIA,EAAK,WAAW,OAAS,EACzB,CACE,CACE,MAAO,uBACP,QAAS,IAAM,IACb,eAAWA,CAAI,EAAE,YAAYiB,GAAW,CACtC0B,GACA,CAAE,MAAO3C,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,EACA,CAAC,EACL,GAAIjB,EAAK,WAAW,OAAS,GAAKA,EAAK,eACnC,CACE,CAAE,KAAM,YAAsB,MAAO,SAAU,EAC/C,GAAG4C,GAAa,IAAI,CAAC,CAAE,MAAAC,EAAO,MAAApB,CAAM,KAAO,CACzC,KAAM,QACN,MAAOoB,IAAU,OAAS,wBAA0BpB,EACpD,QAASzB,EAAK,MAAM,QAAU6C,EAC9B,QAAS,IAAM,CACb7C,EAAK,SAAS6C,CAAK,CACrB,CACF,EAAE,CACJ,EACA,CAAC,CACP,CACF,EACA,iBAAiBA,EAA4B,CAC3C,IAAMpB,EAAQqB,GAAc,KAAKC,GAAKA,EAAE,QAAUF,CAAK,GAAG,OAASA,EACnE,OAAOA,IAAU,OACb,GAAGpB,CAAK,KAAK,KAAK,iBAAiBzB,EAAK,oBAAoB,CAAC,IAC7DyB,CACN,EACA,gBAA6B,CAC3B,IAAMuB,EAAU,KAAK,sBAAsB,EAC3C,MAAO,CACL,CACE,MAAO,WAAWC,EAAkBjD,EAAK,gBAAgB,EAAE,MAAM,QAAQ,WAAY,EAAE,CAAC,GACxF,KAAMkD,GACN,QAAS,CACP,GAAGC,GAAa,IAAIC,IAAS,CAC3B,KAAM,QACN,MAAOA,EAAK,MACZ,QAASpD,EAAK,mBAAqBoD,EAAK,MACxC,SAAUpD,EAAK,MAAQ,CAACoD,EAAK,UAAUpD,EAAK,KAAK,EAAI,GACrD,iBAAkBoD,EAAK,YACvB,QAAS,IAAM,CACRpD,EAAK,aAAaoD,EAAK,KAAK,CACnC,CACF,EAAE,EACF,GAAIJ,EAAQ,OAAS,EACjB,CAAC,CAAE,KAAM,SAAmB,EAAG,GAAGA,CAAO,EACzC,CAAC,EACL,GAAIhD,EAAK,YACL,CAAC,EACD,CACE,CAAE,KAAM,SAAmB,EAC3B,CACE,MAAO,cACP,QAAS,IAAM,CACbA,EAAK,UAAU,CACjB,CACF,CACF,CACN,CACF,EACA,CACE,MAAO,UAAU,KAAK,iBAAiBA,EAAK,iBAAiB,CAAC,GAC9D,KAAMqD,GACN,QAASP,GAAc,IAAIQ,IAAW,CACpC,KAAM,QACN,MAAO,KAAK,iBAAiBA,EAAO,KAAK,EACzC,QAAStD,EAAK,oBAAsBsD,EAAO,MAC3C,QAAS,IAAM,CACbtD,EAAK,eAAesD,EAAO,KAAK,CAClC,CACF,EAAE,CACJ,EACA,CACE,MAAO,UACP,KAAMC,GACN,QAAS,KAAK,cAAc,CAC9B,CACF,CACF,EAEA,iBAA8B,CAC5B,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQC,GAAqB,CACtC,aAAc1D,EAAK,qBACnB,cAAeA,EAAK,oBACpB,aAAcC,GAAU,CACtBD,EAAK,iBAAiBC,CAAM,CAC9B,EACA,cAAeO,GAAW,CACxBR,EAAK,gBAAgBQ,CAAO,CAC9B,CACF,CAAC,KACC,2BAAuBgD,EAAOC,CAAI,EAEpC,OAAOD,CACT,CACF,EAAE,EyC7bG,SAASG,IAAiB,CAC/B,OAAOC,EACT,C1CUe,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,SAAS,KAAO,CACf,cAAe,EACjB,EAAE,EACD,QAAQC,GAAQ,CACf,IAAMC,EAAeD,EAAK,SAC1B,MAAO,CACL,SAASE,EAAe,CACtBD,EAAaC,CAAK,EAClBF,EAAK,cAAgB,EACvB,CACF,CACF,CAAC,EACA,MAAMA,IAAS,CACd,IAAI,cAAe,CACjB,OAAOA,EAAK,EACd,EAEA,IAAI,WAAY,CACd,OAAOA,EAAK,KACd,EAEA,IAAI,cAAe,CACjB,OAAOA,EAAK,aACd,EAEA,IAAI,eAAgB,CAClB,IAAMG,EAAQ,KAAK,YACnB,OACEH,EAAK,qBACJG,EACGC,GAAiBC,GAAmBL,EAAMG,CAAK,CAAC,EAChD,OAER,EACA,IAAI,mBAAoB,CACtB,OAAOH,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,MAAO,CAAC,GAAGA,EAAK,gBAAgB,EAAG,GAAGA,EAAK,gBAAgB,CAAC,CAC9D,CACF,EAAE,EACD,QAAQA,GAAQ,CACf,IAAMM,EAAYN,EAAK,WACvB,MAAO,CAGL,YAAa,CACXM,EAAU,EACVN,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,cAAgB,EACvB,EACA,MAAO,CACL,IAAMO,EAASP,EAAK,aACpB,GAAIA,EAAK,YAEP,OAAKA,EAAK,aACRA,EAAK,eAAeQ,GAASR,EAAK,WAAW,CAAC,EAEzCA,EAAK,oBAAoBA,EAAK,YAAaO,CAAM,EAE1D,GAAI,CAACP,EAAK,eAAiB,CAACO,EAC1B,OAEF,IAAMJ,EAAQH,EAAK,YACbS,EAAOF,EAAO,IAAMA,EAAO,MAC3BG,EAAUP,EACZQ,GACEC,GAAuBT,CAAK,EAC5BI,EAAO,YACT,EACA,OACJ,GAAI,CAACJ,EACHH,EAAK,SACH,IAAI,MACF,uCAAuCA,EAAK,aAAa,2BAC3D,CACF,UACSU,EACTV,EAAK,SAAS,IAAI,MAAMU,CAAO,CAAC,UACvBD,EAAOT,EAAK,YACrBA,EAAK,SACH,IAAI,MACF,qBAAqBa,GAAaJ,CAAI,CAAC,uCAAkCI,GAAab,EAAK,WAAW,CAAC,GACzG,CACF,MAEA,QAAOA,EAAK,YAAYK,GAAmBL,EAAMG,CAAK,EAAGI,EAAQ,CAC/D,KAAMP,EAAK,gBACX,WAAYA,EAAK,cACjB,GAAIA,EAAK,eACL,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CAGL,CACF,CACF,CAAC,EACA,QAAQA,IAAS,CAChB,WAAY,CACLA,EAAK,KAAK,CACjB,EAKA,aAAac,EAAuB,CAClC,IAAMC,EAASf,EAAK,eACpB,OAAAA,EAAK,cAAcc,CAAI,EAChBd,EAAK,eAAiBA,EAAK,iBAAmBe,EACjDf,EAAK,KAAK,EACVA,EAAK,gBAAgB,CAC3B,EAIA,aAAc,CACPA,EAAK,OACHA,EAAK,KAAK,KAEjB,eACEA,KACA,aACE,IAAMA,EAAK,UACX,IAAM,CAEFA,EAAK,eACL,CAACgB,EAAkBhB,EAAK,gBAAgB,EAAE,YAErCA,EAAK,KAAK,CAEnB,CACF,CACF,CACF,CACF,EAAE,CACN,CD5KA,IAAMiB,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,C4CxCA,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,EAKA,iBAAkB,CAChB,KAAM,UACN,aAAc,EAChB,EACA,MAAG,kCAA8B,CAC/B,cAAe,IACf,OAAQ,+CACV,CAAC,CACH,EACA,CAAE,gBAAiB,GAAM,mBAAoB,WAAY,CAC3D,CACF,CCnDA,IAAAC,GAAqB,UAIrB,IAAAC,GAAgD,SAChDC,GAA4B,UAC5BC,GAAgC,UAChCC,GAAuC,UACvCC,GAA4C,UAC5CC,GAA6B,UAC7BC,EAKO,UACPC,GAGO,UAIP,IAAAC,GAAyB,UClBlB,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,CDiBA,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,EAG/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,OAEP,eAAgB,MAClB,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,EACA,IAAI,yBAAmC,CACrC,SAAO,YAAQA,EAAM,kBAAkB,CACzC,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,GAAiB,KAAK,aAAa,GACnCC,GAAWH,EAAK,YAAY,aAAa,CAE7C,EAGA,IAAI,oBAAqB,CAGvB,IAAMI,EAFSJ,EAAK,cAAc,QAEZ,aACtB,OAAO,OAAOI,GAAU,SAAWA,EAAQ,MAC7C,CACF,EAAE,EACD,MAAMJ,IAAS,CACd,OAAOK,EAA+B,CACpC,IAAMD,EAAQJ,EAAK,mBACnB,OAAOI,IAAU,QAAaC,EAAUD,EAAQ,SAAW,MAC7D,EACA,OAAOE,EAAoB,CACzB,OAAOA,IAAS,SAAW,IAAWN,EAAK,WAC7C,EACA,IAAI,SAAwB,CAC1B,OAAOA,EAAK,WAAaA,EAAK,qBAAuB,OACjD,SACA,MACN,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,cAAe,CACjB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,EAAOP,EAAK,OAAOA,EAAK,OAAOO,EAAK,OAAO,CAAC,EAAI,GACzD,CACF,EAAE,EACD,MAAMP,IAAS,CACd,IAAI,gBAAiB,CACnB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,IAAS,QAAaA,EAAK,IAAMA,EAAK,MAAQP,EAAK,YAC5D,EACA,IAAI,sBAAuB,CACzB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,EACH,qCAAqCC,GAAaD,EAAK,IAAMA,EAAK,KAAK,CAAC,SAASC,GAAaR,EAAK,YAAY,CAAC,IAChH,EACN,EACA,IAAI,oBAAqB,CACvB,MAAO,EACT,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAK,YACd,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,UAAW,CACb,SAAO,oBACL,CACE,MAAOA,EAAK,MACZ,eAAgBA,EAAK,eACrB,cAAe,GACf,cAAeA,EAAK,YACtB,EACA,IAAM,CAACA,EAAK,WAAaA,EAAK,UAAY,CAAC,CAACA,EAAK,YACnD,CACF,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,mBAAmBS,EAAc,CAC/BT,EAAK,gBAAkBS,CACzB,EACA,sBAAsBC,EAAkC,CACtDV,EAAK,mBAAqBU,EAC1BV,EAAK,MAAQ,MACf,EACA,SAASW,EAAiC,CACxCX,EAAK,MAAQW,CACf,EACA,kBAAkBC,EAA6B,CAC7CZ,EAAK,eAAiBY,CACxB,EACA,eAAeC,EAAY,CACzBb,EAAK,YAAca,CACrB,EAIA,KAAM,CACJ,IAAMC,EAASd,EAAK,UACpB,GAAI,CAACc,EACH,OAEF,IAAMC,EAAUC,GACdC,GAAuBjB,EAAK,YAAY,aAAa,EACrDc,EAAO,YACT,EACA,GAAIC,EAAS,CACXf,EAAK,WAAW,EAChBA,EAAK,SAAS,IAAI,MAAMe,CAAO,CAAC,EAChC,MACF,CACA,IAAMG,EAASlB,EAAK,UAAY,SAChC,OAAOA,EAAK,YAAYA,EAAK,cAAec,EAAQ,CAClD,KAAMI,EAAS,EAAIlB,EAAK,gBACxB,WAAYA,EAAK,iBACjB,KAAMkB,EAAS,SAAW,OAC1B,GAAIC,EAAkBnB,EAAK,gBAAgB,EAAE,WACzC,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CACH,CACF,EAAE,EACD,QAAQA,IAAS,CAChB,QAAQO,EAAkB,CACxB,IAAMD,EAAON,EAAK,OAAOO,EAAK,OAAO,EACrC,OAAAP,EAAK,UAAYM,IAAS,SAC1BN,EAAK,UAAYoB,GACfb,EACAP,EAAK,OAAOM,CAAI,EAChBa,EAAkBnB,EAAK,gBAAgB,EAAE,UAC3C,EACAA,EAAK,SACEA,EAAK,IAAI,CAClB,CACF,EAAE,EACD,QAAQA,IAAS,CAOhB,SAASO,EAA2B,CAClCP,EAAK,cAAgBO,EACrB,IAAMc,EAAUF,EAAkBnB,EAAK,gBAAgB,EAAE,WACzD,OACEA,EAAK,gBACLsB,GAAYtB,EAAK,MAAOO,CAAI,GAC3B,CAACP,EAAK,cACLA,EAAK,OAAOO,EAAK,OAAO,IAAMP,EAAK,SACnCuB,GAASvB,EAAK,UAAWO,EAAMc,CAAO,EAEjC,IAIJ,QAAQ,QAAQrB,EAAK,QAAQO,CAAI,CAAC,EAAE,KAAK,IAAM,IAC9C,WAAQP,CAAI,GAAKwB,GAAiBxB,EAAK,KAAK,GAC9C,KAAK,eAAeO,CAAI,CAE5B,CAAC,EACM,GACT,EAGA,eAAeA,EAAkB,CAC/BP,EAAK,SAASO,CAAI,EAClBP,EAAK,UAAY,OACjB,KAAK,SAASA,EAAK,eAAiBO,CAAI,CAC1C,EACA,aAAakB,EAAuB,CAClC,IAAMC,EAAOP,EAAkBnB,EAAK,gBAAgB,EACpDA,EAAK,cAAcyB,CAAI,EACvB,IAAME,EAAKR,EAAkBM,CAAI,EAC3BlB,EAAOP,EAAK,KAAO4B,GAAW5B,EAAK,IAAI,EAAI,OACjD,OACEO,GACA,CAACP,EAAK,iBACL2B,EAAG,aAAeD,EAAK,YACtBC,EAAG,aAAeD,EAAK,YAElB1B,EAAK,QAAQO,CAAI,EAEnBP,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,CAEhB,MAAM,oBAAoB6B,EAAwC,CAChE,GAAI,CACF,IAAMjB,EAAQ,QAAM,eAAWZ,CAAI,EAAE,WAAW,QAC9C,oBAAgBA,CAAI,EACpB,qBACA,CAAE,cAAA6B,CAAc,CAClB,KACI,WAAQ7B,CAAI,GACdA,EAAK,kBAAkBY,CAAK,CAEhC,OAASkB,EAAG,CACV,QAAQ,KAAK,0CAA2CA,CAAC,CAC3D,CACF,CACF,EAAE,EACD,QAAQ9B,IAAS,CAChB,WAAY,CACV,IAAMO,EAAOP,EAAK,cACdO,IACFP,EAAK,eAAe,KAAK,KAAKO,EAAK,IAAMA,EAAK,KAAK,CAAC,EACpDP,EAAK,SAASO,CAAI,EAEtB,EAIA,aAAc,CACRP,EAAK,WAAa,CAACA,EAAK,OACrBA,EAAK,IAAI,KAEhB,eACEA,KACA,aACE,IACE+B,GAAY/B,EAAK,aAAa,EAC1BA,EAAK,cACL,OACN6B,GAAiB,CACf7B,EAAK,kBAAkB,MAAS,EAC5B6B,GACG7B,EAAK,oBAAoB6B,CAAa,CAE/C,EACA,CAAE,gBAAiB,GAAM,KAAM,qBAAsB,CACvD,CACF,KACA,eACE7B,KACA,aACE,IAAMA,EAAK,YACXgC,GAAU,CACHA,GACHhC,EAAK,YAAY,CAErB,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACEA,KACA,aACE,IAAMA,EAAK,UACXiC,GAAS,CACHA,GACFjC,EAAK,cAAciC,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,eACEnC,KACA,aACE,IAAM,GAAGA,EAAK,MAAM,KAAK,IAAIA,EAAK,gBAAgB,KAAK,GACvD,IAAM,CACJ,IAAMoC,EAAQpC,EAAK,YAAYA,EAAK,WAAW,GAAG,OAAS,GACtDA,EAAK,WAAW,OAAS,GAAKA,EAAK,QACtCA,EAAK,UAAU,KAAK,IAAIA,EAAK,OAAQ,KAAK,KAAKoC,CAAK,CAAC,CAAC,CAE1D,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACEpC,KACA,aACE,IAAMA,EAAK,MAAM,oBACjBqC,GAAU,CACR,GAAM,CAAE,KAAAC,CAAK,EAAItC,EACXO,EAAO8B,GAAUC,EAAOV,GAAWU,CAAI,EAAI,OAC7C/B,GACFP,EAAK,SAASO,CAAI,CAEtB,EACA,CAAE,gBAAiB,GAAM,KAAM,iBAAkB,CACnD,CACF,CACF,CACF,EAAE,EACD,MAAMP,IAAS,CAId,IAAI,eAAgB,CAClB,IAAMO,EAAOP,EAAK,KAAO4B,GAAW5B,EAAK,IAAI,EAAI,OAC3CuC,EAAUvC,EAAK,cACrB,GACE,CAACO,GACD,CAACgC,GACD,CAACvC,EAAK,UACNA,EAAK,WACLA,EAAK,eAEL,OAEF,IAAMwC,EAAQ,KAAK,MAAMjC,EAAK,KAAK,EAC7BkC,EAAM,KAAK,KAAKlC,EAAK,GAAG,EAC9B,MAAO,CACL,cAAegC,EACf,aAAc,CACZ,QAAShC,EAAK,QACd,aAAcA,EAAK,aACnB,MAAAiC,EACA,IAAAC,CACF,EACA,gBAAiBzC,EAAK,gBACtB,mBAAoBA,EAAK,iBACzB,YAAa,KAAK,IAAIA,EAAK,YAAayC,EAAMD,CAAK,EACnD,WAAYxC,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,IAAM0C,EAAO1C,EAAK,cACd0C,MACF,eAAW1C,CAAI,EAAE,QAAQ,kBAAmB0C,CAAI,CAEpD,CACF,EAAE,EACD,MAAM1C,IAAS,CAId,cAA2B,CACzB,GAAI,CAAC2C,GAAgB3C,EAAK,aAAa,EACrC,MAAO,CAAC,EAEV,IAAM4C,EAAW1C,GAAiBF,EAAK,aAAa,EAC9C6C,EAAQ1C,GAAWH,EAAK,YAAY,aAAa,EACjDY,EAAQZ,EAAK,eACb8C,EAAS9C,EAAK,mBACd+C,EAASrC,GAAqC,CAClDV,EAAK,sBAAsBU,CAAU,EAChCV,EAAK,IAAI,CAChB,EACA,MAAO,CACL,CAAE,KAAM,YAAa,MAAO,MAAO,EACnC,CACE,KAAM,QACN,MAAOY,EACH,iCAAiCA,EAAM,OAAO,eAAe,CAAC,IAC9D,+BACJ,QAASkC,EAASA,EAAO,SAAW,EAAI,CAACF,GAAY,CAACC,EACtD,QAAS,IAAM,CACbE,EAAM,CAAC,CAAC,CACV,CACF,EACA,GAAIH,GAAYC,EACZ,CACE,CACE,KAAM,QACN,MAAOD,EACH,iCACA,eAAeC,GAAO,MAAM,cAChC,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,EACA,cAAe,IACb,eAAW9C,CAAI,EAAE,YAAYgD,GAAW,CACtC7D,GACA,CAAE,MAAOa,EAAM,KAAM,GAAM,QAAAgD,CAAQ,CACrC,CAAC,CACH,EACA,MAAM,UAAUC,EAAoD,CAClE,GAAM,CAAE,oBAAAC,CAAoB,EAAI,KAAM,QAAO,gCAAa,EAC1D,OAAOA,EACLlD,EACAiD,CACF,CACF,EACA,gBAA6B,CAC3B,IAAME,EAAWnD,EAAK,gBAAgB,KACtC,2BAAuBmD,EAAU,CAC/B,MAAO,oBACP,KAAMC,GACN,SAAU,CAACpD,EAAK,cAChB,iBAAkB,uCAClB,QAAS,IAAM,CACbA,EAAK,cAAc,CACrB,CACF,CAAC,EACD,IAAMU,EAAa,CACjB,GAAG,KAAK,aAAa,EACrB,GAAGV,EAAK,mBAAmB,CAC7B,EACA,MAAO,CACL,GAAIU,EAAW,OAAS,EACpB,CAAC,CAAE,MAAO,aAAc,KAAM2C,GAAW,QAAS3C,CAAW,CAAC,EAC9D,CAAC,EACL,GAAGV,EAAK,eAAe,EACvB,CACE,MAAO,WACP,KAAMsD,GACN,QAAS,IAAM,CACb,KAAK,aAAa,CACpB,CACF,EACA,GAAGH,CACL,CACF,CACF,EAAE,CAER,CFzmBe,SAARI,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,UA8CtB,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,CAEA,SAASC,GAAeD,EAA+B,CACrD,GAAM,CAAE,SAAAE,EAAU,QAAAL,EAAS,IAAAC,CAAI,EAAIE,EACnC,GAAI,OAAOE,GAAa,SACtB,OAAOF,EAET,IAAMG,EAAQC,GAAiB,GAAGF,CAAQ,IAAIE,CAAI,UAClD,MAAO,CACL,GAAGJ,EACH,cAAe,CAAE,IAAKG,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAC7C,WAAYF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,EAC3C,iBAAkB,CAAE,IAAKK,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAChD,cAAeF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,EAC9C,cAAe,CAAE,IAAKK,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAC7C,WAAYF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,CAC7C,CACF,CAEO,SAASO,GAAkBL,EAA+B,CAC/D,GAAM,CAAE,OAAAM,EAAQ,QAAAT,EAAS,IAAAC,CAAI,EAAIE,EACjC,OAAOC,GACLF,GACE,OAAOO,GAAW,UAAYA,IAAW,KACrC,CAAE,GAAGN,EAAM,OAAQD,GAAgB,CAAE,QAAAF,EAAS,IAAAC,EAAK,GAAGQ,CAAO,CAAC,CAAE,EAChEN,CACN,CACF,CACF,CAEA,IAAMO,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,EAOA,cAAe,CACb,KAAM,eACN,aAAc,CAAE,IAAK,GAAI,aAAc,aAAc,CACvD,EAIA,WAAYA,GAAY,iBAAkB,EAAE,EAM5C,UAAW,CACT,KAAM,UACN,aAAc,KAChB,EAOA,eAAgB,CACd,KAAM,UACN,aAAc,GAChB,EAWA,eAAgB,CACd,KAAM,UACN,aAAc,GAChB,EASA,kBAAmB,CACjB,KAAM,cACN,aAAc,CAAC,CACjB,EAcA,oBAAqB,CACnB,KAAM,SACN,aAAc,CAAC,CACjB,EAQA,OAAQG,EACV,EACA,CACE,gBAAiB,GAcjB,mBAAoBL,EACtB,CACF,EAIOO,GAAQD,GD7SA,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,gBAAa,UAAMA,EAAM,QAAQ,QAAQ,KAAM,EAAG,CAAC,GAC/D,YAAa,gBAAa,UAAMA,EAAM,QAAQ,QAAQ,KAAM,EAAG,CAAC,GAChE,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,QrEyBvB,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,EACjEA,EAAc,aAAa,IAAM,IAAIe,GAAmBf,CAAa,CAAC,CACxE,CAMA,UAAUA,EAA8B,CACtC,GAAI,IACE,0BAAsBA,EAAc,SAAS,GAC/CA,EAAc,UAAU,gBAAgB,CAAC,KAAK,EAAG,CAC/C,MAAO,oBACP,KAAMgB,GACN,QAAUC,GAAkC,CAC1CA,EAAQ,QAAQ,kBAAmB,CAAC,CAAC,CACvC,CACF,CAAC,CAEL,OAASC,EAAG,CACV,QAAQ,KAAK,qDAAsDA,CAAC,CACtE,CACF,CACF",
|
|
4
|
+
"sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/Plugin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/AdapterType\"];", "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/core/pluggableElementTypes/renderers/util/serializableFilterChain\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"];", "module.exports = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"];", "module.exports = JBrowseExports[\"@jbrowse/core/svg/svgReady\"];", "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 GetGraphHaplotypes from './GetGraphHaplotypes'\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 pluginManager.addRpcMethod(() => new GetGraphHaplotypes(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 { splitUri } from '../locationName'\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...\"). 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 ...readsIndexBeside(reads, baseUri),\n }\n : {}),\n }\n },\n },\n)\n\n// a bgzipped GAF's index, before any query string its url carries\nfunction readsIndexBeside(reads: string, baseUri: unknown) {\n const { name, query } = splitUri(reads)\n return name.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${name}.tbi${query}`, baseUri } } }\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 { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The haplotypes a graph names without a cut, for the track's haplotype picker:\n// a walk-indexed rGFA's header lines. Undefined where the graph names none, and\n// the picker falls back to typed names.\n\nexport interface GetGraphHaplotypesArgs {\n adapterConfig: Record<string, unknown>\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphHaplotypes: {\n args: GetGraphHaplotypesArgs\n return: string[] | undefined\n }\n }\n}\n\ninterface HaplotypeNamesAdapter {\n getHaplotypeNames(opts: {\n signal?: AbortSignal\n }): Promise<string[] | undefined>\n}\n\nfunction namesHaplotypes(adapter: object): adapter is HaplotypeNamesAdapter {\n return (\n 'getHaplotypeNames' in adapter &&\n typeof (adapter as HaplotypeNamesAdapter).getHaplotypeNames === 'function'\n )\n}\n\nexport default class GetGraphHaplotypes extends RpcMethodType<'GetGraphHaplotypes'> {\n name = 'GetGraphHaplotypes' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphHaplotypes'>) {\n const { adapterConfig, sessionId, signal } = args\n const { dataAdapter } = await getAdapter(\n this.pluginManager,\n sessionId,\n adapterConfig,\n )\n return namesHaplotypes(dataAdapter)\n ? dataAdapter.getHaplotypeNames({ signal })\n : undefined\n }\n}\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 the GBZ cut\n// and a walk-indexed rGFA cut read: they keep those walks, the reference's,\n// 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", "import { layoutEngine } from '@jbrowse/bandage-core/layoutEngines'\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?.('Computing layout')\n return layoutEngine({ graph, options })\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 {\n GraphPaneMixin,\n MAX_GRAPH_REGION_BP,\n fileName,\n formatSpanBp,\n} from './model'\nimport {\n configHaplotypes,\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\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 .volatile(() => ({\n widthMeasured: false,\n }))\n .actions(self => {\n const setBaseWidth = self.setWidth\n return {\n setWidth(width: number) {\n setBaseWidth(width)\n self.widthMeasured = true\n },\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 // until then the width is BaseViewModel's 800 px default\n get paneMeasured() {\n return self.widthMeasured\n },\n // the set stated, else the source track's defaultHaplotypes\n get cutHaplotypes() {\n const track = this.sourceTrack\n return (\n self.subgraphHaplotypes ??\n (track\n ? configHaplotypes(trackAdapterConfig(self, track))\n : undefined)\n )\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.exportMenuItems(), ...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.cutHaplotypes,\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 {\n LAYOUT_MODES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getSession } from '@jbrowse/core/util'\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy'\nimport HubIcon from '@mui/icons-material/Hub'\nimport PaletteIcon from '@mui/icons-material/Palette'\nimport PhotoCameraIcon from '@mui/icons-material/PhotoCamera'\nimport VisibilityIcon from '@mui/icons-material/Visibility'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n HighlightColorDialog,\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 { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\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 // 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 // `repeat` false where a toolbar already picks the repeat\n layoutOptionMenuItems({ repeat = true } = {}): MenuItem[] {\n return [\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 ...(repeat &&\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.selectedRepeat,\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...', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ]\n },\n showMenuItems(): MenuItem[] {\n return [\n {\n type: 'checkbox',\n label: 'Show bubble halos',\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: 'Show hover highlight',\n checked: self.chosenHighlightOnHover,\n onClick: () => {\n self.setHighlightOnHover(!self.chosenHighlightOnHover)\n },\n },\n {\n type: 'checkbox',\n label: 'Show genes on the backbone',\n checked: self.showGenes,\n onClick: () => {\n self.setShowGenes(!self.showGenes)\n },\n },\n ...(self.referenceStripApplies\n ? [\n {\n type: 'checkbox' as const,\n label: 'Show reference strip',\n checked: self.showReferenceStrip,\n onClick: () => {\n self.setShowReferenceStrip(!self.showReferenceStrip)\n },\n },\n ]\n : []),\n ]\n },\n exportMenuItems(): MenuItem[] {\n return [\n {\n label: 'Export SVG',\n icon: PhotoCameraIcon,\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 icon: ContentCopyIcon,\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 // `picks` false where a toolbar already picks the walks, leaving what is\n // done with those picked\n highlightMenuItems({ picks = true } = {}): MenuItem[] {\n const walks = picks ? self.walkChoices : []\n if (\n self.walkChoices.length === 0 ||\n !self.liftsWalks ||\n (!picks && self.walkLayers.length === 0)\n ) {\n return []\n }\n const lifted = (name: string) =>\n self.walkLayers.some(l => l.walk === name)\n const many = walks.length > WALK_MENU_ITEMS\n return [\n { type: 'subHeader', label: 'Highlight' },\n ...(many\n ? [\n {\n label: 'Choose haplotypes...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(many ? walks.filter(walk => lifted(walk.name)) : walks).map(\n walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: lifted(walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n }),\n ),\n {\n label: 'Clear highlights',\n disabled: self.walkLayers.length === 0,\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.drawnWalks.length > 0\n ? [\n {\n label: 'Color highlighted...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n HighlightColorDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n { type: 'subHeader' as const, label: 'Arrange' },\n ...FACET_FIELDS.map(({ value, label }) => ({\n type: 'radio' as const,\n label: value === 'walk' ? 'A panel per haplotype' : label,\n checked: self.facet.field === value,\n onClick: () => {\n self.setFacet(value)\n },\n })),\n ]\n : []),\n ]\n },\n colorSchemeLabel(value: ColorScheme): string {\n const label = COLOR_SCHEMES.find(s => s.value === value)?.label ?? value\n return value === 'auto'\n ? `${label} (${this.colorSchemeLabel(self.effectiveColorScheme)})`\n : label\n },\n graphMenuItems(): MenuItem[] {\n const options = this.layoutOptionMenuItems()\n return [\n {\n label: `Layout: ${layoutModeByValue(self.chosenLayoutMode).label.replace(/ layout$/, '')}`,\n icon: HubIcon,\n subMenu: [\n ...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 disabledHelpText: mode.description,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n })),\n ...(options.length > 0\n ? [{ type: 'divider' as const }, ...options]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n { type: 'divider' as const },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.refitView()\n },\n },\n ]),\n ],\n },\n {\n label: `Color: ${this.colorSchemeLabel(self.chosenColorScheme)}`,\n icon: PaletteIcon,\n subMenu: COLOR_SCHEMES.map(scheme => ({\n type: 'radio' as const,\n label: this.colorSchemeLabel(scheme.value),\n checked: self.chosenColorScheme === scheme.value,\n onClick: () => {\n self.setColorScheme(scheme.value)\n },\n })),\n },\n {\n label: 'Show...',\n icon: VisibilityIcon,\n subMenu: this.showMenuItems(),\n },\n ]\n },\n // the graph's way out, in the \"Launch view\" submenu every view shares\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", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z\"\n}), 'ContentCopy');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M8.4 18.2c.38.5.6 1.12.6 1.8 0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3c.44 0 .85.09 1.23.26l1.41-1.77c-.92-1.03-1.29-2.39-1.09-3.69l-2.03-.68c-.54.83-1.46 1.38-2.52 1.38-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3c0 .07 0 .14-.01.21l2.03.68c.64-1.21 1.82-2.09 3.22-2.32V5.91C9.96 5.57 9 4.4 9 3c0-1.66 1.34-3 3-3s3 1.34 3 3c0 1.4-.96 2.57-2.25 2.91v2.16c1.4.23 2.58 1.11 3.22 2.32L18 9.71V9.5c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3c-1.06 0-1.98-.55-2.52-1.37l-2.03.68c.2 1.29-.16 2.65-1.09 3.69l1.41 1.77Q17.34 17 18 17c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3c0-.68.22-1.3.6-1.8l-1.41-1.77c-1.35.75-3.01.76-4.37 0z\"\n}), 'Hub');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c1.38 0 2.5-1.12 2.5-2.5 0-.61-.23-1.2-.64-1.67-.08-.1-.13-.21-.13-.33 0-.28.22-.5.5-.5H16c3.31 0 6-2.69 6-6 0-4.96-4.49-9-10-9m5.5 11c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5m-3-4c-.83 0-1.5-.67-1.5-1.5S13.67 6 14.5 6s1.5.67 1.5 1.5S15.33 9 14.5 9M5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S7.33 13 6.5 13 5 12.33 5 11.5m6-4c0 .83-.67 1.5-1.5 1.5S8 8.33 8 7.5 8.67 6 9.5 6s1.5.67 1.5 1.5\"\n}), 'Palette');", "\"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: \"12\",\n cy: \"12\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 2 7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5\"\n}, \"1\")], 'PhotoCamera');", "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 // A narrower or shorter pane can leave a placed drawing off screen\n addDisposer(\n self,\n reaction(\n () => `${self.viewBox.width} ${self.viewBox.height}`,\n () => {\n self.keepDrawingInView()\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...\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 || 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 {\n TUBE_MAP_MODES,\n bubblePrefix,\n fileName,\n forceLayouts,\n} 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 engine: self.layoutEngine,\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 // the error the last failed layout raised, which the next one to land clears\n let layoutError: unknown\n // the graph the layout on screen was computed for\n let laidOutGraph: Graph | undefined\n // a haplotype's genes by track and contig span\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 the node limit in Settings.`,\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 layoutError = e\n throw e\n }\n const live = isLive()\n if (live) {\n if (layoutError !== undefined && self.error === layoutError) {\n self.error = undefined\n }\n layoutError = undefined\n const previous = self.layoutResult\n laidOutGraph = graph\n self.layoutResult = computed.result\n self.setLayoutMs(computed.duration)\n self.followNewLayout(previous)\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 // against the new graph's own nodes: nodeById reads through the layout,\n // which is still the last graph's\n if (selected !== null && graph.nodes.some(n => n.id === 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 // the load still fetching, parsing or reading annotations, whose spinner a\n // layout of the graph already on screen must not clear\n let loadInFlight: number | undefined\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n loadInFlight = load\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n function endLoad() {\n loadInFlight = undefined\n self.finishLoading()\n }\n\n function layoutSettled() {\n if (loadInFlight === undefined) {\n self.finishLoading()\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 signal?: AbortSignal,\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 signal,\n },\n )) as Feature[]\n if (isLive()) {\n const bubbles = 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 // an open bubble derives its own; the index is the window's\n const [outermost, ...popped] = self.popStack\n if (outermost) {\n self.popStack = [{ ...outermost, indexBubbles: bubbles }, ...popped]\n } else {\n self.indexBubbles = bubbles\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 signal?: AbortSignal,\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 signal,\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(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const features = yield* trackFeatures(\n self.geneTrack?.trackId,\n region,\n 'genes',\n signal,\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(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const features = yield* trackFeatures(\n self.repeatTrack?.trackId,\n region,\n 'repeats',\n signal,\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 endLoad()\n }\n }\n return isLive()\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n loadInFlight = 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 // the next graph has nothing to do with where the user left this one\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\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 // a graph that landed ahead of its layout has nothing of its own drawn\n if (self.graph !== laidOutGraph) {\n self.layoutResult = undefined\n }\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 fileName(location) || 'GFA',\n signal => openLocation(location).readFile({ encoding: 'utf8', signal }),\n region,\n )\n if (region && live && self.graph) {\n const isLive = () => self.graphRegion === region\n yield Promise.all([\n flow(loadGenes)(region, isLive),\n flow(loadRepeats)(region, isLive),\n ])\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, signal),\n flow(loadGenes)(region, isLive, signal),\n flow(loadRepeats)(region, isLive, signal),\n ])\n } catch (e) {\n if (isLive()) {\n console.error('[GraphGenomeView.cutSubgraph]', e)\n self.error = e\n }\n } finally {\n if (isLive()) {\n endLoad()\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 self.repeatArrays = undefined\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 self.geneTrackFeatures = undefined\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 self.popStack = [\n ...self.popStack,\n {\n graph,\n layoutMode: self.layoutMode,\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 layoutSettled()\n }\n } catch (e) {\n self.error = e\n layoutSettled()\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 layoutSettled()\n }\n } catch (e) {\n self.error = e\n layoutSettled()\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 layoutSettled()\n }\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n layoutSettled()\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 { keepInView, onScreen } from './keepInView'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\n\nimport type { 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 { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\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 { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withFitViews\n .actions(self => ({\n // A pan or zoom never leaves the drawing wholly off screen, where\n // nothing says which way it went. A host's x is its own.\n keepDrawingInView() {\n const bounds = self.layoutBounds\n const view = self.viewBox\n if (\n !bounds ||\n self.viewportOwner === 'fit' ||\n !self.paneMeasured ||\n view.width <= 0 ||\n view.height <= 0\n ) {\n return\n }\n const t = keepInView(bounds, self, view)\n if (self.viewportOwner !== 'host') {\n self.translateX = t.translateX\n }\n self.translateY = t.translateY\n },\n }))\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 setLayoutEngine(engine: LayoutEngineKind) {\n self.layoutEngine = engine\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.layoutMode = mode\n },\n setHighlightOnHover(highlight: boolean) {\n self.highlightOnHover = highlight\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 setMaxGraphNodes(limit: number) {\n self.maxGraphNodes = limit\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 // 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 self.keepDrawingInView()\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 self.keepDrawingInView()\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 // A new layout under a view the user placed. One that replaces a\n // drawing is fitted unless both are on the reference's bp and some of it\n // is still on screen: a force run or a fresh cut draws in coordinates of\n // its own, where the old transform shows nothing in particular. The\n // first layout after a restored session keeps the saved view, pulled\n // into the pane once its width is known.\n followNewLayout(previous: LayoutResult | undefined) {\n const bounds = self.layoutBounds\n if (\n self.viewportOwner !== 'user' ||\n !bounds ||\n previous === self.layoutResult\n ) {\n return\n }\n const keepsAxis = previous?.referenceAxis === true && self.xIsReferenceBp\n if (\n previous === undefined ||\n (keepsAxis &&\n (!self.paneMeasured || onScreen(bounds, self, self.viewBox)))\n ) {\n self.keepDrawingInView()\n } else {\n self.viewportOwner = 'fit'\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", "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-DPV2CUIE.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.2\";\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-O2ANJQVH.js\";\nimport {\n walkRowsKey,\n walkRowsKeyTree,\n walkRowsTree\n} from \"./chunk-V3MD3IZB.js\";\nimport {\n Canvas2DRenderer\n} from \"./chunk-2WNBVB55.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-MBB7ATM6.js\";\nimport {\n encodingStops\n} from \"./chunk-DPV2CUIE.js\";\nimport {\n rangeText,\n walkKey\n} from \"./chunk-2LQ5BWT7.js\";\nimport {\n buildGeometry,\n computeReferenceRamp\n} from \"./chunk-HBEKUQO4.js\";\nimport {\n version\n} from \"./chunk-XNE4UNSJ.js\";\nimport {\n axisScaleOf\n} from \"./chunk-AO2VAMA4.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-XRPU24OP.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(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\");\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-XRPU24OP.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 { litNode, hoveredEdge, selectedNode } = self\n const nodes = new Map<string, number>()\n if (selectedNode !== null) {\n nodes.set(selectedNode, SELECT_BRIGHTEN)\n }\n if (litNode !== null && litNode !== selectedNode) {\n nodes.set(litNode, HOVER_BRIGHTEN)\n }\n b.setNodeHighlights(nodes)\n b.setEdgeHighlight(\n self.chosenHighlightOnHover ? hoveredEdge : null,\n HOVER_BRIGHTEN,\n )\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 engine: self.layoutEngine,\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... 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 // 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-HBEKUQO4.js\";\nimport {\n abgrToCssRgba\n} from \"./chunk-G2FD7S3C.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 get defaultHighlightOnHover(): boolean {\n return true\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 get chosenHighlightOnHover() {\n return self.highlightOnHover ?? self.defaultHighlightOnHover\n },\n // the hovered node, where hovering is to light it\n get litNode() {\n return this.chosenHighlightOnHover ? self.hoveredNode : null\n },\n }))\n .views(self => ({\n get paneWidth() {\n return getContainingView(self).width\n },\n // a linear view knows its width before its tracks draw\n get paneMeasured() {\n return true\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 && !this.geometryPainted))\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 highlighted haplotype colours its own lane: set it under Haplotypes, Color highlighted...',\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 && self.chosenHighlightOnHover\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", "// How much of the drawing a pan or zoom leaves on screen in each axis, or\n// all of it when it is smaller\nexport const KEEP_IN_VIEW_PX = 48\n\n// The shift that brings a span starting at `lo`, `size` px long, back to\n// overlapping [0, extent] by `margin` px\nfunction shiftIntoView(lo: number, size: number, extent: number) {\n const margin = Math.min(KEEP_IN_VIEW_PX, size, extent)\n return Math.max(0, margin - (lo + size)) - Math.max(0, lo - (extent - margin))\n}\n\ninterface DrawingBox {\n minX: number\n minY: number\n w: number\n h: number\n}\n\ninterface Placement {\n scaleX: number\n scaleY: number\n translateX: number\n translateY: number\n}\n\nexport function keepInView(\n bounds: DrawingBox,\n t: Placement,\n view: { width: number; height: number },\n) {\n return {\n translateX:\n t.translateX +\n shiftIntoView(\n bounds.minX * t.scaleX + t.translateX,\n bounds.w * t.scaleX,\n view.width,\n ),\n translateY:\n t.translateY +\n shiftIntoView(\n bounds.minY * t.scaleY + t.translateY,\n bounds.h * t.scaleY,\n view.height,\n ),\n }\n}\n\nexport function onScreen(\n bounds: DrawingBox,\n t: Placement,\n view: { width: number; height: number },\n) {\n const left = bounds.minX * t.scaleX + t.translateX\n const top = bounds.minY * t.scaleY + t.translateY\n return (\n left < view.width &&\n left + bounds.w * t.scaleX > 0 &&\n top < view.height &&\n top + bounds.h * t.scaleY > 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 { canonicalAssemblyName } from './launchFromGraph'\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 wanted = canonicalAssemblyName(session, assemblyName)\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.some(\n name =>\n typeof name === 'string' &&\n canonicalAssemblyName(session, name) === wanted,\n ) &&\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 fileName,\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 { 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 /**\n * #slot\n * whether hovering a node lightens it and bands its span on the view\n */\n highlightOnHover: {\n type: 'boolean',\n defaultValue: true,\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'\nimport type { ReactNode } from 'react'\n\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationReference, getConf } from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { computeSvgReady } from '@jbrowse/core/svg/svgReady'\nimport { pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport { getRpcSessionId, 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 RouteIcon from '@mui/icons-material/Route'\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 configHaplotypes,\n cutsByHaplotype,\n graphReferenceAssembly,\n offReferenceProblem,\n trackLanes,\n walkIndexed,\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 { ExportSvgDisplayOptions } from '@jbrowse/display-kit/types'\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 or walk-indexed cut is for; unset is the\n // config's defaultHaplotypes, else 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 // the haplotypes a walk-indexed graph's header names, once read\n haplotypeNames: undefined as string[] | 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 get defaultHighlightOnHover(): boolean {\n return getConf(self, 'highlightOnHover')\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 configHaplotypes(this.adapterConfig) ??\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 get svgReady() {\n return computeSvgReady(\n {\n error: self.error,\n regionTooLarge: self.regionTooLarge,\n extraTerminal: false,\n fetchCanceled: self.loadCanceled,\n },\n () => !self.isLoading && self.hasGraph && !!self.layoutResult,\n )\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 setHaplotypeNames(names: string[] | undefined) {\n self.haplotypeNames = names\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 // A failed read leaves the picker taking typed names\n async fetchHaplotypeNames(adapterConfig: Record<string, unknown>) {\n try {\n const names = await getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphHaplotypes',\n { adapterConfig },\n )\n if (isAlive(self)) {\n self.setHaplotypeNames(names)\n }\n } catch (e) {\n console.warn('[LinearGraphDisplay] no haplotype names', e)\n }\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 () =>\n walkIndexed(self.adapterConfig)\n ? self.adapterConfig\n : undefined,\n adapterConfig => {\n self.setHaplotypeNames(undefined)\n if (adapterConfig) {\n void self.fetchHaplotypeNames(adapterConfig)\n }\n },\n { fireImmediately: true, name: 'GraphHaplotypeNames' },\n ),\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 or walk-indexed cut is for: every one in the\n // graph, the config's default set or the assemblies the track names,\n // or a list chosen in Settings\n cutMenuItems(): MenuItem[] {\n if (!cutsByHaplotype(self.adapterConfig)) {\n return []\n }\n const defaults = configHaplotypes(self.adapterConfig)\n const lanes = trackLanes(self.parentTrack.configuration)\n const names = self.haplotypeNames\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n void self.cut()\n }\n return [\n { type: 'subHeader', label: 'Load' },\n {\n type: 'radio',\n label: names\n ? `Every haplotype in the graph (${names.length.toLocaleString()})`\n : 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !defaults && !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(defaults || lanes\n ? [\n {\n type: 'radio' as const,\n label: defaults\n ? \"The track's default haplotypes\"\n : `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 openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, open: true, onClose },\n ])\n },\n async renderSvg(opts?: ExportSvgDisplayOptions): Promise<ReactNode> {\n const { renderGraphTrackSvg } = await import('./renderSvg')\n return renderGraphTrackSvg(\n self as unknown as LinearGraphDisplayModel,\n opts,\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 const haplotypes = [\n ...this.cutMenuItems(),\n ...self.highlightMenuItems(),\n ]\n return [\n ...(haplotypes.length > 0\n ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]\n : []),\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' | 'cutMenuItems' | 'openSettings' | 'renderSvg'\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 GFA | Built by `gfa-to-tabix`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED files, one of a graph's segments and one of its links,\n * written by [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) from an rGFA\n * or from a plain GFA with paths. Both of its layouts are read: `anchored`,\n * where one query per file returns the graph under a region, and `contig`,\n * where the adapter follows links onto other contigs.\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 * `walksUri` takes the prefix of a walk-indexed file set in place of `uri`, and\n * resolves `<walksUri>.walks.bed.gz`, `<walksUri>.nodes.bed.gz`,\n * `<walksUri>.links.bed.gz` and their `.tbi` indexes. `gfa-to-tabix --walks -o\n * <prefix>` writes a set per reference sample from 0.5.0, so a track names one\n * as `<prefix>.<sample>`; a set from 0.4.0 holds every reference, and the track\n * names `<prefix>`. Such a graph's cut carries the haplotypes' walks, and\n * `defaultHaplotypes` names the ones it is cut for until the user picks others.\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 * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * walksUri: 'https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.GRCh38',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * defaultHaplotypes: ['HG002', 'HG00733', 'HG02257', 'NA19240'],\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\nfunction walksLocations(snap: Record<string, unknown>) {\n const { walksUri, baseUri, csi } = snap\n if (typeof walksUri !== 'string') {\n return snap\n }\n const file = (kind: string) => `${walksUri}.${kind}.bed.gz`\n return {\n ...snap,\n walksLocation: { uri: file('walks'), baseUri },\n walksIndex: tbi(file('walks'), baseUri, csi),\n segmentsLocation: { uri: file('nodes'), baseUri },\n segmentsIndex: tbi(file('nodes'), baseUri, csi),\n linksLocation: { uri: file('links'), baseUri },\n linksIndex: tbi(file('links'), baseUri, csi),\n }\n}\n\nexport function normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri, csi } = snap\n return walksLocations(\n prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, csi, ...coarse }) }\n : snap,\n ),\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 * one row per haplotype path per reference chunk, its steps through that\n * chunk, written beside node and link files filed under the same chunks.\n * Unset means the graph has no walks.\n */\n walksLocation: {\n type: 'fileLocation',\n defaultValue: { uri: '', locationType: 'UriLocation' },\n },\n /**\n * #slot\n */\n walksIndex: indexSchema('RgfaWalksIndex', ''),\n /**\n * #slot\n * the reference chunk the walk file's rows are filed under, in bp, when\n * its header has no `chunk:i:` line to say so\n */\n walkChunk: {\n type: 'integer',\n defaultValue: 65536,\n },\n /**\n * #slot\n * the most haplotype steps a cut decodes; a window whose walk rows hold\n * more shows a zoom-in notice instead. Counts only the haplotypes the cut\n * is for, so fewer haplotypes draw a wider window.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: 4_000_000,\n },\n /**\n * #slot\n * the most compressed bytes a cut of a walk-indexed graph fetches from its\n * three files, as their Tabix indexes estimate it before any row is read;\n * a window over it shows a zoom-in notice instead. On HPRC v2.1 chr22 a 1\n * Mb window fetches about 3 to 5 MB, and the dense 64 kb chunks at 11.80 to\n * 12.06 Mb on GRCh38 fetch 15 MB or more for a 10 kb window. The budget\n * covers every haplotype, since node and link rows are filed for all of\n * them.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: 8_000_000,\n },\n /**\n * #slot\n * the haplotypes a walk-indexed graph is cut for until the user picks\n * others in the track's Haplotypes menu or Settings, as PanSN prefixes\n * (`HG002#1`, or `HG002` for both of its haplotypes). Empty means every\n * haplotype, or the lanes the track's `assemblyNames` lists after its\n * reference.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\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 * or, for the GRCh38 set of a graph built by `gfa-to-tabix --walks -o\n * chr22`,\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"walksUri\": \"chr22.GRCh38\" }\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} from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport { locationName } from '../locationName'\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.08),\n borderLeft: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n borderRight: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\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.9.2'\n"],
|
|
5
|
+
"mappings": "47EAAA,IAAAA,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,sBAAsB,ICAtD,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,qCAAqC,ICArE,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,8CAA8C,ICA9E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oCAAoC,ICApE,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4CAA4C,ICA5E,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4EAA4E,ICA5G,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,iDAAiD,ICAjF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,oDAAoD,ICApF,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,4BAA4B,ICA5D,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,eAAe,uCAAuC,ICAvE,IAAAC,GAAAC,EAAA,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,UAkCtB,IAAMC,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,GAAGE,GAAiBD,EAAOD,CAAO,CACpC,EACA,CAAC,CACP,CACF,CACF,CACF,EAGA,SAASE,GAAiBD,EAAeD,EAAkB,CACzD,GAAM,CAAE,KAAAG,EAAM,MAAAC,CAAM,EAAIC,GAASJ,CAAK,EACtC,OAAOE,EAAK,SAAS,KAAK,EACtB,CAAE,WAAY,CAAE,SAAU,CAAE,IAAK,GAAGA,CAAI,OAAOC,CAAK,GAAI,QAAAJ,CAAQ,CAAE,CAAE,EACpE,CAAC,CACP,CAIA,IAAOM,GAAQV,GD/OA,SAARW,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,UA2B9B,SAASC,GAAgBC,EAAmD,CAC1E,MACE,sBAAuBA,GACvB,OAAQA,EAAkC,mBAAsB,UAEpE,CAEA,IAAqBC,GAArB,cAAgD,gBAAoC,CAApF,kCACE,UAAO,qBAEP,MAAM,QAAQC,EAA4C,CACxD,GAAM,CAAE,cAAAC,EAAe,UAAAC,EAAW,OAAAC,CAAO,EAAIH,EACvC,CAAE,YAAAI,CAAY,EAAI,QAAM,eAC5B,KAAK,cACLF,EACAD,CACF,EACA,OAAOJ,GAAgBO,CAAW,EAC9BA,EAAY,kBAAkB,CAAE,OAAAD,CAAO,CAAC,EACxC,MACN,CACF,ECjDA,IAAAE,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,UA6D9C,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,EC3GA,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,IAAAG,GAA8B,UAqBTC,GAArB,cAAgD,gBAAoC,CAApF,kCACE,UAAO,qBAEP,MAAM,QAAQC,EAA4C,CACxD,GAAM,CAAE,MAAAC,EAAO,QAAAC,EAAS,eAAAC,CAAe,EAAIH,EAE3C,OAAAG,IAAiB,kBAAkB,EAC5BC,GAAa,CAAE,MAAAH,EAAO,QAAAC,CAAQ,CAAC,CACxC,CACF,EC/BA,IAAAG,GAAqB,UAErBC,GAAqB,UACrBC,GAAiC,UCFjC,IAAAC,GAA8B,UAC9BC,GAA2B,UAC3BC,EAAmC,UACnCC,GAAyB,UCEzB,IAAAC,GAAuC,UACvCC,GAA2B,UCJ3B,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,2HACL,CAAC,EAAG,aAAa,ECHjB,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,qmBACL,CAAC,EAAG,KAAK,ECHT,IAAAC,GAA4B,UACrBC,MAAQ,qBAA2B,GAAAC,KAAK,OAAQ,CACrD,EAAG,ycACL,CAAC,EAAG,SAAS,ECHb,IAAAC,GAA4B,UACrBC,MAAQ,kBAAc,IAAc,GAAAC,KAAK,SAAU,CACxD,GAAI,KACJ,GAAI,KACJ,EAAG,KACL,EAAG,GAAG,KAAgB,GAAAA,KAAK,OAAQ,CACjC,EAAG,wJACL,EAAG,GAAG,CAAC,EAAG,aAAa,ECTvB,IAAAC,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,EAAM,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,EACP,OAAA3E,CACF,CAAC,EACD6D,EAAW,IAAI/D,EAAK,KAAM8E,CAAM,EAChCD,GAAO7E,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,CCGA,SAASE,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,EACJ,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,EAASG,EAAK,KAChB,KAAO,CACL,IAAI,EAAI,EACFO,EAAQ1G,GAAQ,CACpB+F,EAAM,KAAK/F,EAAI,MAAM,EACrB,GAAKA,EAAI,MAAQxB,EACnB,EAkBA,GAjBI+D,IACFA,EAAK,MAAM,QAAQ,CAACzC,EAAMwG,KAAM,CAC9BI,EAAK7G,GAAW,MAAMyG,EAAC,GAAI,EAAG,EAAGxG,EAAMkD,EAAQlD,EAAK,IAAI,EAAGC,CAAS,CAAC,CACvE,CAAC,EACD2G,EACE5H,GACE,QACA,EACA,EACA,CAAC,CAAE,OAAQ,EAAG,MAAOJ,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,EACD,EACA,EACA,UACF,EACA0F,EAAK,CAAE,MAAO1G,EAAI,MAAO,OAAQkE,GAAYlE,EAAI,IAAI,CAAE,CAAC,CAC1D,KAAW,CAACuC,GAAQT,GAClB4E,EACE5H,GACE,OACA,EACA,EACAoB,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,GAAW,EAAG,CAAC,CAAC,EAEvB,IAAMmH,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,EAASc,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,EAAS3B,EAAM,OACf,WACF,EACA0B,EAAM,KACJ,oBAAoB9E,CAAK,SAAS+E,EAAS,EAAG,SAASA,EAAS,EAAG,oBACnE,WAAWA,CAAM,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,GAAU3B,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,CAAM,kBAAkB/E,CAAK,IAAI+E,CAAM,eAAepH,GAAI0I,CAAQ,CAAC,2BAA2BrG,CAAK,aAAa+E,CAAM,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,UCvBnB,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,CCxJA,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,EACtBE,EAAIR,EAAQ,IAAIM,EAAE,EAAE,EAC1B,GAAIC,IAAM,QAAUC,IAAM,QAAUD,IAAMC,EACxC,SAEFH,EAAO,IAAI,GAAGC,EAAE,IAAI,IAAIA,EAAE,EAAE,EAAE,EAAE,IAAI,GAAGA,EAAE,EAAE,IAAIA,EAAE,IAAI,EAAE,EACvD,GAAM,CAACG,EAAIC,CAAE,EAAIH,EAAIC,EAAI,CAACD,EAAGC,CAAC,EAAI,CAACA,EAAGD,CAAC,EACvCJ,EAAMM,EAAK,CAAC,IACZN,EAAMO,CAAE,IACR,GAAM,CAACC,EAAMC,CAAE,EAAIL,EAAIC,EAAI,CAACF,EAAE,KAAMA,EAAE,EAAE,EAAI,CAACA,EAAE,GAAIA,EAAE,IAAI,GACxDF,EAAK,IAAIO,CAAI,GAAKP,EAAK,IAAIO,EAAsB,IAAI,GAAK,EAAE,IAAIA,CAAI,GAAG,IAAIC,CAAE,CAChF,CACA,QAASV,EAAI,EAAGA,EAAIC,EAAM,OAAQD,IAChCC,EAAMD,CAAC,GAAKC,EAAMD,EAAI,CAAC,EAEzB,IAAMW,EAAWnB,EAAM,MAAM,OAAOC,CAAU,EAAE,KAAK,CAACY,EAAGC,IAAMD,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EACxFM,EAAuB,IAAI,IAAI,CAACD,EAAS,CAAC,EAAE,GAAIA,EAAS,GAAG,EAAE,EAAE,EAAE,CAAC,EACnEE,EAAaF,EAAS,IAAKG,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,CAACT,EAAGU,CAAE,IAAMD,EAAKC,GAAMX,EAAE,OAAO,MAAQC,EAAE,OAAO,KAAK,EAClMW,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,EACA,IAAI,yBAAmC,CACrC,MAAO,EACT,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,EACA,IAAI,wBAAyB,CAC3B,OAAOA,EAAK,kBAAoBA,EAAK,uBACvC,EAEA,IAAI,SAAU,CACZ,OAAO,KAAK,uBAAyBA,EAAK,YAAc,IAC1D,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,WAAY,CACd,SAAO,sBAAkBA,CAAI,EAAE,KACjC,EAEA,IAAI,cAAe,CACjB,MAAO,EACT,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,CAAC,KAAK,gBAEzC,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,gGACP,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,GAAQjG,EAAK,uBAC1B,CACE,QAAS8B,EAAO,QAChB,aAAcA,EAAO,aACrB,GAAGmE,CACL,EACA,MACN,CACF,EAAE,EKr4BJ,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,QAAAC,EAAS,YAAAC,EAAa,aAAAC,CAAa,EAAI/D,EACzCgE,EAAQ,IAAI,IACdD,IAAiB,MACnBC,EAAM,IAAID,EAAcE,EAAe,EAErCJ,IAAY,MAAQA,IAAYE,GAClCC,EAAM,IAAIH,EAASK,EAAc,EAEnCN,EAAE,kBAAkBI,CAAK,EACzBJ,EAAE,iBACA5D,EAAK,uBAAyB8D,EAAc,KAC5CI,EACF,CACF,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,OAAQpG,EAAK,aACb,QAASA,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,2EACAA,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,EgBrvBJ,SAASG,GAAcC,EAAYC,EAAcC,EAAgB,CAC/D,IAAMC,EAAS,KAAK,IAAI,GAAiBF,EAAMC,CAAM,EACrD,OAAO,KAAK,IAAI,EAAGC,GAAUH,EAAKC,EAAK,EAAI,KAAK,IAAI,EAAGD,GAAME,EAASC,EAAO,CAC/E,CAgBO,SAASC,GACdC,EACA,EACAC,EACA,CACA,MAAO,CACL,WACE,EAAE,WACFP,GACEM,EAAO,KAAO,EAAE,OAAS,EAAE,WAC3BA,EAAO,EAAI,EAAE,OACbC,EAAK,KACP,EACF,WACE,EAAE,WACFP,GACEM,EAAO,KAAO,EAAE,OAAS,EAAE,WAC3BA,EAAO,EAAI,EAAE,OACbC,EAAK,MACP,CACJ,CACF,CAEO,SAASC,GACdF,EACA,EACAC,EACA,CACA,IAAME,EAAOH,EAAO,KAAO,EAAE,OAAS,EAAE,WAClCI,EAAMJ,EAAO,KAAO,EAAE,OAAS,EAAE,WACvC,OACEG,EAAOF,EAAK,OACZE,EAAOH,EAAO,EAAI,EAAE,OAAS,GAC7BI,EAAMH,EAAK,QACXG,EAAMJ,EAAO,EAAI,EAAE,OAAS,CAEhC,CzB3BO,IAAMK,GAAqBC,GAC/B,QAAQC,IAAS,CAGhB,mBAAoB,CAClB,IAAMC,EAASD,EAAK,aACdE,EAAOF,EAAK,QAClB,GACE,CAACC,GACDD,EAAK,gBAAkB,OACvB,CAACA,EAAK,cACNE,EAAK,OAAS,GACdA,EAAK,QAAU,EAEf,OAEF,IAAMC,EAAIC,GAAWH,EAAQD,EAAME,CAAI,EACnCF,EAAK,gBAAkB,SACzBA,EAAK,WAAaG,EAAE,YAEtBH,EAAK,WAAaG,EAAE,UACtB,CACF,EAAE,EACD,QAAQH,IAAS,CAChB,SAASK,EAAgB,CACvBL,EAAK,MAAQK,EACbL,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,eAAgB,CACdA,EAAK,UAAY,GACjBA,EAAK,cAAgB,EACvB,EACA,iBAAiBM,EAAiB,CAChCN,EAAK,cAAgBM,CACvB,EACA,WAAWC,EAAY,CACrBP,EAAK,YAAcO,CACrB,EACA,YAAYA,EAAY,CACtBP,EAAK,aAAeO,CACtB,EACA,mBACEA,EACAC,EACAC,EACA,CACAT,EAAK,eAAiBO,EACtBP,EAAK,wBAA0BQ,EAC/BR,EAAK,cAAgB,CAAE,GAAGS,EAAO,cAAeT,EAAK,aAAc,EACnEA,EAAK,iBACP,EACA,aAAc,CACZA,EAAK,gBAAkBA,EAAK,aAC9B,EACA,iBAAiBU,EAAiB,CAChCV,EAAK,cAAgBU,CACvB,EACA,gBAAgBC,EAA0B,CACxCX,EAAK,aAAeW,CACtB,EACA,gBAAgBC,EAAiB,CAC/BZ,EAAK,aAAeY,CACtB,EACA,cAAcC,EAAuB,CACnCb,EAAK,WAAaa,CACpB,EACA,oBAAoBC,EAAoB,CACtCd,EAAK,iBAAmBc,CAC1B,EAKA,iBAAiBC,EAAc,CAC7Bf,EAAK,cAAgBe,EACrB,IAAMC,EAAQhB,EAAK,MACnB,GAAIgB,GAAO,aAAe,QAAS,CACjC,IAAMC,EAAaC,GAAgBF,EAAOD,CAAI,EAC9CI,GAAa,QAAQH,EAAOC,CAAU,EACtCjB,EAAK,MAAQiB,CACf,CACF,EACA,aAAaG,EAAe,CAC1BpB,EAAK,UAAYoB,CACnB,EACA,YAAYC,EAAe,CACzBrB,EAAK,SAAWqB,CAClB,EACA,eAAeC,EAAqB,CAClCtB,EAAK,YAAcsB,CACrB,EACA,gBAAgBC,EAAsB,CACpCvB,EAAK,aAAeuB,CACtB,EACA,iBAAiBC,EAAe,CAC9BxB,EAAK,cAAgBwB,CACvB,EACA,aAAaC,EAAkB,CAC7BzB,EAAK,UAAYyB,CACnB,EACA,eAAeJ,EAAe,CAC5BrB,EAAK,YAAcqB,CACrB,EACA,qBAAqBA,EAAe,CAClCrB,EAAK,kBAAoBqB,CAC3B,EACA,aAAaA,EAAe,CAC1BrB,EAAK,UAAYqB,CACnB,EACA,sBAAsBA,EAAe,CACnCrB,EAAK,mBAAqBqB,CAC5B,EACA,eAAeK,EAAY,CACzB1B,EAAK,YAAc0B,CACrB,EACA,eAAeC,EAAiB,CAC9B3B,EAAK,YAAc2B,CACrB,EACA,iBAAiBA,EAAiB,CAChC3B,EAAK,cAAgB2B,CACvB,EACA,aAAaC,EAAa,CACxB5B,EAAK,UAAY4B,CACnB,EACA,cAAcC,EAAqB,CACjC7B,EAAK,WAAa6B,CACpB,EAGA,UAAUC,EAAiB,CACzB,IAAMC,EAAM,IAAI,IAAI/B,EAAK,WAAW,IAAIgC,GAAK,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACzDhC,EAAK,WAAa8B,EAAM,IAAIG,GAAQF,EAAI,IAAIE,CAAI,GAAK,CAAE,KAAAA,CAAK,CAAC,CAC/D,EAGA,SAASC,EAA8B,CACjCA,IAAUlC,EAAK,MAAM,QACvBA,EAAK,MAAM,OAAS,CAAC,GAEvBA,EAAK,MAAM,MAAQkC,CACrB,EACA,gBAAgBC,EAA6B,CAC3CnC,EAAK,MAAM,QAAUmC,CACvB,EACA,WAAWF,EAAc,CACvB,IAAMJ,EAAS7B,EAAK,WACpBA,EAAK,WAAa6B,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,CACvDpC,EAAK,WAAaA,EAAK,WAAW,IAAIgC,GACpCA,EAAE,OAASC,EAAO,CAAE,GAAGD,EAAG,MAAO,CAAE,GAAGA,EAAE,MAAO,GAAGI,CAAM,CAAE,EAAIJ,CAChE,CACF,EAKA,cAAcK,EAAwB,CACpCrC,EAAK,WAAaqC,CACpB,EACA,kBAAkBC,EAA+B,CAC/CtC,EAAK,eAAiBsC,CACxB,EACA,kBAAkBC,EAAqC,CACrDvC,EAAK,eAAiBuC,CACxB,EASA,mBAAmBC,EAAgB,CACjC,IAAMC,EAASzC,EAAK,gBAElByC,IAAW,QACXC,GAAS,CAAC,MAAG,eAAW1C,CAAI,EAAE,KAAK,CAAC,EAAE,KACpCE,GAASA,EAA0B,KAAOuC,CAC5C,IAEAzC,EAAK,gBAAkBwC,EAE3B,EACA,eAAeG,EAAuB,CACpC3C,EAAK,YAAc2C,CACrB,EACA,mBAAmBC,EAAiB,CAC9BA,EAAM,KAAK;AAAA,CAAI,IAAM5C,EAAK,gBAAgB,KAAK;AAAA,CAAI,IACrDA,EAAK,gBAAkB4C,EAE3B,EACA,kBAAkB7B,EAAqB,CACrCf,EAAK,eAAiBe,CACxB,EACA,iBAAiB8B,EAAgC,CAC/C7C,EAAK,cAAgB6C,CACvB,EACA,iBAAiBC,EAAiB,CAChC9C,EAAK,cAAgB8C,CACvB,EACA,aAAazB,EAAe,CAC1BrB,EAAK,UAAYqB,EACjBrB,EAAK,WAAa,IACpB,EAGA,cAAc+C,EAA+C,CAC3D/C,EAAK,WAAa+C,EAClB,IAAMC,EAAOhD,EAAK,cACZiD,EAAQjD,EAAK,eACbkD,EACJH,GAASC,EACL,CAACA,EAAK,UAAW,GAAGA,EAAK,IAAI,EAAE,KAAKG,GAAKA,EAAE,OAASJ,EAAM,GAAG,EAC7D,OACAK,EACJF,GAAOD,GAASjD,EAAK,MACjBqD,GAAUrD,EAAK,MAAOkD,EAAKH,EAAO,OAAQE,EAAM,MAAM,EACtD,OACNjD,EAAK,YAAcoD,GAAQ,IAC7B,EACA,cAAcE,EAAyC,CACrDtD,EAAK,WAAasD,CACpB,EACA,eAAeC,EAAwB,CACrCvD,EAAK,YAAcuD,CACrB,EACA,gBAAgBZ,EAAuB,CACrC3C,EAAK,aAAe2C,CACtB,EACA,gBAAgBA,EAAuB,CACrC3C,EAAK,aAAe2C,CACtB,EACA,WAAWa,EAAkB,CAC3BxD,EAAK,UAAYwD,CACnB,EACA,cAAe,CACbxD,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,gBAAgB2C,EAAgB,CAC9B,IAAMS,EAAOpD,EAAK,UAAU,IAAI2C,CAAM,EAChCc,EAAWzD,EAAK,SAChB0D,EAAY1D,EAAK,cACvB,GAAIoD,GAAQK,GAAYC,EAAW,CACjC,IAAMC,KAAU,eAAW3D,CAAI,EACzB4D,EAAS5D,EAAK,YAId6D,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,EAAInE,EACbA,EAAK,gBAAkB,QAAUmE,EACnCA,EAAK,iBAAiBnE,EAAK,WAAaiE,CAAE,GAE1CjE,EAAK,cAAgB,OACrBA,EAAK,MAAQoE,GAAUJ,CAAC,EACxBhE,EAAK,WAAaiE,GAEpBjE,EAAK,WAAakE,EAClBlE,EAAK,kBAAkB,CACzB,EACA,KAAKqE,EAAgBC,EAAiBC,EAAiB,CACrD,GAAM,CAAE,KAAAJ,CAAK,EAAInE,EACjB,GAAIA,EAAK,gBAAkB,QAAUmE,EAAM,CACzCA,EAAK,OAAOA,EAAK,QAAUE,EAAQC,CAAO,EAC1C,MACF,CACAtE,EAAK,cAAgB,OACrB,IAAMG,EAAIqE,GAAUxE,EAAMqE,EAAQC,EAASC,EAASvE,EAAK,SAAS,EAClEA,EAAK,MAAQG,EAAE,MACfH,EAAK,WAAaG,EAAE,WACpBH,EAAK,WAAaG,EAAE,WACpBH,EAAK,kBAAkB,CACzB,EACA,kBAAmB,CACjBA,EAAK,uBAAyB,GAC9BA,EAAK,eACP,EAEA,mBAAoB,CAClBA,EAAK,kBACP,EACA,WAAY,CAEV,GAAIA,EAAK,gBAAkB,OAAQ,CACjC,IAAMC,EAASD,EAAK,aACdyE,EAAUzE,EAAK,YAAc,OAC7B0E,EAAMD,EAAUE,GAAeC,EAC/BC,EAASJ,EAAUE,GAAe3E,EAAK,UACvC8E,EAAe9E,EAAK,QAAQ,OAAS6E,EAASH,EAChDzE,GAAU6E,EAAe,IAC3B9E,EAAK,WAAa+E,GAChB9E,EACA6E,EACA9E,EAAK,OACL6E,CACF,GAEF,MACF,CAIA,IAAMG,EAAMhF,EAAK,gBACbgF,IACFhF,EAAK,MAAQgF,EAAI,MACjBhF,EAAK,WAAagF,EAAI,WACtBhF,EAAK,WAAagF,EAAI,WAE1B,EACA,kBAAmB,CACjBhF,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,eAAiB,OACtBA,EAAK,wBAA0B,OAC/BA,EAAK,cAAgB,MACvB,CACF,EAAE,EACD,QAAQA,IAAS,CAIhB,cAAciF,EAAeC,EAAoB,CAC/C,IAAMC,EAAWnF,EAAK,gBAAkB,OACpCmF,IACFnF,EAAK,cAAgB,QAEvBA,EAAK,MAAQiF,EACbjF,EAAK,WAAakF,EACdC,GACFnF,EAAK,UAAU,CAEnB,EAOA,gBAAgBoF,EAAoC,CAClD,IAAMnF,EAASD,EAAK,aACpB,GACEA,EAAK,gBAAkB,QACvB,CAACC,GACDmF,IAAapF,EAAK,aAElB,OAEF,IAAMqF,EAAYD,GAAU,gBAAkB,IAAQpF,EAAK,eAEzDoF,IAAa,QACZC,IACE,CAACrF,EAAK,cAAgBsF,GAASrF,EAAQD,EAAMA,EAAK,OAAO,GAE5DA,EAAK,kBAAkB,GAEvBA,EAAK,cAAgB,MACrBA,EAAK,UAAU,EAEnB,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,SAASuF,GAAwB,CAC/B,aAAavF,EAAK,kBAAkB,EACpCA,EAAK,uBAAyB,GAC9BA,EAAK,mBAAqB,WAAW,IAAM,IACrC,YAAQA,CAAI,GACdA,EAAK,iBAAiB,CAE1B,EAAGwF,EAAoB,CACzB,CAQA,SAASC,GAA6B,CACpC,qBAAqBzF,EAAK,mBAAmB,EAC7CA,EAAK,oBAAsB,sBAAsB,IAAM,IACjD,YAAQA,CAAI,GACdA,EAAK,kBAAkB,CAE3B,CAAC,CACH,CAEA,MAAO,CAsBL,SAAS2C,EAAgB+C,EAAYC,EAAY,CAC/C,IAAMC,EAAY5F,EAAK,cAAc,cACrC,GAAI4F,IAAYjD,CAAM,EAAG,CACvB,QAAWkD,KAAOD,EAAUjD,CAAM,EAChCkD,EAAI,GAAKH,EACTG,EAAI,GAAKF,EAEXF,EAA2B,CAC7B,CACF,EACA,sBAAAF,CACF,CACF,CAAC,ED3eI,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,OAAQR,EAAK,aACb,QAASA,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,EAEdC,EAEAC,EAEEC,EAAgB,IAAI,IAK1B,SAAUC,EAAWlB,EAAc,CACjC,IAAMN,EAAU,EAAEoB,EACZK,EAAS,IAAM7B,EAAK,QAAUU,GAASN,IAAYoB,EACnDM,EAAS7B,GAAgB,OAC3B8B,EACJ,GAAI,CAEF,GAAI/B,EAAK,gBAAkBU,EAAM,MAAM,OAASV,EAAK,cACnD,MAAM,IAAI,MACR,4BAA4BU,EAAM,MAAM,OAAO,eAAe,CAAC,iBAAiBV,EAAK,cAAc,eAAe,CAAC,oGACrH,EAEF+B,EAAW,MAAOtB,EAAcC,CAAK,CACvC,OAASsB,EAAG,CAMV,GAAI,CAACH,EAAO,GAAKC,GAAQ,QACvB,MAAO,GAET,MAAAL,EAAcO,EACRA,CACR,CACA,IAAMC,EAAOJ,EAAO,EACpB,GAAII,EAAM,CACJR,IAAgB,QAAazB,EAAK,QAAUyB,IAC9CzB,EAAK,MAAQ,QAEfyB,EAAc,OACd,IAAMS,EAAWlC,EAAK,aACtB0B,EAAehB,EACfV,EAAK,aAAe+B,EAAS,OAC7B/B,EAAK,YAAY+B,EAAS,QAAQ,EAClC/B,EAAK,gBAAgBkC,CAAQ,CAC/B,CACA,OAAOD,CACT,CAIA,SAASE,EAAgBzB,EAAcI,EAAwB,CAC7D,IAAMsB,EAAQ1B,EAAM,YACpB,OAAOA,EAAM,aAAe,SAAW0B,GAEjCC,GAAa3B,EAAOV,EAAK,kBAAkBc,EAAO,YAAY,CAAC,GAC/DwB,GAAoBF,EAAOtB,EAAO,YAAY,IAC7C,KACH,MACN,CAMA,SAAUyB,EACRC,EACAC,EACA3B,EACA4B,EAAgB,GAChBC,EACA,CACA,IAAMb,EAAS7B,GAAgB,OAC/BD,EAAK,iBAAiB,aAAa,EACnC,IAAM4C,EAASC,GAAUL,EAAMC,EAAM,CACnC,cAAezC,EAAK,eAAiBc,GAAQ,YAC/C,CAAC,EACKgC,EAAShC,EAASqB,EAAgBS,EAAQ9B,CAAM,EAAI,OACpDJ,EACJ,CAACV,EAAK,eACN8C,IAAW,QACXA,IAAWF,EAAO,cACdG,GAAgBH,EAAQE,CAAM,EAC9BF,EACN,GAAID,EAAS,CACX3C,EAAK,iBAAiB,oBAAoB,EAC1C,GAAI,CACF,GAAM,CAAE,QAAAgD,EAAS,MAAAC,CAAM,EAAK,MAAMN,EAAQjC,CAAK,EAC/CA,EAAM,MAAQsC,EACdhD,EAAK,WAAa,CAAE,MAAOgD,EAAQ,OAAQ,MAAAC,CAAM,CACnD,OAASjB,EAAG,CACV,GAAIF,GAAQ,QACV,OAEF,QAAQ,KAAK,4CAA6CE,CAAC,EAC3DhC,EAAK,WAAa,MACpB,CACA,GAAI8B,GAAQ,QACV,MAEJ,MACE9B,EAAK,WAAa,OAEpB,IAAMkD,EAAWR,EAAgB1C,EAAK,aAAe,KACrDA,EAAK,MAAQU,EACbV,EAAK,YAAcc,EACnBd,EAAK,oBAAsB8C,EAC3B9C,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxB2B,EAAc,MAAM,EACpB3B,EAAK,aAAe,OACpBA,EAAK,SAAW,CAAC,EAKjBA,EAAK,sBAAsB,EAGvBkD,IAAa,MAAQxC,EAAM,MAAM,KAAKyC,GAAKA,EAAE,KAAOD,CAAQ,IAC9DlD,EAAK,aAAekD,GAEtBlD,EAAK,iBAAiB,kBAAkB,EACxC,MAAO4B,EAAWlB,CAAK,CACzB,CAKA,IAAI0C,EAAW,EAGXC,EAEJ,SAASC,GAAY,CACnB,IAAMC,EAAO,EAAEH,EACf,OAAAnD,GAAgB,MAAM,EACtBA,EAAiB,IAAI,gBACrBoD,EAAeE,EACfvD,EAAK,aAAe,GACb,CACL,OAAQ,IAAMuD,IAASH,EACvB,OAAQnD,EAAe,MACzB,CACF,CAEA,SAASuD,GAAU,CACjBH,EAAe,OACfrD,EAAK,cAAc,CACrB,CAEA,SAASyD,GAAgB,CACnBJ,IAAiB,QACnBrD,EAAK,cAAc,CAEvB,CAQA,SAAU0D,EACRC,EACA7C,EACAe,EACAC,EACA,CAGA,IAAM8B,EAASC,GAAaF,CAAa,EACzC,GAAI,EAAAA,EAAc,OAAS,oBAAsBC,IAAW,QAG5D,GAAI,CACF,IAAME,EAAY,QAAM,cAAW9D,CAAI,EAAE,WAAW,QAClD,mBAAgBA,CAAI,EACpB,kBACA,CACE,cAAe,CACb,KAAM,yBACN,IAAK,GAAG4D,CAAM,kBACd,QAASD,EAAc,QACvB,oBAAqBA,EAAc,mBACrC,EACA,QAAS,CAAC7C,CAAM,EAChB,OAAAgB,CACF,CACF,EACA,GAAID,EAAO,EAAG,CACZ,IAAMkC,EAAUD,EAAS,IAAIE,IAAM,CACjC,QAASlD,EAAO,QAChB,MAAOkD,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,EAEI,CAACC,EAAW,GAAGC,CAAM,EAAIlE,EAAK,SAChCiE,EACFjE,EAAK,SAAW,CAAC,CAAE,GAAGiE,EAAW,aAAcF,CAAQ,EAAG,GAAGG,CAAM,EAEnElE,EAAK,aAAe+D,CAExB,CACF,OAAS/B,EAAG,CACV,QAAQ,KAAK,mDAAoDA,CAAC,CACpE,CACF,CAKA,SAAUmC,EACRC,EACAtD,EACAuD,EACAvC,EACA,CACA,IAAMwC,KAAU,cAAWtE,CAAI,EACzBuE,EAASH,EACXE,EAAQ,OAAO,KAAKE,GAAKA,EAAE,UAAYJ,CAAO,EAC9C,OACJ,GAAKG,EAGL,GAAI,CACF,OAAQ,MAAMD,EAAQ,WAAW,QAC/B,mBAAgBtE,CAAI,EACpB,kBACA,CACE,iBAAe,mBAAeuE,EAAQ,SAAS,EAC/C,QAAS,CAACzD,CAAM,EAChB,OAAAgB,CACF,CACF,CACF,OAASE,EAAG,CACV,QAAQ,KAAK,wBAAwBqC,CAAI,kBAAmBrC,CAAC,EAC7D,MACF,CACF,CAIA,SAAUyC,EACR3D,EACAe,EACAC,EACA,CACA,IAAMgC,EAAW,MAAOK,EACtBnE,EAAK,WAAW,QAChBc,EACA,QACAgB,CACF,EACIgC,GAAYjC,EAAO,IACrB7B,EAAK,kBAAoB8D,EAE7B,CAIA,SAAUY,EACR5D,EACAe,EACAC,EACA,CACA,IAAMgC,EAAW,MAAOK,EACtBnE,EAAK,aAAa,QAClBc,EACA,UACAgB,CACF,EACIgC,GAAYjC,EAAO,IACrB7B,EAAK,aAAe2E,GAAiBb,CAAQ,EAEjD,CAMA,SAAUc,EACRnC,EACAoC,EACA/D,EACA,CACA,GAAM,CAAE,OAAAe,EAAQ,OAAAC,CAAO,EAAIwB,EAAU,EACrCtD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACb,GAAI,CACF,IAAMwC,EACJ,OAAOqC,GAAW,SAAWA,EAAW,MAAMA,EAAO/C,CAAM,EACzDD,EAAO,IACT,MAAOU,EAAeC,EAAMC,EAAM3B,CAAM,EAE5C,OAASkB,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,iCAAkCG,CAAC,EACjDhC,EAAK,MAAQgC,EAEjB,QAAE,CACIH,EAAO,GACT2B,EAAQ,CAEZ,CACA,OAAO3B,EAAO,CAChB,CAEA,SAASiD,GAAY,CACnB7E,GAAgB,MAAM,EACtBA,EAAiB,OACjBoD,EAAe,OACfD,IACA5B,GACF,CAIA,SAASuD,GAAY,CACnBD,EAAU,EACV9E,EAAK,MAAQ,OACbA,EAAK,YAAc,OACnBA,EAAK,oBAAsB,OAC3BA,EAAK,aAAe,OACpBA,EAAK,aAAe,OACpBA,EAAK,kBAAoB,OACzBA,EAAK,iBAAmB,OACxB2B,EAAc,MAAM,EACpB3B,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,EAElBA,EAAK,gBAAkB,SACzBA,EAAK,cAAgB,MAEzB,CAEA,MAAO,CAEL,YAAa,CACX+E,EAAU,CACZ,EAGA,YAAa,CACP/E,EAAK,gBACP+E,EAAU,EACV/E,EAAK,aAAe,GAExB,EAEA,UAAW,CACT8E,EAAU,EAEN9E,EAAK,QAAU0B,IACjB1B,EAAK,aAAe,QAEtBA,EAAK,UAAY,GACjBA,EAAK,cAAgB,GACrBA,EAAK,aAAe,EACtB,EACA,eAAgB,CACd8E,EAAU,CACZ,EACA,WAAS,QAAK,UAAWtC,EAAcC,EAAO,eAAgB,CAC5D,MAAOmC,EAAanC,EAAMD,CAAI,CAChC,CAAC,EACD,uBAAqB,QAAK,UACxBwC,EACAlE,EACA,CACAd,EAAK,iBAAiB,cAAc,EACpC,IAAMiC,EAAO,MAAO2C,EAClBK,GAASD,CAAQ,GAAK,MACtBlD,MAAU,iBAAakD,CAAQ,EAAE,SAAS,CAAE,SAAU,OAAQ,OAAAlD,CAAO,CAAC,EACtEhB,CACF,EACA,GAAIA,GAAUmB,GAAQjC,EAAK,MAAO,CAChC,IAAM6B,EAAS,IAAM7B,EAAK,cAAgBc,EAC1C,MAAM,QAAQ,IAAI,IAChB,QAAK2D,CAAS,EAAE3D,EAAQe,CAAM,KAC9B,QAAK6C,CAAW,EAAE5D,EAAQe,CAAM,CAClC,CAAC,CACH,CACF,CAAC,EAID,eAAa,QAAK,UAChB8B,EACA7C,EACAoE,EAA2B,CAAC,EAC5B,CACA,GAAM,CAAE,OAAArD,EAAQ,OAAAC,CAAO,EAAIwB,EAAU,EACrCtD,EAAK,UAAY,GACjBA,EAAK,MAAQ,OACbA,EAAK,iBAAiB,mBAAmB,EACzC,GAAI,CACF,IAAMmF,EAAa,YAAY,IAAI,EAC7BC,EAAW,QAAM,cAAWpF,CAAI,EAAE,WAAW,QACjD,mBAAgBA,CAAI,EACpB,cACA,CAAE,cAAA2D,EAAe,OAAA7C,EAAQ,KAAAoE,EAAM,OAAApD,CAAO,CACxC,EACA,GAAI,CAACD,EAAO,EACV,OAGF,GADA7B,EAAK,WAAW,YAAY,IAAI,EAAImF,CAAU,EAC1C,CAACC,EACH,MAAM,IAAI,MACR,iHACF,EAoBF,GAlBA,MAAO7C,EACL6C,EACAC,GAASvE,CAAM,EACfA,EACA,GACAwE,GAAW3B,CAAa,EACpBjD,MACE,cAAWV,CAAI,EAAE,WAAW,QAC1B,mBAAgBA,CAAI,EACpB,gBACA,CACE,cAAA2D,EACA,UAAWjD,EAAM,MAAM,IAAIyC,GAAKA,EAAE,IAAI,EACtC,OAAArB,CACF,CACF,EACF,MACN,EACI,CAACD,EAAO,EACV,OAKF7B,EAAK,iBAAiB,qBAAqB,EAC3C,MAAM,QAAQ,IAAI,CAChBkF,EAAK,OAAS,SACV,UACA,QAAKxB,CAAW,EAAEC,EAAe7C,EAAQe,EAAQC,CAAM,KAC3D,QAAK2C,CAAS,EAAE3D,EAAQe,EAAQC,CAAM,KACtC,QAAK4C,CAAW,EAAE5D,EAAQe,EAAQC,CAAM,CAC1C,CAAC,CACH,OAASE,EAAG,CACNH,EAAO,IACT,QAAQ,MAAM,gCAAiCG,CAAC,EAChDhC,EAAK,MAAQgC,EAEjB,QAAE,CACIH,EAAO,GACT2B,EAAQ,CAEZ,CACF,CAAC,EAKD,iBAAe,QAAK,WAAa,CAC/B,IAAM1C,EAASd,EAAK,YACdoE,EAAUpE,EAAK,aAAa,QAC9Bc,IACFd,EAAK,aAAe,OACpB,MAAO0E,EACL5D,EACA,IACEd,EAAK,cAAgBc,GACrBd,EAAK,aAAa,UAAYoE,CAClC,EAEJ,CAAC,EAGD,0BAAwB,QAAK,WAAa,CACxC,IAAMY,EAAWhF,EAAK,kBAChBuF,EAAMP,EAAW,KAAK,UAAUA,CAAQ,EAAI,OAClD,GAAIO,IAAQrF,IAGZA,EAAiBqF,EACjBvF,EAAK,mBAAqB,OACtB,EAACgF,GAGL,GAAI,CACF,IAAMxC,EAAQ,QAAM,iBAAawC,CAAQ,EAAE,SAAS,MAAM,KACtD,WAAQhF,CAAI,GAAKuF,IAAQrF,IAC3BF,EAAK,mBAAqBwF,GAAgBhD,CAAI,EAElD,OAASR,EAAG,IACN,WAAQhC,CAAI,GAAKuF,IAAQrF,MAC3B,cAAWF,CAAI,EAAE,OACf,gEAAgE,OAAOgC,CAAC,CAAC,IACzE,SACF,CAEJ,CACF,CAAC,EAID,iBAAe,QAAK,WAAa,CAC/B,IAAMyD,EAAQzF,EAAK,eAAe,OAAS,CAAC,EACtCuF,EAAM,KAAK,UAAUE,CAAK,EAC1B/E,EAAQV,EAAK,MACb0F,EAAU,IAAI,IACpB,MAAM,QAAQ,IACZD,EAAM,IAAI,CAAC,CAAE,IAAAE,EAAK,QAAAvB,EAAS,OAAAtD,CAAO,OAChC,QAAK,WAAa,CAChB,IAAM8E,EAAW,GAAGxB,CAAO,IAAItD,EAAO,OAAO,IAAIA,EAAO,KAAK,IAAIA,EAAO,GAAG,GACvE+E,EAAQlE,EAAc,IAAIiE,CAAQ,EACtC,GAAI,CAACC,EAAO,CACV,IAAM/B,EAAW,MAAOK,EACtBC,EACAtD,EACA,iBACF,EACA,GAAI,CAACgD,EACH,OAEF+B,EAAQC,GAAehC,CAAQ,EAAE,IAAIiC,IAAM,CACzC,GAAGA,EACH,QAASjF,EAAO,OAClB,EAAE,EACFa,EAAc,IAAIiE,EAAUC,CAAK,CACnC,CACAH,EAAQ,IAAIC,EAAKE,CAAK,CACxB,CAAC,EAAE,CACL,CACF,KAEE,WAAQ7F,CAAI,GACZA,EAAK,QAAUU,GACf,KAAK,UAAUV,EAAK,eAAe,OAAS,CAAC,CAAC,IAAMuF,IAEpDvF,EAAK,iBAAmByF,EAAM,OAASC,EAAU,OAErD,CAAC,EACD,eAAa,QAAK,WAAa,CAC7B/D,EAAc,MAAM,EACpB,IAAMb,EAASd,EAAK,YACdoE,EAAUpE,EAAK,WAAW,QAC5Bc,IACFd,EAAK,kBAAoB,OACzB,MAAOyE,EACL3D,EACA,IACEd,EAAK,cAAgBc,GAAUd,EAAK,WAAW,UAAYoE,CAC/D,EAEJ,CAAC,EAKD,aAAW,QAAK,UAAW4B,EAAyB,CAClD,IAAMtF,EAAQV,EAAK,MACnB,GAAI,CAACU,EACH,OAEF,IAAMuF,EAAMC,GAAexF,EAAOyF,GAAiBH,CAAM,CAAC,EAC1D,GAAIC,EAAI,MAAM,SAAW,EAAG,IAC1B,cAAWjG,CAAI,EAAE,OACf,yFACA,MACF,EACA,MACF,CACAA,EAAK,SAAW,CACd,GAAGA,EAAK,SACR,CACE,MAAAU,EACA,WAAYV,EAAK,WACjB,MAAOU,EAAM,KACb,aAAcV,EAAK,YACrB,CACF,EACAA,EAAK,aAAe,OACpB,IAAMoG,EAAQ,GAAGC,GAAkBC,GAAeN,EAAQhG,EAAK,YAAY,EAAE,IAAI,CAAC,OAAOgG,EAAO,OAAO,IAAIA,EAAO,MAAM,eAAe,CAAC,GACxIhG,EAAK,MAAQ,CAAE,GAAGiG,EAAK,KAAMG,CAAM,EACnCpG,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO4B,EAAW5B,EAAK,KAAK,IAC9ByD,EAAc,CAElB,OAASzB,EAAG,CACVhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,CACF,CAAC,EACD,eAAa,QAAK,WAAa,CAC7B,IAAM8C,EAAOvG,EAAK,WAClB,GAAKuG,EAGL,CAAAvG,EAAK,SAAWA,EAAK,SAAS,MAAM,EAAG,EAAE,EACzCA,EAAK,MAAQuG,EAAK,MAClBvG,EAAK,WAAauG,EAAK,WACvBvG,EAAK,aAAeuG,EAAK,aACzBvG,EAAK,sBAAsB,EAC3BA,EAAK,cAAgB,MACrBA,EAAK,UAAY,GACjB,GAAI,EACE,MAAO4B,EAAW2E,EAAK,KAAK,IAC9B9C,EAAc,CAElB,OAASzB,EAAG,CACVhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,EACF,CAAC,EACD,mBAAiB,QAAK,WAAa,CACjC,IAAM/C,EAAQV,EAAK,MACnB,GAAKU,EAGL,CAAAV,EAAK,UAAY,GACjBA,EAAK,iBAAiB,kBAAkB,EAExC,GAAI,EAKE,MAAO4B,EAAWlB,CAAK,IACzB+C,EAAc,CAElB,OAASzB,EAAG,CACV,QAAQ,MAAM,oCAAqCA,CAAC,EACpDhC,EAAK,MAAQgC,EACbyB,EAAc,CAChB,EACF,CAAC,CACH,CACF,CAAC,E2BpuBD,SAAS+C,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,KAGA,gBACEA,KACA,YACE,IAAM,GAAGA,EAAK,QAAQ,KAAK,IAAIA,EAAK,QAAQ,MAAM,GAClD,IAAM,CACJA,EAAK,kBAAkB,CACzB,CACF,CACF,KACA,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,SAAWA,EAAK,YACrC,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,EiC9SJ,IAAAyB,GAA+B,SAM/B,IAAMC,GAAwB,eAmBvB,SAASC,GAAa,CAC3B,QAAAC,EACA,aAAAC,EACA,MAAAC,CACF,EAIG,CACD,IAAMC,EAASC,GAAsBJ,EAASC,CAAY,EACpDI,EAAkB,CAAC,EACzB,QAAWC,KAASN,EAAQ,OAAQ,CAClC,IAAMO,KAAgB,mBAAeD,EAAO,MAAM,EAC5CE,KAAyB,mBAAeF,EAAO,eAAe,EAC9DG,KAAmB,mBAAeH,EAAO,SAAS,EAEtDC,IAAST,IACT,MAAM,QAAQU,CAAa,GAC3BA,EAAc,KACZE,GACE,OAAOA,GAAS,UAChBN,GAAsBJ,EAASU,CAAI,IAAMP,CAC7C,GACA,OAAOM,GAAY,UACnBA,IAAYP,GAEZG,EAAM,KAAKI,CAAO,CAEtB,CACA,OAAOP,EAAQ,CAACA,EAAO,GAAGG,CAAK,EAAIA,CACrC,CCvDA,IAAAM,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,CxCuBO,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,CAGd,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,EAEA,sBAAsB,CAAE,OAAAC,EAAS,EAAK,EAAI,CAAC,EAAe,CACxD,MAAO,CACL,GAAIC,GAAe,IAAItB,EAAK,gBAAgB,EACxC,CACE,CACE,MAAO,gBACP,QAASuB,GAAe,IAAI,CAAC,CAAE,GAAAC,EAAI,MAAAC,CAAM,KAAO,CAC9C,KAAM,QACN,MAAAA,EACA,QAASzB,EAAK,cAAgBwB,EAC9B,SAAUA,EAAK,GAAKxB,EAAK,OAAO,QAAU,OAC1C,QAAS,IAAM,CACbA,EAAK,eAAewB,CAAE,EACjBxB,EAAK,gBAAgB,CAC5B,CACF,EAAE,CACJ,CACF,EACA,CAAC,EACL,GAAIqB,GACJrB,EAAK,mBAAqB,YAC1BA,EAAK,cAAc,OAAS,EACxB,CACE,CACE,MAAO,SACP,QAAS,CACP,CACE,KAAM,QACN,MAAO,eACP,QAAS,CAACA,EAAK,eACf,QAAS,IAAM,CACbA,EAAK,aAAa,EAAE,CACtB,CACF,EACA,GAAGA,EAAK,cAAc,IAAI,CAAC,CAAE,IAAA0B,EAAK,KAAAC,EAAM,KAAAC,CAAK,KAAO,CAClD,KAAM,QACN,MAAO,GAAGD,CAAI,SAAMC,EAAK,eAAe,CAAC,WACzC,QAAS5B,EAAK,YAAc0B,EAC5B,QAAS,IAAM,CACb1B,EAAK,aAAa0B,CAAG,CACvB,CACF,EAAE,CACJ,CACF,CACF,EACA,CAAC,EACL,GAAI1B,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,cAAe,QAAS,KAAK,sBAAsB,CAAE,CAAC,EAChE,CAAC,CACP,CACF,EACA,eAA4B,CAC1B,MAAO,CACL,CACE,KAAM,WACN,MAAO,oBACP,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,uBACP,QAASA,EAAK,uBACd,QAAS,IAAM,CACbA,EAAK,oBAAoB,CAACA,EAAK,sBAAsB,CACvD,CACF,EACA,CACE,KAAM,WACN,MAAO,6BACP,QAASA,EAAK,UACd,QAAS,IAAM,CACbA,EAAK,aAAa,CAACA,EAAK,SAAS,CACnC,CACF,EACA,GAAIA,EAAK,sBACL,CACE,CACE,KAAM,WACN,MAAO,uBACP,QAASA,EAAK,mBACd,QAAS,IAAM,CACbA,EAAK,sBAAsB,CAACA,EAAK,kBAAkB,CACrD,CACF,CACF,EACA,CAAC,CACP,CACF,EACA,iBAA8B,CAC5B,MAAO,CACL,CACE,MAAO,aACP,KAAM6B,GACN,SAAU7B,EAAK,oBAAsB,OACrC,iBAAkBA,EAAK,kBACvB,QAAS,IAAM,CACb,IAAM8B,EAAM9B,EAAK,OAAO,EACpB8B,GACFC,GACED,EACA,IAAI9B,EAAK,OAAO,MAAQ,SAAS,WAAW,YAAa,GAAG,CAAC,MAC/D,CAEJ,CACF,EACA,CACE,MAAO,mBACP,KAAMgC,GACN,SAAUhC,EAAK,wBAA0B,OACzC,iBAAkBA,EAAK,sBACvB,QAAS,IAAM,CACb,IAAMiC,EAAOjC,EAAK,WAAW,EACvBE,KAAU,eAAWF,CAAI,EAC/B,UAAU,UACP,UAAU,GAAG,KAAK,UAAUiC,EAAM,KAAM,CAAC,CAAC;AAAA,CAAI,EAC9C,KAAK,IAAM,CACV/B,EAAQ,OACN,wHACA,MACF,CACF,CAAC,EACA,MAAOgC,GAAe,CACrBhC,EAAQ,OAAO,mCAAmC,OAAOgC,CAAC,CAAC,EAAE,CAC/D,CAAC,CACL,CACF,CACF,CACF,EAGA,mBAAmB,CAAE,MAAAC,EAAQ,EAAK,EAAI,CAAC,EAAe,CACpD,IAAMC,EAAQD,EAAQnC,EAAK,YAAc,CAAC,EAC1C,GACEA,EAAK,YAAY,SAAW,GAC5B,CAACA,EAAK,YACL,CAACmC,GAASnC,EAAK,WAAW,SAAW,EAEtC,MAAO,CAAC,EAEV,IAAMqC,EAAUV,GACd3B,EAAK,WAAW,KAAKsC,GAAKA,EAAE,OAASX,CAAI,EACrCY,EAAOH,EAAM,OAASI,GAC5B,MAAO,CACL,CAAE,KAAM,YAAa,MAAO,WAAY,EACxC,GAAID,EACA,CACE,CACE,MAAO,uBACP,QAAS,IAAM,IACb,eAAWvC,CAAI,EAAE,YAAYiB,GAAW,CACtCwB,GACA,CAAE,MAAOzC,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,EACA,CAAC,EACL,IAAIsB,EAAOH,EAAM,OAAOM,GAAQL,EAAOK,EAAK,IAAI,CAAC,EAAIN,GAAO,IAC1DM,IAAS,CACP,KAAM,WACN,MAAOA,EAAK,MACZ,QAASL,EAAOK,EAAK,IAAI,EACzB,QAAS,IAAM,CACb1C,EAAK,WAAW0C,EAAK,IAAI,CAC3B,CACF,EACF,EACA,CACE,MAAO,mBACP,SAAU1C,EAAK,WAAW,SAAW,EACrC,QAAS,IAAM,CACbA,EAAK,cAAc,CAAC,CAAC,CACvB,CACF,EACA,GAAIA,EAAK,WAAW,OAAS,EACzB,CACE,CACE,MAAO,uBACP,QAAS,IAAM,IACb,eAAWA,CAAI,EAAE,YAAYiB,GAAW,CACtC0B,GACA,CAAE,MAAO3C,EAAM,QAAAiB,CAAQ,CACzB,CAAC,CACH,CACF,CACF,EACA,CAAC,EACL,GAAIjB,EAAK,WAAW,OAAS,GAAKA,EAAK,eACnC,CACE,CAAE,KAAM,YAAsB,MAAO,SAAU,EAC/C,GAAG4C,GAAa,IAAI,CAAC,CAAE,MAAAC,EAAO,MAAApB,CAAM,KAAO,CACzC,KAAM,QACN,MAAOoB,IAAU,OAAS,wBAA0BpB,EACpD,QAASzB,EAAK,MAAM,QAAU6C,EAC9B,QAAS,IAAM,CACb7C,EAAK,SAAS6C,CAAK,CACrB,CACF,EAAE,CACJ,EACA,CAAC,CACP,CACF,EACA,iBAAiBA,EAA4B,CAC3C,IAAMpB,EAAQqB,GAAc,KAAKC,GAAKA,EAAE,QAAUF,CAAK,GAAG,OAASA,EACnE,OAAOA,IAAU,OACb,GAAGpB,CAAK,KAAK,KAAK,iBAAiBzB,EAAK,oBAAoB,CAAC,IAC7DyB,CACN,EACA,gBAA6B,CAC3B,IAAMuB,EAAU,KAAK,sBAAsB,EAC3C,MAAO,CACL,CACE,MAAO,WAAWC,EAAkBjD,EAAK,gBAAgB,EAAE,MAAM,QAAQ,WAAY,EAAE,CAAC,GACxF,KAAMkD,GACN,QAAS,CACP,GAAGC,GAAa,IAAIC,IAAS,CAC3B,KAAM,QACN,MAAOA,EAAK,MACZ,QAASpD,EAAK,mBAAqBoD,EAAK,MACxC,SAAUpD,EAAK,MAAQ,CAACoD,EAAK,UAAUpD,EAAK,KAAK,EAAI,GACrD,iBAAkBoD,EAAK,YACvB,QAAS,IAAM,CACRpD,EAAK,aAAaoD,EAAK,KAAK,CACnC,CACF,EAAE,EACF,GAAIJ,EAAQ,OAAS,EACjB,CAAC,CAAE,KAAM,SAAmB,EAAG,GAAGA,CAAO,EACzC,CAAC,EACL,GAAIhD,EAAK,YACL,CAAC,EACD,CACE,CAAE,KAAM,SAAmB,EAC3B,CACE,MAAO,cACP,QAAS,IAAM,CACbA,EAAK,UAAU,CACjB,CACF,CACF,CACN,CACF,EACA,CACE,MAAO,UAAU,KAAK,iBAAiBA,EAAK,iBAAiB,CAAC,GAC9D,KAAMqD,GACN,QAASP,GAAc,IAAIQ,IAAW,CACpC,KAAM,QACN,MAAO,KAAK,iBAAiBA,EAAO,KAAK,EACzC,QAAStD,EAAK,oBAAsBsD,EAAO,MAC3C,QAAS,IAAM,CACbtD,EAAK,eAAesD,EAAO,KAAK,CAClC,CACF,EAAE,CACJ,EACA,CACE,MAAO,UACP,KAAMC,GACN,QAAS,KAAK,cAAc,CAC9B,CACF,CACF,EAEA,iBAA8B,CAC5B,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQC,GAAqB,CACtC,aAAc1D,EAAK,qBACnB,cAAeA,EAAK,oBACpB,aAAcC,GAAU,CACtBD,EAAK,iBAAiBC,CAAM,CAC9B,EACA,cAAeO,GAAW,CACxBR,EAAK,gBAAgBQ,CAAO,CAC9B,CACF,CAAC,KACC,2BAAuBgD,EAAOC,CAAI,EAEpC,OAAOD,CACT,CACF,EAAE,EyC7bG,SAASG,IAAiB,CAC/B,OAAOC,EACT,C1CUe,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,SAAS,KAAO,CACf,cAAe,EACjB,EAAE,EACD,QAAQC,GAAQ,CACf,IAAMC,EAAeD,EAAK,SAC1B,MAAO,CACL,SAASE,EAAe,CACtBD,EAAaC,CAAK,EAClBF,EAAK,cAAgB,EACvB,CACF,CACF,CAAC,EACA,MAAMA,IAAS,CACd,IAAI,cAAe,CACjB,OAAOA,EAAK,EACd,EAEA,IAAI,WAAY,CACd,OAAOA,EAAK,KACd,EAEA,IAAI,cAAe,CACjB,OAAOA,EAAK,aACd,EAEA,IAAI,eAAgB,CAClB,IAAMG,EAAQ,KAAK,YACnB,OACEH,EAAK,qBACJG,EACGC,GAAiBC,GAAmBL,EAAMG,CAAK,CAAC,EAChD,OAER,EACA,IAAI,mBAAoB,CACtB,OAAOH,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,MAAO,CAAC,GAAGA,EAAK,gBAAgB,EAAG,GAAGA,EAAK,gBAAgB,CAAC,CAC9D,CACF,EAAE,EACD,QAAQA,GAAQ,CACf,IAAMM,EAAYN,EAAK,WACvB,MAAO,CAGL,YAAa,CACXM,EAAU,EACVN,EAAK,YAAc,OACnBA,EAAK,aAAe,OACpBA,EAAK,cAAgB,EACvB,EACA,MAAO,CACL,IAAMO,EAASP,EAAK,aACpB,GAAIA,EAAK,YAEP,OAAKA,EAAK,aACRA,EAAK,eAAeQ,GAASR,EAAK,WAAW,CAAC,EAEzCA,EAAK,oBAAoBA,EAAK,YAAaO,CAAM,EAE1D,GAAI,CAACP,EAAK,eAAiB,CAACO,EAC1B,OAEF,IAAMJ,EAAQH,EAAK,YACbS,EAAOF,EAAO,IAAMA,EAAO,MAC3BG,EAAUP,EACZQ,GACEC,GAAuBT,CAAK,EAC5BI,EAAO,YACT,EACA,OACJ,GAAI,CAACJ,EACHH,EAAK,SACH,IAAI,MACF,uCAAuCA,EAAK,aAAa,2BAC3D,CACF,UACSU,EACTV,EAAK,SAAS,IAAI,MAAMU,CAAO,CAAC,UACvBD,EAAOT,EAAK,YACrBA,EAAK,SACH,IAAI,MACF,qBAAqBa,GAAaJ,CAAI,CAAC,uCAAkCI,GAAab,EAAK,WAAW,CAAC,GACzG,CACF,MAEA,QAAOA,EAAK,YAAYK,GAAmBL,EAAMG,CAAK,EAAGI,EAAQ,CAC/D,KAAMP,EAAK,gBACX,WAAYA,EAAK,cACjB,GAAIA,EAAK,eACL,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CAGL,CACF,CACF,CAAC,EACA,QAAQA,IAAS,CAChB,WAAY,CACLA,EAAK,KAAK,CACjB,EAKA,aAAac,EAAuB,CAClC,IAAMC,EAASf,EAAK,eACpB,OAAAA,EAAK,cAAcc,CAAI,EAChBd,EAAK,eAAiBA,EAAK,iBAAmBe,EACjDf,EAAK,KAAK,EACVA,EAAK,gBAAgB,CAC3B,EAIA,aAAc,CACPA,EAAK,OACHA,EAAK,KAAK,KAEjB,eACEA,KACA,aACE,IAAMA,EAAK,UACX,IAAM,CAEFA,EAAK,eACL,CAACgB,EAAkBhB,EAAK,gBAAgB,EAAE,YAErCA,EAAK,KAAK,CAEnB,CACF,CACF,CACF,CACF,EAAE,CACN,CD5KA,IAAMiB,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,C4CxCA,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,EAKA,iBAAkB,CAChB,KAAM,UACN,aAAc,EAChB,EACA,MAAG,kCAA8B,CAC/B,cAAe,IACf,OAAQ,+CACV,CAAC,CACH,EACA,CAAE,gBAAiB,GAAM,mBAAoB,WAAY,CAC3D,CACF,CCnDA,IAAAC,GAAqB,UAIrB,IAAAC,GAAgD,SAChDC,GAA4B,UAC5BC,GAAgC,UAChCC,GAAuC,UACvCC,GAA4C,UAC5CC,GAA6B,UAC7BC,EAKO,UACPC,GAGO,UAIP,IAAAC,GAAyB,UClBlB,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,CDiBA,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,EAG/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,OAEP,eAAgB,MAClB,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,EACA,IAAI,yBAAmC,CACrC,SAAO,YAAQA,EAAM,kBAAkB,CACzC,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,GAAiB,KAAK,aAAa,GACnCC,GAAWH,EAAK,YAAY,aAAa,CAE7C,EAGA,IAAI,oBAAqB,CAGvB,IAAMI,EAFSJ,EAAK,cAAc,QAEZ,aACtB,OAAO,OAAOI,GAAU,SAAWA,EAAQ,MAC7C,CACF,EAAE,EACD,MAAMJ,IAAS,CACd,OAAOK,EAA+B,CACpC,IAAMD,EAAQJ,EAAK,mBACnB,OAAOI,IAAU,QAAaC,EAAUD,EAAQ,SAAW,MAC7D,EACA,OAAOE,EAAoB,CACzB,OAAOA,IAAS,SAAW,IAAWN,EAAK,WAC7C,EACA,IAAI,SAAwB,CAC1B,OAAOA,EAAK,WAAaA,EAAK,qBAAuB,OACjD,SACA,MACN,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,cAAe,CACjB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,EAAOP,EAAK,OAAOA,EAAK,OAAOO,EAAK,OAAO,CAAC,EAAI,GACzD,CACF,EAAE,EACD,MAAMP,IAAS,CACd,IAAI,gBAAiB,CACnB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,IAAS,QAAaA,EAAK,IAAMA,EAAK,MAAQP,EAAK,YAC5D,EACA,IAAI,sBAAuB,CACzB,IAAMO,EAAOP,EAAK,cAClB,OAAOO,EACH,qCAAqCC,GAAaD,EAAK,IAAMA,EAAK,KAAK,CAAC,SAASC,GAAaR,EAAK,YAAY,CAAC,IAChH,EACN,EACA,IAAI,oBAAqB,CACvB,MAAO,EACT,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAK,YACd,CACF,EAAE,EACD,MAAMA,IAAS,CACd,IAAI,UAAW,CACb,SAAO,oBACL,CACE,MAAOA,EAAK,MACZ,eAAgBA,EAAK,eACrB,cAAe,GACf,cAAeA,EAAK,YACtB,EACA,IAAM,CAACA,EAAK,WAAaA,EAAK,UAAY,CAAC,CAACA,EAAK,YACnD,CACF,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,mBAAmBS,EAAc,CAC/BT,EAAK,gBAAkBS,CACzB,EACA,sBAAsBC,EAAkC,CACtDV,EAAK,mBAAqBU,EAC1BV,EAAK,MAAQ,MACf,EACA,SAASW,EAAiC,CACxCX,EAAK,MAAQW,CACf,EACA,kBAAkBC,EAA6B,CAC7CZ,EAAK,eAAiBY,CACxB,EACA,eAAeC,EAAY,CACzBb,EAAK,YAAca,CACrB,EAIA,KAAM,CACJ,IAAMC,EAASd,EAAK,UACpB,GAAI,CAACc,EACH,OAEF,IAAMC,EAAUC,GACdC,GAAuBjB,EAAK,YAAY,aAAa,EACrDc,EAAO,YACT,EACA,GAAIC,EAAS,CACXf,EAAK,WAAW,EAChBA,EAAK,SAAS,IAAI,MAAMe,CAAO,CAAC,EAChC,MACF,CACA,IAAMG,EAASlB,EAAK,UAAY,SAChC,OAAOA,EAAK,YAAYA,EAAK,cAAec,EAAQ,CAClD,KAAMI,EAAS,EAAIlB,EAAK,gBACxB,WAAYA,EAAK,iBACjB,KAAMkB,EAAS,SAAW,OAC1B,GAAIC,EAAkBnB,EAAK,gBAAgB,EAAE,WACzC,CAAE,OAAQ,aAAuB,EACjC,CAAC,CACP,CAAC,CACH,CACF,EAAE,EACD,QAAQA,IAAS,CAChB,QAAQO,EAAkB,CACxB,IAAMD,EAAON,EAAK,OAAOO,EAAK,OAAO,EACrC,OAAAP,EAAK,UAAYM,IAAS,SAC1BN,EAAK,UAAYoB,GACfb,EACAP,EAAK,OAAOM,CAAI,EAChBa,EAAkBnB,EAAK,gBAAgB,EAAE,UAC3C,EACAA,EAAK,SACEA,EAAK,IAAI,CAClB,CACF,EAAE,EACD,QAAQA,IAAS,CAOhB,SAASO,EAA2B,CAClCP,EAAK,cAAgBO,EACrB,IAAMc,EAAUF,EAAkBnB,EAAK,gBAAgB,EAAE,WACzD,OACEA,EAAK,gBACLsB,GAAYtB,EAAK,MAAOO,CAAI,GAC3B,CAACP,EAAK,cACLA,EAAK,OAAOO,EAAK,OAAO,IAAMP,EAAK,SACnCuB,GAASvB,EAAK,UAAWO,EAAMc,CAAO,EAEjC,IAIJ,QAAQ,QAAQrB,EAAK,QAAQO,CAAI,CAAC,EAAE,KAAK,IAAM,IAC9C,WAAQP,CAAI,GAAKwB,GAAiBxB,EAAK,KAAK,GAC9C,KAAK,eAAeO,CAAI,CAE5B,CAAC,EACM,GACT,EAGA,eAAeA,EAAkB,CAC/BP,EAAK,SAASO,CAAI,EAClBP,EAAK,UAAY,OACjB,KAAK,SAASA,EAAK,eAAiBO,CAAI,CAC1C,EACA,aAAakB,EAAuB,CAClC,IAAMC,EAAOP,EAAkBnB,EAAK,gBAAgB,EACpDA,EAAK,cAAcyB,CAAI,EACvB,IAAME,EAAKR,EAAkBM,CAAI,EAC3BlB,EAAOP,EAAK,KAAO4B,GAAW5B,EAAK,IAAI,EAAI,OACjD,OACEO,GACA,CAACP,EAAK,iBACL2B,EAAG,aAAeD,EAAK,YACtBC,EAAG,aAAeD,EAAK,YAElB1B,EAAK,QAAQO,CAAI,EAEnBP,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,CAEhB,MAAM,oBAAoB6B,EAAwC,CAChE,GAAI,CACF,IAAMjB,EAAQ,QAAM,eAAWZ,CAAI,EAAE,WAAW,QAC9C,oBAAgBA,CAAI,EACpB,qBACA,CAAE,cAAA6B,CAAc,CAClB,KACI,WAAQ7B,CAAI,GACdA,EAAK,kBAAkBY,CAAK,CAEhC,OAASkB,EAAG,CACV,QAAQ,KAAK,0CAA2CA,CAAC,CAC3D,CACF,CACF,EAAE,EACD,QAAQ9B,IAAS,CAChB,WAAY,CACV,IAAMO,EAAOP,EAAK,cACdO,IACFP,EAAK,eAAe,KAAK,KAAKO,EAAK,IAAMA,EAAK,KAAK,CAAC,EACpDP,EAAK,SAASO,CAAI,EAEtB,EAIA,aAAc,CACRP,EAAK,WAAa,CAACA,EAAK,OACrBA,EAAK,IAAI,KAEhB,eACEA,KACA,aACE,IACE+B,GAAY/B,EAAK,aAAa,EAC1BA,EAAK,cACL,OACN6B,GAAiB,CACf7B,EAAK,kBAAkB,MAAS,EAC5B6B,GACG7B,EAAK,oBAAoB6B,CAAa,CAE/C,EACA,CAAE,gBAAiB,GAAM,KAAM,qBAAsB,CACvD,CACF,KACA,eACE7B,KACA,aACE,IAAMA,EAAK,YACXgC,GAAU,CACHA,GACHhC,EAAK,YAAY,CAErB,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACEA,KACA,aACE,IAAMA,EAAK,UACXiC,GAAS,CACHA,GACFjC,EAAK,cAAciC,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,eACEnC,KACA,aACE,IAAM,GAAGA,EAAK,MAAM,KAAK,IAAIA,EAAK,gBAAgB,KAAK,GACvD,IAAM,CACJ,IAAMoC,EAAQpC,EAAK,YAAYA,EAAK,WAAW,GAAG,OAAS,GACtDA,EAAK,WAAW,OAAS,GAAKA,EAAK,QACtCA,EAAK,UAAU,KAAK,IAAIA,EAAK,OAAQ,KAAK,KAAKoC,CAAK,CAAC,CAAC,CAE1D,EACA,CAAE,KAAM,kBAAmB,CAC7B,CACF,KACA,eACEpC,KACA,aACE,IAAMA,EAAK,MAAM,oBACjBqC,GAAU,CACR,GAAM,CAAE,KAAAC,CAAK,EAAItC,EACXO,EAAO8B,GAAUC,EAAOV,GAAWU,CAAI,EAAI,OAC7C/B,GACFP,EAAK,SAASO,CAAI,CAEtB,EACA,CAAE,gBAAiB,GAAM,KAAM,iBAAkB,CACnD,CACF,CACF,CACF,EAAE,EACD,MAAMP,IAAS,CAId,IAAI,eAAgB,CAClB,IAAMO,EAAOP,EAAK,KAAO4B,GAAW5B,EAAK,IAAI,EAAI,OAC3CuC,EAAUvC,EAAK,cACrB,GACE,CAACO,GACD,CAACgC,GACD,CAACvC,EAAK,UACNA,EAAK,WACLA,EAAK,eAEL,OAEF,IAAMwC,EAAQ,KAAK,MAAMjC,EAAK,KAAK,EAC7BkC,EAAM,KAAK,KAAKlC,EAAK,GAAG,EAC9B,MAAO,CACL,cAAegC,EACf,aAAc,CACZ,QAAShC,EAAK,QACd,aAAcA,EAAK,aACnB,MAAAiC,EACA,IAAAC,CACF,EACA,gBAAiBzC,EAAK,gBACtB,mBAAoBA,EAAK,iBACzB,YAAa,KAAK,IAAIA,EAAK,YAAayC,EAAMD,CAAK,EACnD,WAAYxC,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,IAAM0C,EAAO1C,EAAK,cACd0C,MACF,eAAW1C,CAAI,EAAE,QAAQ,kBAAmB0C,CAAI,CAEpD,CACF,EAAE,EACD,MAAM1C,IAAS,CAId,cAA2B,CACzB,GAAI,CAAC2C,GAAgB3C,EAAK,aAAa,EACrC,MAAO,CAAC,EAEV,IAAM4C,EAAW1C,GAAiBF,EAAK,aAAa,EAC9C6C,EAAQ1C,GAAWH,EAAK,YAAY,aAAa,EACjDY,EAAQZ,EAAK,eACb8C,EAAS9C,EAAK,mBACd+C,EAASrC,GAAqC,CAClDV,EAAK,sBAAsBU,CAAU,EAChCV,EAAK,IAAI,CAChB,EACA,MAAO,CACL,CAAE,KAAM,YAAa,MAAO,MAAO,EACnC,CACE,KAAM,QACN,MAAOY,EACH,iCAAiCA,EAAM,OAAO,eAAe,CAAC,IAC9D,+BACJ,QAASkC,EAASA,EAAO,SAAW,EAAI,CAACF,GAAY,CAACC,EACtD,QAAS,IAAM,CACbE,EAAM,CAAC,CAAC,CACV,CACF,EACA,GAAIH,GAAYC,EACZ,CACE,CACE,KAAM,QACN,MAAOD,EACH,iCACA,eAAeC,GAAO,MAAM,cAChC,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,EACA,cAAe,IACb,eAAW9C,CAAI,EAAE,YAAYgD,GAAW,CACtC7D,GACA,CAAE,MAAOa,EAAM,KAAM,GAAM,QAAAgD,CAAQ,CACrC,CAAC,CACH,EACA,MAAM,UAAUC,EAAoD,CAClE,GAAM,CAAE,oBAAAC,CAAoB,EAAI,KAAM,QAAO,gCAAa,EAC1D,OAAOA,EACLlD,EACAiD,CACF,CACF,EACA,gBAA6B,CAC3B,IAAME,EAAWnD,EAAK,gBAAgB,KACtC,2BAAuBmD,EAAU,CAC/B,MAAO,oBACP,KAAMC,GACN,SAAU,CAACpD,EAAK,cAChB,iBAAkB,uCAClB,QAAS,IAAM,CACbA,EAAK,cAAc,CACrB,CACF,CAAC,EACD,IAAMU,EAAa,CACjB,GAAG,KAAK,aAAa,EACrB,GAAGV,EAAK,mBAAmB,CAC7B,EACA,MAAO,CACL,GAAIU,EAAW,OAAS,EACpB,CAAC,CAAE,MAAO,aAAc,KAAM2C,GAAW,QAAS3C,CAAW,CAAC,EAC9D,CAAC,EACL,GAAGV,EAAK,eAAe,EACvB,CACE,MAAO,WACP,KAAMsD,GACN,QAAS,IAAM,CACb,KAAK,aAAa,CACpB,CACF,EACA,GAAGH,CACL,CACF,CACF,EAAE,CAER,CFzmBe,SAARI,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,UAgDtB,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,CAEA,SAASC,GAAeD,EAA+B,CACrD,GAAM,CAAE,SAAAE,EAAU,QAAAL,EAAS,IAAAC,CAAI,EAAIE,EACnC,GAAI,OAAOE,GAAa,SACtB,OAAOF,EAET,IAAMG,EAAQC,GAAiB,GAAGF,CAAQ,IAAIE,CAAI,UAClD,MAAO,CACL,GAAGJ,EACH,cAAe,CAAE,IAAKG,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAC7C,WAAYF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,EAC3C,iBAAkB,CAAE,IAAKK,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAChD,cAAeF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,EAC9C,cAAe,CAAE,IAAKK,EAAK,OAAO,EAAG,QAAAN,CAAQ,EAC7C,WAAYF,GAAIQ,EAAK,OAAO,EAAGN,EAASC,CAAG,CAC7C,CACF,CAEO,SAASO,GAAkBL,EAA+B,CAC/D,GAAM,CAAE,OAAAM,EAAQ,QAAAT,EAAS,IAAAC,CAAI,EAAIE,EACjC,OAAOC,GACLF,GACE,OAAOO,GAAW,UAAYA,IAAW,KACrC,CAAE,GAAGN,EAAM,OAAQD,GAAgB,CAAE,QAAAF,EAAS,IAAAC,EAAK,GAAGQ,CAAO,CAAC,CAAE,EAChEN,CACN,CACF,CACF,CAEA,IAAMO,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,EAOA,cAAe,CACb,KAAM,eACN,aAAc,CAAE,IAAK,GAAI,aAAc,aAAc,CACvD,EAIA,WAAYA,GAAY,iBAAkB,EAAE,EAM5C,UAAW,CACT,KAAM,UACN,aAAc,KAChB,EAOA,eAAgB,CACd,KAAM,UACN,aAAc,GAChB,EAWA,eAAgB,CACd,KAAM,UACN,aAAc,GAChB,EASA,kBAAmB,CACjB,KAAM,cACN,aAAc,CAAC,CACjB,EAcA,oBAAqB,CACnB,KAAM,SACN,aAAc,CAAC,CACjB,EAQA,OAAQG,EACV,EACA,CACE,gBAAiB,GAejB,mBAAoBL,EACtB,CACF,EAIOO,GAAQD,GDhTA,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,gBAAa,UAAMA,EAAM,QAAQ,QAAQ,KAAM,EAAG,CAAC,GAC/D,YAAa,gBAAa,UAAMA,EAAM,QAAQ,QAAQ,KAAM,EAAG,CAAC,GAChE,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,QrEyBvB,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,EACjEA,EAAc,aAAa,IAAM,IAAIe,GAAmBf,CAAa,CAAC,CACxE,CAMA,UAAUA,EAA8B,CACtC,GAAI,IACE,0BAAsBA,EAAc,SAAS,GAC/CA,EAAc,UAAU,gBAAgB,CAAC,KAAK,EAAG,CAC/C,MAAO,oBACP,KAAMgB,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_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_serializableFilterChain", "__commonJSMin", "exports", "module", "require_DisplayType", "__commonJSMin", "exports", "module", "require_trackHeightConfigSchemaFields", "__commonJSMin", "exports", "module", "require_svgReady", "__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", "readsIndexBeside", "name", "query", "splitUri", "configSchema_default", "GbzBaseSyntenyAdapterF", "pluginManager", "AdapterType", "configSchema_default", "r", "import_dataAdapterCache", "import_pluggableElementTypes", "namesHaplotypes", "adapter", "GetGraphHaplotypes", "args", "adapterConfig", "sessionId", "signal", "dataAdapter", "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", "import_pluggableElementTypes", "GraphComputeLayout", "args", "graph", "options", "statusCallback", "layoutEngine", "import_react", "import_ViewType", "import_withLaunchInput", "import_models", "import_util", "import_mobx_state_tree", "import_mobx", "import_ui", "import_util", "import_jsx_runtime", "ContentCopy_default", "_jsx", "import_jsx_runtime", "Hub_default", "_jsx", "import_jsx_runtime", "Palette_default", "_jsx", "import_jsx_runtime", "PhotoCamera_default", "_jsx", "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", "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", "b", "lo", "hi", "from", "to", "backbone", "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", "litNode", "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", "shiftIntoView", "lo", "size", "extent", "margin", "keepInView", "bounds", "view", "onScreen", "left", "top", "withSettingActions", "withFitViews", "self", "bounds", "view", "t", "keepInView", "error", "message", "ms", "strokeCount", "built", "quality", "engine", "linear", "mode", "highlight", "name", "graph", "reanchored", "anchorFromPaths", "forceLayouts", "draw", "show", "scheme", "spread", "limit", "width", "bp", "trackId", "key", "layers", "names", "had", "l", "walk", "field", "columns", "color", "px", "samples", "groupBy", "viewId", "paired", "withRows", "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", "zoomAbout", "faceted", "pad", "FACET_PAD_PX", "FIT_PADDING", "padTop", "usableHeight", "fittedTranslateY", "fit", "scale", "translateX", "engaging", "previous", "keepsAxis", "onScreen", "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", "layoutError", "laidOutGraph", "walkGeneCache", "layoutInto", "isLive", "signal", "computed", "e", "live", "previous", "loadedReference", "paths", "assemblyWalk", "chooseReferencePath", "parseAndLayout", "text", "name", "keepSelection", "readsOf", "parsed", "loadGraph", "loaded", "anchorFromPaths", "records", "total", "selected", "n", "liveLoad", "loadInFlight", "beginLoad", "load", "endLoad", "layoutSettled", "loadBubbles", "adapterConfig", "prefix", "bubblePrefix", "features", "bubbles", "f", "outermost", "popped", "trackFeatures", "trackId", "what", "session", "config", "t", "loadGenes", "loadRepeats", "repeatArraysFrom", "loadWholeGFA", "source", "abortLoad", "dropGraph", "location", "fileName", "opts", "fetchStart", "gfaText", "locLabel", "namesReads", "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", "wanted", "canonicalAssemblyName", "found", "track", "type", "assemblyNames", "trackId", "name", "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", "repeat", "TUBE_MAP_MODES", "TUBE_MAP_FOLDS", "bp", "label", "key", "name", "unit", "PhotoCamera_default", "svg", "downloadText", "ContentCopy_default", "spec", "e", "picks", "walks", "lifted", "l", "many", "WALK_MENU_ITEMS", "ChooseWalksDialog", "walk", "HighlightColorDialog", "FACET_FIELDS", "value", "COLOR_SCHEMES", "s", "options", "layoutModeByValue", "Hub_default", "LAYOUT_MODES", "mode", "Palette_default", "scheme", "Visibility_default", "items", "item", "graphLaunchMenuItems", "GraphPaneMixin", "withLaunchActions", "stateModelFactory", "GraphPaneMixin", "MAX_GRAPH_REGION_BP", "self", "setBaseWidth", "width", "track", "configHaplotypes", "trackAdapterConfig", "clearPane", "region", "fileName", "span", "problem", "offReferenceProblem", "graphReferenceAssembly", "formatSpanBp", "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_svgReady", "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", "configHaplotypes", "trackLanes", "above", "bpPerPx", "tier", "seen", "formatSpanBp", "hops", "haplotypes", "window", "names", "bp", "region", "problem", "offReferenceProblem", "graphReferenceAssembly", "coarse", "layoutModeByValue", "hostCut", "margins", "denseCovers", "cutHolds", "isNodeLimitError", "mode", "from", "to", "hostWindow", "adapterConfig", "e", "walkIndexed", "places", "frame", "a", "b", "needs", "blocks", "host", "trackId", "start", "end", "spec", "cutsByHaplotype", "defaults", "lanes", "chosen", "recut", "onClose", "opts", "renderGraphTrackSvg", "launches", "BubbleChart_default", "Route_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", "walksLocations", "walksUri", "file", "kind", "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", "GetGraphHaplotypes", "BubbleChart_default", "session", "e"]
|
|
7
7
|
}
|