Mercurial > repos > fubar > jbrowse2
diff x/static/js/3120.3940249f.chunk.js.map @ 125:49f3d3878413 draft
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse2 commit 5ea1f9c1eef1de76232e69aa6d34cda77d90d566
author | fubar |
---|---|
date | Sat, 05 Oct 2024 23:58:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x/static/js/3120.3940249f.chunk.js.map Sat Oct 05 23:58:05 2024 +0000 @@ -0,0 +1,1 @@ +{"version":3,"file":"static/js/3120.3940249f.chunk.js","mappings":"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","sources":["../../../packages/core/PluginLoader.ts","../../../packages/core/data_adapters/dataAdapterCache.ts","../../../packages/core/rpc/remoteAbortSignals.ts","../../../packages/core/ui/CascadingMenu.tsx","../../../packages/core/ui/Dialog.tsx","../../../packages/core/ui/EditableTypography.tsx","../../../packages/core/ui/ErrorMessage.tsx","../../../packages/core/ui/FactoryResetDialog.tsx","../../../packages/core/ui/Icons.tsx","../../../packages/core/ui/Logo.tsx","../../../packages/core/ui/Menu.tsx","../../../packages/core/ui/ResizeHandle.tsx","../../../packages/core/ui/ReturnToImportFormDialog.tsx","../../../packages/core/ui/SanitizedHTML.tsx","../../../packages/core/ui/theme.ts","../../../packages/core/ui/AssemblySelector.tsx","../../../packages/core/ui/FileSelector/FileSelector.tsx","../../../packages/core/ui/PrerenderedCanvas.tsx","../../../packages/core/util/QuickLRU.js","../../../packages/core/util/index.ts","../../../packages/core/util/tracks.ts","../../../packages/core/util/types/mst.ts","../../../packages/product-core/src/Session/BaseSession.ts","../../../packages/product-core/src/Session/Connections.ts","../../../plugins/data-management/src/index.ts","../../../packages/core/ui/Snackbar.tsx","../../../packages/core/ui/DropDownMenu.tsx","../../../packages/core/ui/AppLogo.tsx","../../../packages/app-core/src/ui/App/AppToolbar.tsx","../../../packages/app-core/src/ui/App/DialogQueue.tsx","../../../packages/app-core/src/ui/App/AppFab.tsx","../../../packages/app-core/src/ui/App/ViewLauncher.tsx","../../../packages/app-core/src/ui/App/ViewMenu.tsx","../../../packages/app-core/src/ui/App/ViewContainerTitle.tsx","../../../packages/app-core/src/ui/App/ViewHeader.tsx","../../../packages/app-core/src/ui/App/ViewContainer.tsx","../../../packages/app-core/src/ui/App/ViewPanel.tsx","../../../packages/app-core/src/ui/App/ViewsContainer.tsx","../../../packages/app-core/src/ui/App/App.tsx","../../../packages/core/util/TimeTraveller.ts","../../../packages/core/rpc/baseRpcConfig.ts","../../../packages/core/rpc/webWorkerRpcConfig.ts","../../../packages/core/rpc/mainThreadRpcConfig.ts","../../../packages/core/rpc/configSchema.ts","../../../packages/core/rpc/BaseRpcDriver.ts","../../../packages/core/rpc/WebWorkerRpcDriver.ts","../../../packages/core/rpc/MainThreadRpcDriver.ts","../../../packages/core/rpc/RpcManager.ts","components/ShareButton.tsx","components/JBrowse.tsx","SessionLoader.ts","components/StartScreenErrorMessage.tsx","makeWorkerInstance.ts","jbrowseModel.ts","../../../packages/core/assemblyManager/assembly.ts","rootModel/rootModel.ts","../../../packages/core/assemblyManager/assemblyConfigSchema.ts","../../../packages/app-core/src/JBrowseModel/index.ts","../../../packages/app-core/src/JBrowseConfig/index.ts","../../../packages/product-core/src/RootModel/FormatDetails.ts","../../../packages/product-core/src/RootModel/FormatAbout.ts","../../../packages/product-core/src/RootModel/HierarchicalConfig.ts","../../../packages/product-core/src/RootModel/BaseRootModel.ts","../../../packages/core/assemblyManager/assemblyManager.ts","../../../packages/product-core/src/RootModel/InternetAccounts.ts","../../../packages/app-core/src/HistoryManagement/index.ts","../../../packages/app-core/src/RootMenu/index.ts","../../../packages/product-core/src/Session/ReferenceManagement.ts","../../../packages/product-core/src/Session/DrawerWidgets.ts","../../../packages/core/ui/SnackbarModel.tsx","../../../packages/web-core/src/BaseWebSession/index.ts","../../../packages/product-core/src/Session/DialogQueue.ts","../../../packages/product-core/src/Session/Themes.ts","../../../packages/product-core/src/Session/MultipleViews.ts","../../../packages/product-core/src/Session/SessionTracks.ts","../../../packages/product-core/src/Session/Tracks.ts","../../../packages/app-core/src/Assemblies/SessionAssembliesMixin.ts","../../../packages/app-core/src/Assemblies/TemporaryAssembliesMixin.ts","../../../packages/web-core/src/SessionConnections.ts","../../../packages/app-core/src/AppFocus/index.ts","sessionModel/index.ts","createPluginManager.ts","../../../packages/core/util/analytics.ts","components/Loader.tsx","factoryReset.ts","sessionSharing.ts","util.ts"],"sourcesContent":["import domLoadScript from 'load-script'\n\n// locals\nimport Plugin, { PluginConstructor } from './Plugin'\nimport ReExports from './ReExports'\nimport { isElectron } from './util'\n\nexport interface UMDLocPluginDefinition {\n umdLoc: {\n uri: string\n baseUri?: string\n }\n name: string\n}\n\nexport interface UMDUrlPluginDefinition {\n umdUrl: string\n name: string\n}\n\nexport interface LegacyUMDPluginDefinition {\n url: string\n name: string\n}\n\ntype UMDPluginDefinition = UMDLocPluginDefinition | UMDUrlPluginDefinition\n\nexport function isUMDPluginDefinition(\n def: PluginDefinition,\n): def is UMDPluginDefinition | LegacyUMDPluginDefinition {\n return (\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ((def as UMDUrlPluginDefinition).umdUrl !== undefined ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (def as LegacyUMDPluginDefinition).url !== undefined ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (def as UMDLocPluginDefinition).umdLoc !== undefined) &&\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (def as LegacyUMDPluginDefinition | UMDPluginDefinition).name !== undefined\n )\n}\n\nexport interface ESMLocPluginDefinition {\n esmLoc: {\n uri: string\n baseUri?: string\n }\n}\nexport interface ESMUrlPluginDefinition {\n esmUrl: string\n}\n\nexport type ESMPluginDefinition =\n | ESMLocPluginDefinition\n | ESMUrlPluginDefinition\n\nexport function isESMPluginDefinition(\n def: PluginDefinition,\n): def is ESMPluginDefinition {\n return (\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (def as ESMUrlPluginDefinition).esmUrl !== undefined ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (def as ESMLocPluginDefinition).esmLoc !== undefined\n )\n}\n\nexport interface CJSPluginDefinition {\n cjsUrl: string\n}\n\nfunction promisifiedLoadScript(src: string) {\n return new Promise((resolve, reject) => {\n domLoadScript(src, (err, script) => {\n if (err) {\n reject(err)\n } else {\n resolve(script.src)\n }\n })\n })\n}\n\nasync function loadScript(scriptUrl: string) {\n if (!isInWebWorker()) {\n return promisifiedLoadScript(scriptUrl)\n }\n\n // @ts-expect-error\n if (globalThis.importScripts) {\n // @ts-expect-error\n await globalThis.importScripts(scriptUrl)\n return\n }\n throw new Error(\n 'cannot figure out how to load external JS scripts in this environment',\n )\n}\n\nexport function isCJSPluginDefinition(\n def: PluginDefinition,\n): def is CJSPluginDefinition {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (def as CJSPluginDefinition).cjsUrl !== undefined\n}\n\nexport type PluginDefinition =\n | UMDUrlPluginDefinition\n | UMDLocPluginDefinition\n | LegacyUMDPluginDefinition\n | ESMLocPluginDefinition\n | ESMUrlPluginDefinition\n | CJSPluginDefinition\n\nexport interface PluginRecord {\n plugin: PluginConstructor\n definition: PluginDefinition\n}\n\nexport interface LoadedPlugin {\n default: PluginConstructor\n}\n\nexport function pluginDescriptionString(pluginDefinition: PluginDefinition) {\n if (isUMDPluginDefinition(pluginDefinition)) {\n return `UMD plugin ${pluginDefinition.name}`\n }\n if (isESMPluginDefinition(pluginDefinition)) {\n return `ESM plugin ${\n (pluginDefinition as ESMUrlPluginDefinition).esmUrl ||\n (pluginDefinition as ESMLocPluginDefinition).esmLoc.uri\n }`\n }\n if (isCJSPluginDefinition(pluginDefinition)) {\n return `CJS plugin ${pluginDefinition.cjsUrl}`\n }\n return 'unknown plugin'\n}\n\nfunction isInWebWorker() {\n return Boolean('WorkerGlobalScope' in globalThis)\n}\n\nexport default class PluginLoader {\n definitions: PluginDefinition[] = []\n\n fetchESM?: (url: string) => Promise<LoadedPlugin>\n fetchCJS?: (url: string) => Promise<LoadedPlugin>\n\n constructor(\n defs: PluginDefinition[] = [],\n args?: {\n fetchESM?: (url: string) => Promise<LoadedPlugin>\n fetchCJS?: (url: string) => Promise<LoadedPlugin>\n },\n ) {\n this.fetchESM = args?.fetchESM\n this.fetchCJS = args?.fetchCJS\n this.definitions = JSON.parse(JSON.stringify(defs))\n }\n\n async loadCJSPlugin(def: CJSPluginDefinition, baseUri?: string) {\n const parsedUrl = new URL(def.cjsUrl, baseUri)\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error(\n `Cannot load plugins using protocol \"${parsedUrl.protocol}\"`,\n )\n }\n if (!this.fetchCJS) {\n throw new Error('No fetchCJS callback provided')\n }\n\n return this.fetchCJS(parsedUrl.href)\n }\n\n async loadESMPlugin(def: ESMPluginDefinition, baseUri?: string) {\n const parsedUrl =\n 'esmUrl' in def\n ? new URL(def.esmUrl, baseUri)\n : new URL(def.esmLoc.uri, def.esmLoc.baseUri)\n\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error(\n `cannot load plugins using protocol \"${parsedUrl.protocol}\"`,\n )\n }\n\n if (!this.fetchESM) {\n throw new Error('No ESM fetcher installed')\n }\n const plugin = await this.fetchESM(parsedUrl.href)\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!plugin) {\n throw new Error(`Could not load ESM plugin: ${parsedUrl}`)\n }\n return plugin\n }\n\n async loadUMDPlugin(\n def: UMDPluginDefinition | LegacyUMDPluginDefinition,\n baseUri?: string,\n ) {\n const parsedUrl =\n 'url' in def\n ? new URL(def.url, baseUri)\n : 'umdUrl' in def\n ? new URL(def.umdUrl, baseUri)\n : new URL(def.umdLoc.uri, def.umdLoc.baseUri)\n\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error(\n `cannot load plugins using protocol \"${parsedUrl.protocol}\"`,\n )\n }\n const moduleName = def.name\n const umdName = `JBrowsePlugin${moduleName}`\n if (typeof jest === 'undefined') {\n await loadScript(parsedUrl.href)\n } else {\n // @ts-expect-error\n globalThis[umdName] = { default: Plugin }\n }\n\n // @ts-expect-error\n const plugin = globalThis[umdName] as\n | { default: PluginConstructor }\n | undefined\n if (!plugin) {\n throw new Error(\n `Failed to load UMD bundle for ${moduleName}, ${umdName} is undefined`,\n )\n }\n return plugin\n }\n\n async loadPlugin(def: PluginDefinition, baseUri?: string) {\n let plugin: LoadedPlugin\n if (isElectron && isCJSPluginDefinition(def)) {\n plugin = await this.loadCJSPlugin(def, baseUri)\n } else if (isESMPluginDefinition(def)) {\n plugin = await this.loadESMPlugin(def, baseUri)\n } else if (isUMDPluginDefinition(def)) {\n plugin = await this.loadUMDPlugin(def, baseUri)\n } else if (!isElectron && isCJSPluginDefinition(def)) {\n throw new Error(\n `CommonJS plugin found, but not in a NodeJS environment: ${JSON.stringify(\n def,\n )}`,\n )\n } else {\n throw new Error(`Could not determine plugin type: ${JSON.stringify(def)}`)\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!plugin.default) {\n throw new Error(\n `${pluginDescriptionString(\n def,\n )} does not have a default export, cannot load`,\n )\n }\n return plugin.default\n }\n\n installGlobalReExports(target: WindowOrWorkerGlobalScope) {\n // @ts-expect-error\n target.JBrowseExports = Object.fromEntries(\n Object.entries(ReExports).map(([moduleName, module]) => {\n return [moduleName, module]\n }),\n )\n return this\n }\n\n async load(baseUri?: string) {\n return Promise.all(\n this.definitions.map(async definition => ({\n plugin: await this.loadPlugin(definition, baseUri),\n definition,\n })),\n )\n }\n}\n","import { SnapshotIn } from 'mobx-state-tree'\nimport PluginManager from '../PluginManager'\nimport { AnyConfigurationSchemaType } from '../configuration'\nimport { AnyDataAdapter } from './BaseAdapter'\nimport idMaker from '../util/idMaker'\n\ntype ConfigSnap = SnapshotIn<AnyConfigurationSchemaType>\n\nexport function adapterConfigCacheKey(conf: Record<string, unknown> = {}) {\n return `${idMaker(conf)}`\n}\n\ninterface AdapterCacheEntry {\n dataAdapter: AnyDataAdapter\n sessionIds: Set<string>\n}\n\nlet adapterCache: Record<string, AdapterCacheEntry> = {}\n\n/**\n * instantiate a data adapter, or return an already-instantiated one if we have\n * one with the same configuration\n *\n * @param pluginManager\n *\n * @param sessionId - session ID of the associated worker session. used for\n * reference counting\n *\n * @param adapterConfigSnapshot - plain-JS configuration snapshot for the\n * adapter\n */\nexport async function getAdapter(\n pluginManager: PluginManager,\n sessionId: string,\n adapterConfigSnapshot: SnapshotIn<AnyConfigurationSchemaType>,\n): Promise<AdapterCacheEntry> {\n // cache the adapter object\n const cacheKey = adapterConfigCacheKey(adapterConfigSnapshot)\n if (!adapterCache[cacheKey]) {\n const adapterType = adapterConfigSnapshot?.type\n\n if (!adapterType) {\n throw new Error(\n `could not determine adapter type from adapter config snapshot ${JSON.stringify(\n adapterConfigSnapshot,\n )}`,\n )\n }\n const dataAdapterType = pluginManager.getAdapterType(adapterType)\n if (!dataAdapterType) {\n throw new Error(`unknown data adapter type ${adapterType}`)\n }\n\n // instantiate the data adapter's config schema so it gets its defaults,\n // callbacks, etc\n const adapterConfig = dataAdapterType.configSchema.create(\n adapterConfigSnapshot,\n { pluginManager },\n )\n\n const getSubAdapter = getAdapter.bind(null, pluginManager, sessionId)\n const CLASS = await dataAdapterType.getAdapterClass()\n const dataAdapter = new CLASS(adapterConfig, getSubAdapter, pluginManager)\n\n // store it in our cache\n adapterCache[cacheKey] = {\n dataAdapter,\n sessionIds: new Set([sessionId]),\n }\n }\n\n const cacheEntry = adapterCache[cacheKey]\n cacheEntry.sessionIds.add(sessionId)\n\n return cacheEntry\n}\n\n/**\n * this is a callback that is passed to adapters that\n * allows them to get any sub-adapters that they need\n * internally, staying with the same worker session ID\n */\nexport type getSubAdapterType = (\n adapterConfigSnap: ConfigSnap,\n) => ReturnType<typeof getAdapter>\n\nexport function freeAdapterResources(specification: Record<string, any>) {\n let deleteCount = 0\n const specKeys = Object.keys(specification)\n\n // if we don't specify a range, delete any adapters that are only associated\n // with that session\n if (specKeys.length === 1 && specKeys[0] === 'sessionId') {\n const { sessionId } = specification\n Object.entries(adapterCache).forEach(([cacheKey, cacheEntry]) => {\n cacheEntry.sessionIds.delete(sessionId)\n if (cacheEntry.sessionIds.size === 0) {\n deleteCount += 1\n delete adapterCache[cacheKey]\n }\n })\n } else {\n // otherwise call freeResources on all the cached data adapters\n Object.values(adapterCache).forEach(cacheEntry => {\n const regions =\n specification.regions ||\n (specification.region ? [specification.region] : [])\n for (const region of regions) {\n if (region.refName !== undefined) {\n cacheEntry.dataAdapter.freeResources(region)\n }\n }\n })\n }\n\n return deleteCount\n}\n\nexport function clearAdapterCache() {\n adapterCache = {}\n}\n","/* ---------------- for the RPC client ----------------- */\n\nlet abortSignalCounter = 0\nexport interface RemoteAbortSignal {\n abortSignalId: number\n}\nconst abortSignalIds = new WeakMap<AbortSignal, number>() // map of abortsignal => numerical ID\n\n/**\n * assign an ID to the given abort signal and return a plain object\n * representation\n *\n * @param signal - the signal to serialize\n * @param callfunc - function used to call\n * a remote method, will be called like callfunc('signalAbort', signalId)\n */\nexport function serializeAbortSignal(\n signal: AbortSignal,\n callfunc: (name: string, abortSignalId: number) => void,\n): RemoteAbortSignal {\n let abortSignalId = abortSignalIds.get(signal)\n if (!abortSignalId) {\n abortSignalCounter += 1\n abortSignalIds.set(signal, abortSignalCounter)\n abortSignalId = abortSignalCounter\n signal.addEventListener('abort', () => {\n const signalId = abortSignalIds.get(signal)\n if (signalId !== undefined) {\n callfunc('signalAbort', signalId)\n }\n })\n }\n return { abortSignalId }\n}\n\n/* ---------------- for the RPC server ----------------- */\n\n/**\n * test whether a given object\n * @param thing - the thing to test\n * @returns true if the thing is a remote abort signal\n */\nexport function isRemoteAbortSignal(\n thing: unknown,\n): thing is RemoteAbortSignal {\n return (\n typeof thing === 'object' &&\n thing !== null &&\n 'abortSignalId' in thing &&\n typeof thing.abortSignalId === 'number'\n )\n}\n\n// the server side keeps a set of surrogate abort controllers that can be\n// aborted based on ID\nconst surrogateAbortControllers = new Map<number, AbortController>() // numerical ID => surrogate abort controller\n\n/**\n * deserialize the result of serializeAbortSignal into an AbortSignal\n *\n * @param signal -\n * @returns an abort signal that corresponds to the given ID\n */\nexport function deserializeAbortSignal({\n abortSignalId,\n}: RemoteAbortSignal): AbortSignal {\n let surrogateAbortController = surrogateAbortControllers.get(abortSignalId)\n if (!surrogateAbortController) {\n surrogateAbortController = new AbortController()\n surrogateAbortControllers.set(abortSignalId, surrogateAbortController)\n }\n return surrogateAbortController.signal\n}\n\n/**\n * fire an abort signal from a remote abort signal ID\n *\n * @param abortSignalId -\n */\nexport function remoteAbort(props: { signalId: number }) {\n const { signalId: abortSignalId } = props\n const surrogateAbortController = surrogateAbortControllers.get(abortSignalId)\n\n if (surrogateAbortController) {\n surrogateAbortController.abort()\n }\n}\n\nexport function remoteAbortRpcHandler() {\n return {\n signalAbort: remoteAbort,\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-function-type */\nimport React, { useContext, useMemo } from 'react'\nimport {\n Divider,\n ListItemIcon,\n ListItemText,\n ListSubheader,\n Menu,\n MenuItem,\n PopoverOrigin,\n SvgIconProps,\n} from '@mui/material'\nimport { MenuItem as JBMenuItem, MenuItemEndDecoration } from './Menu'\nimport {\n bindHover,\n bindFocus,\n bindMenu,\n usePopupState,\n PopupState,\n} from 'material-ui-popup-state/hooks'\nimport HoverMenu from 'material-ui-popup-state/HoverMenu'\nimport ChevronRight from '@mui/icons-material/ChevronRight'\n\nconst CascadingContext = React.createContext({\n parentPopupState: null,\n rootPopupState: null,\n} as { parentPopupState: PopupState | null; rootPopupState: PopupState | null })\n\nfunction CascadingMenuItem({\n onClick,\n closeAfterItemClick,\n ...props\n}: {\n closeAfterItemClick: boolean\n onClick?: Function\n disabled?: boolean\n children: React.ReactNode\n}) {\n const { rootPopupState } = useContext(CascadingContext)\n if (!rootPopupState) {\n throw new Error('must be used inside a CascadingMenu')\n }\n\n return (\n <MenuItem\n {...props}\n onClick={event => {\n if (closeAfterItemClick) {\n rootPopupState.close()\n }\n onClick?.(event)\n }}\n />\n )\n}\n\nfunction CascadingSubmenu({\n title,\n Icon,\n inset,\n popupId,\n ...props\n}: {\n children: React.ReactNode\n title: React.ReactNode\n onMenuItemClick: Function\n Icon: React.ComponentType<SvgIconProps> | undefined\n\n inset: boolean\n menuItems: JBMenuItem[]\n popupId: string\n}) {\n const { parentPopupState } = useContext(CascadingContext)\n const popupState = usePopupState({\n popupId,\n variant: 'popover',\n parentPopupState,\n })\n return (\n <>\n <MenuItem {...bindHover(popupState)} {...bindFocus(popupState)}>\n {Icon ? (\n <ListItemIcon>\n <Icon />\n </ListItemIcon>\n ) : null}\n <ListItemText primary={title} inset={inset} />\n <ChevronRight />\n </MenuItem>\n <CascadingSubmenuHover\n {...props}\n anchorOrigin={{ vertical: 'top', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n popupState={popupState}\n />\n </>\n )\n}\n\nfunction CascadingSubmenuHover({\n popupState,\n onMenuItemClick,\n menuItems,\n classes,\n ...props\n}: {\n classes?: Record<string, string>\n popupState: PopupState\n anchorOrigin: PopoverOrigin\n transformOrigin: PopoverOrigin\n onMenuItemClick: Function\n menuItems: JBMenuItem[]\n}) {\n const { rootPopupState } = useContext(CascadingContext)\n const context = useMemo(\n () => ({\n rootPopupState: rootPopupState || popupState,\n parentPopupState: popupState,\n }),\n [rootPopupState, popupState],\n )\n\n return (\n <CascadingContext.Provider value={context}>\n <HoverMenu {...props} {...bindMenu(popupState)} />\n </CascadingContext.Provider>\n )\n}\n\nfunction CascadingMenu({\n popupState,\n onMenuItemClick,\n menuItems,\n ...props\n}: {\n popupState: PopupState\n onMenuItemClick: Function\n menuItems: JBMenuItem[]\n}) {\n const { rootPopupState } = useContext(CascadingContext)\n const context = useMemo(\n () => ({\n rootPopupState: rootPopupState || popupState,\n parentPopupState: popupState,\n }),\n [rootPopupState, popupState],\n )\n\n return (\n <CascadingContext.Provider value={context}>\n <Menu {...props} {...bindMenu(popupState)} />\n </CascadingContext.Provider>\n )\n}\n\nfunction EndDecoration({ item }: { item: JBMenuItem }) {\n if ('subMenu' in item) {\n return <MenuItemEndDecoration type=\"subMenu\" />\n } else if (item.type === 'checkbox' || item.type === 'radio') {\n return (\n <MenuItemEndDecoration\n type={item.type}\n checked={item.checked}\n disabled={item.disabled}\n />\n )\n }\n return null\n}\n\nfunction CascadingMenuList({\n onMenuItemClick,\n closeAfterItemClick,\n menuItems,\n ...props\n}: {\n menuItems: JBMenuItem[]\n closeAfterItemClick: boolean\n onMenuItemClick: Function\n}) {\n function handleClick(callback: Function) {\n return (event: React.MouseEvent<HTMLLIElement>) => {\n onMenuItemClick(event, callback)\n }\n }\n\n const hasIcon = menuItems.some(m => 'icon' in m && m.icon)\n return (\n <>\n {menuItems\n .sort((a, b) => (b.priority || 0) - (a.priority || 0))\n .map((item, idx) => {\n return 'subMenu' in item ? (\n <CascadingSubmenu\n key={`subMenu-${item.label}-${idx}`}\n popupId={`subMenu-${item.label}`}\n title={item.label}\n Icon={item.icon}\n inset={hasIcon && !item.icon}\n onMenuItemClick={onMenuItemClick}\n menuItems={item.subMenu}\n >\n <CascadingMenuList\n {...props}\n closeAfterItemClick={closeAfterItemClick}\n onMenuItemClick={onMenuItemClick}\n menuItems={item.subMenu}\n />\n </CascadingSubmenu>\n ) : item.type === 'divider' ? (\n <Divider\n key={`divider-${JSON.stringify(item)}-${idx}`}\n component=\"li\"\n />\n ) : item.type === 'subHeader' ? (\n <ListSubheader key={`subHeader-${item.label}-${idx}`}>\n {item.label}\n </ListSubheader>\n ) : (\n <CascadingMenuItem\n key={`${item.label}-${idx}`}\n closeAfterItemClick={closeAfterItemClick}\n onClick={\n 'onClick' in item ? handleClick(item.onClick) : undefined\n }\n disabled={Boolean(item.disabled)}\n >\n {item.icon ? (\n <ListItemIcon>\n <item.icon />\n </ListItemIcon>\n ) : null}{' '}\n <ListItemText\n primary={item.label}\n secondary={item.subLabel}\n inset={hasIcon && !item.icon}\n />\n <div style={{ flexGrow: 1, minWidth: 10 }} />\n <EndDecoration item={item} />\n </CascadingMenuItem>\n )\n })}\n </>\n )\n}\n\nfunction CascadingMenuChildren(props: {\n onMenuItemClick: Function\n closeAfterItemClick?: boolean\n menuItems: JBMenuItem[]\n popupState: PopupState\n}) {\n const { closeAfterItemClick = true, ...rest } = props\n return (\n <CascadingMenu {...rest}>\n <CascadingMenuList {...rest} closeAfterItemClick={closeAfterItemClick} />\n </CascadingMenu>\n )\n}\n\nexport default CascadingMenuChildren\n","import React from 'react'\nimport {\n Dialog as MUIDialog,\n DialogTitle,\n DialogProps,\n Divider,\n IconButton,\n ScopedCssBaseline,\n ThemeProvider,\n createTheme,\n useTheme,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\nimport { ErrorBoundary } from 'react-error-boundary'\n\n// icons\nimport CloseIcon from '@mui/icons-material/Close'\n// locals\nimport ErrorMessage from './ErrorMessage'\nimport SanitizedHTML from './SanitizedHTML'\n\nconst useStyles = makeStyles()(theme => ({\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n}))\n\nfunction DialogError({ error }: { error: unknown }) {\n return (\n <div style={{ width: 800, margin: 40 }}>\n <ErrorMessage error={error} />\n </div>\n )\n}\n\ninterface Props extends DialogProps {\n header?: React.ReactNode\n}\n\nconst Dialog = observer(function (props: Props) {\n const { classes } = useStyles()\n const { title, header, children, onClose } = props\n const theme = useTheme()\n\n return (\n <MUIDialog {...props}>\n <ScopedCssBaseline>\n {React.isValidElement(header) ? (\n header\n ) : (\n <DialogTitle>\n <SanitizedHTML html={title || ''} />\n {onClose ? (\n <IconButton\n className={classes.closeButton}\n onClick={() => {\n // @ts-expect-error\n onClose()\n }}\n >\n <CloseIcon />\n </IconButton>\n ) : null}\n </DialogTitle>\n )}\n <Divider />\n\n <ErrorBoundary FallbackComponent={DialogError}>\n <ThemeProvider\n theme={createTheme(theme, {\n components: {\n MuiInputBase: {\n styleOverrides: {\n input: {\n // xref https://github.com/GMOD/jbrowse-components/pull/3666\n boxSizing: 'content-box!important' as 'content-box',\n },\n },\n },\n },\n })}\n >\n {children}\n </ThemeProvider>\n </ErrorBoundary>\n </ScopedCssBaseline>\n </MUIDialog>\n )\n})\n\nexport default Dialog\n","import React, { useEffect, useState } from 'react'\nimport { InputBase, Typography, TypographyProps, useTheme } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport useMeasure from '@jbrowse/core/util/useMeasure'\n\ntype Variant = TypographyProps['variant']\n\ntype EditableTypographyClassKey =\n | 'input'\n | 'inputBase'\n | 'inputRoot'\n | 'inputFocused'\n\nconst useStyles = makeStyles()(theme => ({\n input: {},\n inputBase: {},\n typography: {\n top: 6,\n left: 2,\n position: 'absolute',\n whiteSpace: 'nowrap',\n visibility: 'hidden',\n },\n inputRoot: {\n padding: theme.spacing(0.5),\n },\n inputFocused: {\n borderStyle: 'solid',\n borderWidth: 2,\n },\n}))\n\ninterface Props {\n value: string\n setValue: (value: string) => void\n variant: Variant\n classes?: Partial<Record<EditableTypographyClassKey, string>>\n}\n\n// using forwardRef so that MUI Tooltip can wrap this component\nconst EditableTypography = React.forwardRef<HTMLDivElement, Props>(\n function EditableTypography2(props, ref) {\n const { value, setValue, variant, ...other } = props\n const [ref2, { width }] = useMeasure()\n const [editedValue, setEditedValue] = useState<string>()\n const [inputNode, setInputNode] = useState<HTMLInputElement | null>(null)\n const [blur, setBlur] = useState(false)\n\n useEffect(() => {\n if (blur) {\n inputNode?.blur()\n setBlur(false)\n }\n }, [blur, inputNode])\n\n // possibly tss-react does not understand the passing of props to\n // useStyles, but it appears to work\n // @ts-expect-error\n const { classes } = useStyles(props, { props })\n const theme = useTheme()\n\n const val = editedValue === undefined ? value : editedValue\n\n return (\n <div {...other} ref={ref}>\n <div style={{ position: 'relative' }}>\n <Typography\n ref={ref2}\n component=\"span\"\n variant={variant}\n className={classes.typography}\n >\n {val}\n </Typography>\n </div>\n <InputBase\n inputRef={node => {\n setInputNode(node)\n }}\n className={classes.inputBase}\n inputProps={{\n style: {\n width,\n ...(variant && variant !== 'inherit'\n ? theme.typography[variant]\n : {}),\n },\n }}\n classes={{\n input: classes.input,\n root: classes.inputRoot,\n focused: classes.inputFocused,\n }}\n value={val}\n onChange={event => {\n setEditedValue(event.target.value)\n }}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n inputNode?.blur()\n } else if (event.key === 'Escape') {\n setEditedValue(undefined)\n setBlur(true)\n }\n }}\n onBlur={() => {\n setValue(editedValue || value || '')\n setEditedValue(undefined)\n }}\n />\n </div>\n )\n },\n)\n\nexport default EditableTypography\n","import React, { Suspense, lazy, useState } from 'react'\nimport { IconButton, Tooltip } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\n\n// locals\nimport RedErrorMessageBox from './RedErrorMessageBox'\n\n// icons\nimport RefreshIcon from '@mui/icons-material/Refresh'\nimport ReportIcon from '@mui/icons-material/Report'\n\n// lazies\nconst ErrorMessageStackTraceDialog = lazy(\n () => import('./ErrorMessageStackTraceDialog'),\n)\n\nconst useStyles = makeStyles()(theme => ({\n bg: {\n background: theme.palette.divider,\n border: '1px solid black',\n margin: 20,\n },\n iconFloat: {\n float: 'right',\n marginLeft: 100,\n },\n}))\n\nfunction parseError(str: string) {\n let snapshotError = ''\n const findStr = 'is not assignable'\n const idx = str.indexOf(findStr)\n if (idx !== -1) {\n const trim = str.slice(0, idx + findStr.length)\n // best effort to make a better error message than the default\n // mobx-state-tree\n\n // case 1. element has a path\n const match = /.*at path \"(.*)\" snapshot `(.*)` is not assignable/m.exec(\n trim,\n )\n if (match) {\n str = `Failed to load element at ${match[1]}...Failed element had snapshot`\n snapshotError = match[2]!\n }\n\n // case 2. element has no path\n const match2 = /.*snapshot `(.*)` is not assignable/.exec(trim)\n if (match2) {\n str = 'Failed to load element...Failed element had snapshot'\n snapshotError = match2[1]!\n }\n }\n return snapshotError\n}\n\nfunction ErrorButtons({\n error,\n onReset,\n}: {\n error: unknown\n onReset?: () => void\n}) {\n const { classes } = useStyles()\n const [showStack, setShowStack] = useState(false)\n return (\n <div className={classes.iconFloat}>\n {typeof error === 'object' && error && 'stack' in error ? (\n <Tooltip title=\"Get stack trace\">\n <IconButton\n onClick={() => {\n setShowStack(true)\n }}\n color=\"primary\"\n >\n <ReportIcon />\n </IconButton>\n </Tooltip>\n ) : null}\n {onReset ? (\n <Tooltip title=\"Retry\">\n <IconButton onClick={onReset} color=\"primary\">\n <RefreshIcon />\n </IconButton>\n </Tooltip>\n ) : null}\n {showStack ? (\n <Suspense fallback={null}>\n <ErrorMessageStackTraceDialog\n error={error}\n onClose={() => {\n setShowStack(false)\n }}\n />\n </Suspense>\n ) : null}\n </div>\n )\n}\n\nfunction ErrorMessage({\n error,\n onReset,\n}: {\n error: unknown\n onReset?: () => void\n}) {\n const { classes } = useStyles()\n const str = `${error}`\n const str2 = str.indexOf('expected an instance of')\n const str3 = str2 !== -1 ? str.slice(0, str2) : str\n const snapshotError = parseError(str)\n return (\n <RedErrorMessageBox>\n {str3.slice(0, 10000)}\n <ErrorButtons error={error} onReset={onReset} />\n {snapshotError ? (\n <pre className={classes.bg}>\n {JSON.stringify(JSON.parse(snapshotError), null, 2)}\n </pre>\n ) : null}\n </RedErrorMessageBox>\n )\n}\n\nexport default ErrorMessage\n","import React from 'react'\nimport {\n Button,\n DialogContent,\n DialogContentText,\n DialogActions,\n} from '@mui/material'\nimport Dialog from '@jbrowse/core/ui/Dialog'\n\nexport default function FactoryResetDialog({\n onClose,\n open,\n onFactoryReset,\n}: {\n onClose: () => void\n open: boolean\n onFactoryReset: () => void\n}) {\n function handleDialogClose(action?: string) {\n if (action === 'reset') {\n onFactoryReset()\n }\n onClose()\n }\n\n return (\n <Dialog\n title=\"Reset\"\n onClose={() => {\n handleDialogClose()\n }}\n open={open}\n >\n <DialogContent>\n <DialogContentText>\n Are you sure you want to reset? This will restore the default\n configuration.\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() => {\n handleDialogClose()\n }}\n color=\"primary\"\n >\n Cancel\n </Button>\n <Button\n onClick={() => {\n handleDialogClose('reset')\n }}\n color=\"primary\"\n variant=\"contained\"\n >\n OK\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n","import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon'\nimport React from 'react'\n\n// Icons below come from https://material.io/resources/icons/?icon=line_style&style=baseline\nexport function ContentCopy(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\" />\n </SvgIcon>\n )\n}\n\n// https://materialdesignicons.com/ text-search icon\nexport function Indexing(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M19.31 18.9L22.39 22L21 23.39L17.88 20.32C17.19 20.75 16.37 21 15.5 21C13 21 11 19 11 16.5C11 14 13 12 15.5 12C18 12 20 14 20 16.5C20 17.38 19.75 18.21 19.31 18.9M15.5 19C16.88 19 18 17.88 18 16.5C18 15.12 16.88 14 15.5 14C14.12 14 13 15.12 13 16.5C13 17.88 14.12 19 15.5 19M21 4V6H3V4H21M3 16V14H9V16H3M3 11V9H21V11H18.97C17.96 10.37 16.77 10 15.5 10C14.23 10 13.04 10.37 12.03 11H3Z\" />\n </SvgIcon>\n )\n}\n\nexport function ContentCut(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M19,3L13,9L15,11L22,4V3M12,12.5A0.5,0.5 0 0,1 11.5,12A0.5,0.5 0 0,1 12,11.5A0.5,0.5 0 0,1 12.5,12A0.5,0.5 0 0,1 12,12.5M6,20A2,2 0 0,1 4,18C4,16.89 4.9,16 6,16A2,2 0 0,1 8,18C8,19.11 7.1,20 6,20M6,8A2,2 0 0,1 4,6C4,4.89 4.9,4 6,4A2,2 0 0,1 8,6C8,7.11 7.1,8 6,8M9.64,7.64C9.87,7.14 10,6.59 10,6A4,4 0 0,0 6,2A4,4 0 0,0 2,6A4,4 0 0,0 6,10C6.59,10 7.14,9.87 7.64,9.64L10,12L7.64,14.36C7.14,14.13 6.59,14 6,14A4,4 0 0,0 2,18A4,4 0 0,0 6,22A4,4 0 0,0 10,18C10,17.41 9.87,16.86 9.64,16.36L12,14L19,21H22V20L9.64,7.64Z\" />\n </SvgIcon>\n )\n}\n\nexport function ContentPaste(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M19,20H5V4H7V7H17V4H19M12,2A1,1 0 0,1 13,3A1,1 0 0,1 12,4A1,1 0 0,1 11,3A1,1 0 0,1 12,2M19,2H14.82C14.4,0.84 13.3,0 12,0C10.7,0 9.6,0.84 9.18,2H5A2,2 0 0,0 3,4V20A2,2 0 0,0 5,22H19A2,2 0 0,0 21,20V4A2,2 0 0,0 19,2Z\" />\n </SvgIcon>\n )\n}\n\n// format-list-checkbox from https://materialdesignicons.com/\nexport function TrackSelector(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M21 19v-2H8v2h13m0-6v-2H8v2h13M8 7h13V5H8v2M4 5v2h2V5H4M3 5a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V5m1 6v2h2v-2H4m-1 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1v-2m1 6v2h2v-2H4m-1 0a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1v-2z\" />\n </SvgIcon>\n )\n}\n\n// content-save-edit from https://materialdesignicons.com/\nexport function SaveAs(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path\n fill=\"currentColor\"\n d=\"M10,19L10.14,18.86C8.9,18.5 8,17.36 8,16A3,3 0 0,1 11,13C12.36,13 13.5,13.9 13.86,15.14L20,9V7L16,3H4C2.89,3 2,3.9 2,5V19A2,2 0 0,0 4,21H10V19M4,5H14V9H4V5M20.04,12.13C19.9,12.13 19.76,12.19 19.65,12.3L18.65,13.3L20.7,15.35L21.7,14.35C21.92,14.14 21.92,13.79 21.7,13.58L20.42,12.3C20.31,12.19 20.18,12.13 20.04,12.13M18.07,13.88L12,19.94V22H14.06L20.12,15.93L18.07,13.88Z\"\n />\n </SvgIcon>\n )\n}\n\n// content-save from https://materialdesignicons.com/\nexport function Save(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path\n fill=\"currentColor\"\n d=\"M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z\"\n />\n </SvgIcon>\n )\n}\n\n// dna from https://materialdesignicons.com/\nexport function DNA(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path\n fill=\"currentColor\"\n d=\"M4,2H6V4C6,5.44 6.68,6.61 7.88,7.78C8.74,8.61 9.89,9.41 11.09,10.2L9.26,11.39C8.27,10.72 7.31,10 6.5,9.21C5.07,7.82 4,6.1 4,4V2M18,2H20V4C20,6.1 18.93,7.82 17.5,9.21C16.09,10.59 14.29,11.73 12.54,12.84C10.79,13.96 9.09,15.05 7.88,16.22C6.68,17.39 6,18.56 6,20V22H4V20C4,17.9 5.07,16.18 6.5,14.79C7.91,13.41 9.71,12.27 11.46,11.16C13.21,10.04 14.91,8.95 16.12,7.78C17.32,6.61 18,5.44 18,4V2M14.74,12.61C15.73,13.28 16.69,14 17.5,14.79C18.93,16.18 20,17.9 20,20V22H18V20C18,18.56 17.32,17.39 16.12,16.22C15.26,15.39 14.11,14.59 12.91,13.8L14.74,12.61M7,3H17V4L16.94,4.5H7.06L7,4V3M7.68,6H16.32C16.08,6.34 15.8,6.69 15.42,7.06L14.91,7.5H9.07L8.58,7.06C8.2,6.69 7.92,6.34 7.68,6M9.09,16.5H14.93L15.42,16.94C15.8,17.31 16.08,17.66 16.32,18H7.68C7.92,17.66 8.2,17.31 8.58,16.94L9.09,16.5M7.06,19.5H16.94L17,20V21H7V20L7.06,19.5Z\"\n />\n </SvgIcon>\n )\n}\n\nexport function Cable(props: SvgIconProps) {\n return (\n <SvgIcon {...props}>\n <path d=\"M20 5V4c0-.55-.45-1-1-1h-2c-.55 0-1 .45-1 1v1h-1v4c0 .55.45 1 1 1h1v7c0 1.1-.9 2-2 2s-2-.9-2-2V7c0-2.21-1.79-4-4-4S5 4.79 5 7v7H4c-.55 0-1 .45-1 1v4h1v1c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-1h1v-4c0-.55-.45-1-1-1H7V7c0-1.1.9-2 2-2s2 .9 2 2v10c0 2.21 1.79 4 4 4s4-1.79 4-4v-7h1c.55 0 1-.45 1-1V5h-1z\" />\n </SvgIcon>\n )\n}\n","import React from 'react'\n\ntype LogoVariant = 'color' | 'black' | 'white'\n\ninterface LogoProps {\n variant?: LogoVariant\n}\n\nfunction getColors(variant?: LogoVariant) {\n if (variant === 'black') {\n return {\n midnight: '#808080',\n forrest: '#666666',\n grape: '#4d4d4d',\n mandarin: '#333333',\n gray: '#1a1a1a',\n }\n }\n if (variant === 'white') {\n return {\n midnight: '#ffffff',\n forrest: '#e6e6e6',\n grape: '#cccccc',\n mandarin: '#b3b3b3',\n gray: '#999999',\n }\n }\n return {\n midnight: '#0d233f',\n forrest: '#135560',\n grape: '#721e63',\n mandarin: '#ffb11d',\n gray: '#dadada',\n }\n}\n\nexport function Logomark({ variant }: LogoProps) {\n return (\n <svg viewBox=\"0 0 175 175\">\n <Icon variant={variant} />\n </svg>\n )\n}\n\nexport function LogoFull({ variant }: LogoProps) {\n return (\n <svg viewBox=\"0 0 641 175\">\n <Text variant={variant} />\n <Icon variant={variant} />\n </svg>\n )\n}\n\nfunction Icon({ variant }: LogoProps) {\n const colors = getColors(variant)\n return (\n <>\n <path\n style={{ fill: colors.midnight }}\n d=\"M120.5,57.5c.168,0,.333.012.5.013V40.506c-.167,0-.333-.006-.5-.006a98.325,98.325,0,0,0-77.4,37.565q-2.664,3.378-5.023,6.994l14.206,9.327Q54.043,91.709,56,89.179A81.363,81.363,0,0,1,120.5,57.5Z\"\n />\n <path\n style={{ fill: colors.forrest }}\n d=\"M148.668,86.223c.308.133.6.283.908.42l6.746-15.618c-.153-.067-.3-.143-.454-.21a81.36,81.36,0,0,0-71.777,3.5q-2.8,1.544-5.469,3.309l9.249,14.054A63.93,63.93,0,0,1,148.668,86.223Z\"\n />\n <path\n style={{ fill: colors.grape }}\n d=\"M170.894,109.37A63.929,63.929,0,0,0,113.4,88.861l2.336,15.474a48.456,48.456,0,0,1,44.322,15.42c.111.125.214.255.324.381l11.16-10C171.323,109.879,171.118,109.62,170.894,109.37Z\"\n />\n <path\n style={{ fill: colors.mandarin }}\n d=\"M150.921,150.314c.04.163.07.326.107.489l16.509-4.058c-.039-.163-.067-.326-.107-.489A48.457,48.457,0,0,0,135.575,111.8l-5.515,15.591A32.466,32.466,0,0,1,150.921,150.314Z\"\n />\n <path\n style={{ fill: colors.gray }}\n d=\"M134.1,138.129l-9.779,13.213a32.486,32.486,0,0,1,7.823,14.463l15.147.852c.012-.166.032-.331.041-.5A32.464,32.464,0,0,0,134.1,138.129Z\"\n />\n </>\n )\n}\n\nfunction Text({ variant }: LogoProps) {\n const colors = getColors(variant)\n return (\n <g\n aria-label=\"JBrowse\"\n transform=\"translate(213.084 144.241)\"\n style={{ fill: colors.midnight }}\n >\n <path d=\"m 26.355,-71.505 v 54.075 2.835 q 0,6.825 -0.42,10.185 -0.735,5.67 -2.835,9.135 -3.255,5.355 -8.505,8.4 -4.83,2.73 -11.55,3.57 L 1.47,11.76 Q 7.35,10.185 9.24,4.2 10.605,-0.105 10.605,-9.975 v -5.565 -55.965 q 1.785,0 4.62,0.315 2.835,0.21 3.255,0.21 1.785,0 2.94,-0.105 4.515,-0.42 4.935,-0.42 z\" />\n <path d=\"m 60.68836,-65.415 v 24.78 h 3.255 q 2.94,0 4.935,-0.525 2.1,-0.525 3.885,-2.1 2.31,-1.995 3.36,-4.83 1.155,-2.835 1.155,-6.09 0,-5.565 -2.94,-8.61 -2.94,-3.045 -8.295,-3.045 -2.52,0 -5.355,0.42 z m 0,30.87 V -6.09 h 5.25 q 4.725,0 8.505,-3.675 3.885,-3.78 3.885,-10.08 0,-8.19 -4.62,-11.655 -4.095,-3.045 -13.02,-3.045 z M 44.93836,0 v -71.505 h 27.09 q 9.135,0 14.385,3.255 6.51,3.99 6.51,12.6 0,7.035 -5.25,11.655 -4.62,4.095 -11.97,5.145 v 0.945 q 7.56,0.735 12.285,3.99 6.615,4.62 6.615,13.335 0,10.185 -7.98,15.75 -6.93,4.83 -17.43,4.83 z\" />\n <path d=\"M 109.44281,0.525 V -50.4 q 1.785,0.21 3.99,0.42 2.31,0.105 3.255,0.105 2.31,0 4.2,-0.21 1.89,-0.21 3.045,-0.315 v 13.02 q 1.89,-6.51 5.46,-9.87 4.41,-4.095 11.655,-4.095 -0.315,2.73 -0.42,6.825 -0.105,3.99 -0.105,7.455 l -0.945,0.84 q -0.945,-0.735 -2.415,-1.05 -1.47,-0.315 -2.94,-0.315 -3.57,0 -6.195,1.89 -2.52,1.785 -3.465,5.04 -0.42,1.155 -0.525,3.15 -0.105,1.89 -0.105,4.515 v 4.515 19.005 q -1.785,-0.21 -2.625,-0.21 -3.675,-0.315 -4.62,-0.315 -2.31,0 -4.2,0.21 -1.89,0.21 -3.045,0.315 z\" />\n <path d=\"m 173.77337,1.47 q -11.655,0 -18.585,-6.825 -6.93,-6.825 -6.93,-18.48 0,-12.6 6.72,-20.055 6.825,-7.455 18.9,-7.455 11.97,0 18.9,6.72 6.93,6.72 6.93,18.48 0,12.285 -6.72,19.74 -7.14,7.875 -19.215,7.875 z m 0.735,-48.09 q -5.88,0 -8.505,6.51 -2.205,5.565 -2.205,15.96 0,8.19 1.47,12.915 2.415,7.98 8.505,7.98 5.565,0 8.19,-7.875 2.205,-6.51 2.205,-16.695 0,-8.505 -2.1,-13.23 -2.52,-5.565 -7.56,-5.565 z\" />\n <path d=\"m 222.03563,-50.4 10.5,36.015 q 3.675,-11.235 5.67,-17.85 2.415,-8.085 5.04,-18.165 1.05,0.105 3.045,0.315 2.1,0.21 2.835,0.21 1.995,0 3.15,-0.105 1.26,-0.21 2.73,-0.42 l 10.71,36.015 q 5.88,-17.43 10.71,-36.015 l 4.2,0.315 4.095,-0.315 q -5.145,13.125 -9.135,24.57 -5.04,14.28 -8.505,26.355 -1.89,-0.21 -3.36,-0.42 -1.365,-0.105 -2.205,-0.105 -1.89,0 -3.36,0.21 -1.365,0.21 -2.31,0.315 l -10.605,-34.755 q -4.41,13.65 -6.72,21.105 -2.31,7.35 -4.095,13.65 -1.89,-0.21 -3.36,-0.42 -1.365,-0.105 -2.31,-0.105 -1.995,0 -3.465,0.21 -1.365,0.21 -2.31,0.315 -3.78,-12.81 -5.04,-17.01 -2.205,-7.245 -5.46,-17.01 -2.835,-8.4 -5.88,-16.905 1.575,0 4.305,0.315 2.73,0.21 3.36,0.21 1.47,0 4.305,-0.21 2.835,-0.315 3.465,-0.315 z\" />\n <path d=\"m 292.84172,-12.81 h 2.625 q 1.47,4.095 4.62,6.51 3.15,2.415 7.35,2.415 2.94,0 5.46,-1.785 2.625,-1.89 2.625,-4.62 0,-3.885 -6.195,-6.615 -10.395,-4.62 -11.655,-5.46 -6.405,-4.515 -6.405,-12.285 0,-7.77 5.25,-12.18 5.25,-4.515 12.81,-4.515 3.99,0 8.085,1.365 4.095,1.26 7.14,3.57 l -2.52,9.24 h -2.94 q -0.63,-3.57 -3.57,-6.195 -2.835,-2.625 -6.405,-2.625 -3.15,0 -5.46,1.575 -2.31,1.47 -2.31,4.515 0,3.885 6.405,6.51 10.185,4.095 11.865,5.25 6.405,4.41 6.405,12.81 0,7.455 -5.46,12.18 -5.355,4.62 -14.805,4.62 -8.19,0 -14.49,-4.305 z\" />\n <path d=\"m 349.61228,-29.925 h 15.54 q 0,-6.51 -1.05,-10.395 -1.68,-6.3 -5.88,-6.3 -5.04,0 -7.14,6.195 -1.47,4.305 -1.47,10.5 z m 30.03,5.04 h -30.03 q 0,9.135 3.045,13.86 3.57,5.67 11.55,5.67 3.255,0 6.405,-1.26 3.15,-1.26 5.88,-3.465 l 1.26,0.945 -2.31,5.88 q -6.72,4.725 -15.015,4.725 -12.915,0 -19.635,-7.245 -6.72,-7.245 -6.72,-20.37 0,-11.235 6.405,-18.165 6.51,-7.035 17.64,-7.035 11.655,0 16.905,7.56 4.62,6.615 4.62,18.9 z\" />\n </g>\n )\n}\n","import React, { useEffect, useRef, useState } from 'react'\nimport {\n Divider,\n ListItemIcon,\n ListItemText,\n ListSubheader,\n MenuProps as MUIMenuProps,\n MenuItem as MUIMenuItem,\n MenuItemProps,\n MenuList,\n Paper,\n Popover,\n PopoverProps,\n SvgIconProps,\n Grow,\n} from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\n// icons\nimport ArrowRightIcon from '@mui/icons-material/ArrowRight'\nimport CheckBoxIcon from '@mui/icons-material/CheckBox'\nimport CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'\nimport RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'\nimport RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'\n\n// other\nimport { findLastIndex } from '../util'\n\nconst useStyles = makeStyles()({\n paper: {\n position: 'fixed',\n overflowY: 'auto',\n overflowX: 'hidden',\n // So we see the popover when it's empty.\n minWidth: 16,\n minHeight: 16,\n maxWidth: 'calc(100% - 32px)',\n maxHeight: 'calc(100% - 32px)',\n top: 0,\n left: 0,\n // We disable the focus ring for mouse, touch and keyboard users.\n outline: 0,\n },\n menuItemEndDecoration: {\n padding: 0,\n margin: 0,\n height: 16,\n },\n})\n\ninterface MenuItemEndDecorationSubMenuProps {\n type: 'subMenu'\n}\n\ninterface MenuItemEndDecorationSelectorProps {\n type: 'checkbox' | 'radio'\n checked: boolean\n disabled?: boolean\n}\n\ntype MenuItemEndDecorationProps =\n | MenuItemEndDecorationSubMenuProps\n | MenuItemEndDecorationSelectorProps\n\nexport function MenuItemEndDecoration(props: MenuItemEndDecorationProps) {\n const { classes } = useStyles()\n const { type } = props\n let checked: boolean | undefined\n let disabled: boolean | undefined\n if ('checked' in props) {\n ;({ checked, disabled } = props)\n }\n let icon: React.ReactElement\n switch (type) {\n case 'subMenu': {\n icon = <ArrowRightIcon color=\"action\" />\n break\n }\n case 'checkbox': {\n if (checked) {\n const color = disabled ? 'inherit' : undefined\n icon = <CheckBoxIcon color={color} />\n } else {\n icon = <CheckBoxOutlineBlankIcon color=\"action\" />\n }\n break\n }\n case 'radio': {\n if (checked) {\n const color = disabled ? 'inherit' : undefined\n icon = <RadioButtonCheckedIcon color={color} />\n } else {\n icon = <RadioButtonUncheckedIcon color=\"action\" />\n }\n break\n }\n // No default\n }\n return <div className={classes.menuItemEndDecoration}>{icon}</div>\n}\n\nexport interface MenuDivider {\n priority?: number\n type: 'divider'\n}\n\nexport interface MenuSubHeader {\n type: 'subHeader'\n priority?: number\n label: string\n}\n\nexport interface BaseMenuItem {\n id?: string // used as react key if provided\n label: React.ReactNode\n priority?: number\n subLabel?: string\n icon?: React.ComponentType<SvgIconProps>\n disabled?: boolean\n}\n\nexport interface NormalMenuItem extends BaseMenuItem {\n type?: 'normal'\n onClick: (...args: any[]) => void\n}\n\nexport interface CheckboxMenuItem extends BaseMenuItem {\n type: 'checkbox'\n checked: boolean\n onClick: (...args: any[]) => void\n}\n\nexport interface RadioMenuItem extends BaseMenuItem {\n type: 'radio'\n checked: boolean\n onClick: (...args: any[]) => void\n}\n\nexport interface SubMenuItem extends BaseMenuItem {\n type?: 'subMenu'\n subMenu: MenuItem[]\n}\n\nexport type MenuItem =\n | MenuDivider\n | MenuSubHeader\n | NormalMenuItem\n | CheckboxMenuItem\n | RadioMenuItem\n | SubMenuItem\n\ntype AnchorElProp = MUIMenuProps['anchorEl']\ntype OpenProp = MUIMenuProps['open']\ntype OnCloseProp = MUIMenuProps['onClose']\n\ninterface MenuPageProps {\n menuItems: MenuItem[]\n onMenuItemClick: (\n event: React.MouseEvent<HTMLLIElement>,\n callback: (...args: any[]) => void,\n ) => void\n anchorEl?: AnchorElProp\n open: OpenProp\n onClose: OnCloseProp\n top?: boolean\n}\n\ntype MenuItemStyleProp = MenuItemProps['style']\n\nfunction checkIfValid(m: MenuItem) {\n return m.type !== 'divider' && m.type !== 'subHeader' && !m.disabled\n}\nfunction findNextValidIdx(menuItems: MenuItem[], currentIdx: number) {\n const idx = menuItems.slice(currentIdx + 1).findIndex(checkIfValid)\n if (idx === -1) {\n return idx\n }\n return currentIdx + 1 + idx\n}\n\nfunction findPreviousValidIdx(menuItems: MenuItem[], currentIdx: number) {\n return findLastIndex(menuItems.slice(0, currentIdx), checkIfValid)\n}\n\nconst MenuPage = React.forwardRef<HTMLDivElement, MenuPageProps>(\n function MenuPage2(props, ref) {\n const [subMenuAnchorEl, setSubMenuAnchorEl] = useState<HTMLElement>()\n const [openSubMenuIdx, setOpenSubMenuIdx] = useState<number>()\n const [isSubMenuOpen, setIsSubMenuOpen] = useState(false)\n const [selectedMenuItemIdx, setSelectedMenuItemIdx] = useState<number>()\n const [position, setPosition] = useState<{\n top?: number\n left?: number\n }>()\n const paperRef = useRef<HTMLDivElement | null>(null)\n const { classes } = useStyles()\n\n const {\n menuItems,\n onMenuItemClick,\n open,\n onClose,\n anchorEl,\n top = false,\n } = props\n\n useEffect(() => {\n if (!open) {\n setSubMenuAnchorEl(undefined)\n setOpenSubMenuIdx(undefined)\n }\n }, [open])\n\n useEffect(() => {\n const shouldSubMenuBeOpen = open && Boolean(subMenuAnchorEl)\n let timer: ReturnType<typeof setTimeout>\n if (shouldSubMenuBeOpen && !isSubMenuOpen) {\n timer = setTimeout(() => {\n setIsSubMenuOpen(true)\n }, 300)\n } else if (!shouldSubMenuBeOpen && isSubMenuOpen) {\n timer = setTimeout(() => {\n setIsSubMenuOpen(false)\n }, 300)\n }\n return () => {\n clearTimeout(timer)\n }\n }, [isSubMenuOpen, open, subMenuAnchorEl])\n\n useEffect(() => {\n if (anchorEl) {\n const rect = (anchorEl as HTMLElement).getBoundingClientRect()\n if (position) {\n if (\n rect.top !== position.top ||\n rect.left + rect.width !== position.left\n ) {\n setPosition({ top: rect.top, left: rect.left + rect.width })\n }\n } else {\n setPosition({ top: rect.top, left: rect.left + rect.width })\n }\n } else if (!position) {\n setPosition({})\n }\n }, [position, anchorEl])\n\n const hasIcon = menuItems.some(\n menuItem => 'icon' in menuItem && menuItem.icon,\n )\n const menuItemStyle: MenuItemStyleProp = {}\n\n function handleClick(callback: (...args: any[]) => void) {\n return (event: React.MouseEvent<HTMLLIElement>) => {\n onMenuItemClick(event, callback)\n }\n }\n\n const ListContents = (\n <>\n <MenuList autoFocusItem={open && !isSubMenuOpen} dense>\n {menuItems\n .sort((a, b) => (b.priority || 0) - (a.priority || 0))\n .map((menuItem, idx) => {\n if (menuItem.type === 'divider') {\n return (\n <Divider\n key={`divider-${JSON.stringify(menuItem)}-${idx}`}\n component=\"li\"\n />\n )\n }\n if (menuItem.type === 'subHeader') {\n return (\n <ListSubheader key={`subHeader-${menuItem.label}-${idx}`}>\n {menuItem.label}\n </ListSubheader>\n )\n }\n let icon = null\n let endDecoration = null\n if (menuItem.icon) {\n const Icon = menuItem.icon\n icon = (\n <ListItemIcon>\n <Icon />\n </ListItemIcon>\n )\n }\n if ('subMenu' in menuItem) {\n endDecoration = <MenuItemEndDecoration type=\"subMenu\" />\n } else if (\n menuItem.type === 'checkbox' ||\n menuItem.type === 'radio'\n ) {\n endDecoration = (\n <MenuItemEndDecoration\n type={menuItem.type}\n checked={menuItem.checked}\n disabled={menuItem.disabled}\n />\n )\n }\n const onClick =\n 'onClick' in menuItem\n ? handleClick(menuItem.onClick)\n : undefined\n return (\n <MUIMenuItem\n key={menuItem.id || String(menuItem.label)}\n style={menuItemStyle}\n selected={idx === selectedMenuItemIdx}\n onClick={onClick}\n onMouseMove={e => {\n if (e.currentTarget !== document.activeElement) {\n e.currentTarget.focus()\n setSelectedMenuItemIdx(idx)\n }\n if ('subMenu' in menuItem) {\n if (openSubMenuIdx !== idx) {\n setSubMenuAnchorEl(e.currentTarget)\n setOpenSubMenuIdx(idx)\n }\n } else {\n setSubMenuAnchorEl(undefined)\n setOpenSubMenuIdx(undefined)\n }\n }}\n onKeyDown={e => {\n switch (e.key) {\n case 'ArrowLeft':\n case 'Escape': {\n onClose?.(e, 'escapeKeyDown')\n\n break\n }\n case 'ArrowUp': {\n setSelectedMenuItemIdx(\n findPreviousValidIdx(menuItems, idx),\n )\n\n break\n }\n case 'ArrowDown': {\n const a = findNextValidIdx(menuItems, idx)\n setSelectedMenuItemIdx(a)\n\n break\n }\n default: {\n if (\n 'subMenu' in menuItem &&\n (e.key === 'ArrowRight' || e.key === 'Enter')\n ) {\n setSubMenuAnchorEl(e.currentTarget)\n setOpenSubMenuIdx(idx)\n setIsSubMenuOpen(true)\n }\n }\n }\n }}\n disabled={Boolean(menuItem.disabled)}\n >\n {icon}\n <ListItemText\n primary={menuItem.label}\n secondary={menuItem.subLabel}\n inset={hasIcon && !menuItem.icon}\n />\n {endDecoration}\n </MUIMenuItem>\n )\n })}\n </MenuList>\n {menuItems.map((menuItem, idx) => {\n let subMenu = null\n if ('subMenu' in menuItem) {\n subMenu = (\n <MenuPage\n key={menuItem.id || String(menuItem.label)}\n anchorEl={subMenuAnchorEl}\n open={isSubMenuOpen && openSubMenuIdx === idx}\n onClose={() => {\n setIsSubMenuOpen(false)\n setSubMenuAnchorEl(undefined)\n }}\n onMenuItemClick={onMenuItemClick}\n menuItems={menuItem.subMenu}\n />\n )\n }\n return subMenu\n })}\n </>\n )\n\n return top ? (\n ListContents\n ) : (\n // Grow is required for cascading sub-menus\n <Grow in={open} style={{ transformOrigin: '0 0 0' }} ref={ref}>\n <Paper\n elevation={8}\n ref={paperRef}\n className={classes.paper}\n style={{ ...position }}\n >\n {ListContents}\n </Paper>\n </Grow>\n )\n },\n)\n\ninterface MenuProps extends PopoverProps {\n menuItems: MenuItem[]\n onMenuItemClick: (\n event: React.MouseEvent<HTMLLIElement>,\n callback: (...args: any[]) => void,\n ) => void\n}\n\nfunction Menu(props: MenuProps) {\n const { open, onClose, menuItems, onMenuItemClick, ...other } = props\n\n return (\n <Popover\n open={open}\n onClose={onClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'right',\n ...other.anchorOrigin,\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n ...other.transformOrigin,\n }}\n {...other}\n >\n <MenuPage\n open={open}\n onClose={onClose}\n menuItems={menuItems}\n onMenuItemClick={onMenuItemClick}\n top\n />\n </Popover>\n )\n}\n\nexport default Menu\n","import React, { useEffect, useState, useRef } from 'react'\nimport { makeStyles } from 'tss-react/mui'\n\nconst useStyles = makeStyles()({\n horizontalHandle: {\n cursor: 'row-resize',\n width: '100%',\n },\n verticalHandle: {\n cursor: 'col-resize',\n height: '100%',\n },\n flexbox_verticalHandle: {\n cursor: 'col-resize',\n alignSelf: 'stretch', // the height: 100% is actually unable to function inside flexbox\n },\n flexbox_horizontalHandle: {\n cursor: 'row-resize',\n alignSelf: 'stretch', // similar to above\n },\n})\n\nfunction ResizeHandle({\n onDrag,\n vertical = false,\n flexbox = false,\n className: originalClassName,\n onMouseDown,\n ...props\n}: {\n onDrag: (\n lastFrameDistance: number,\n totalDistance: number,\n ) => number | undefined\n onMouseDown?: (event: React.MouseEvent) => void\n vertical?: boolean\n flexbox?: boolean\n className?: string\n [props: string]: unknown\n}) {\n const [mouseDragging, setMouseDragging] = useState(false)\n const initialPosition = useRef(0)\n const prevPos = useRef(0)\n const { classes, cx } = useStyles()\n\n useEffect(() => {\n function mouseMove(event: MouseEvent) {\n event.preventDefault()\n const pos = vertical ? event.clientX : event.clientY\n const totalDistance = initialPosition.current - pos\n const lastFrameDistance = pos - prevPos.current\n prevPos.current = pos\n onDrag(lastFrameDistance, totalDistance)\n }\n\n function mouseUp() {\n setMouseDragging(false)\n }\n if (mouseDragging) {\n window.addEventListener('mousemove', mouseMove, true)\n window.addEventListener('mouseup', mouseUp, true)\n return () => {\n window.removeEventListener('mousemove', mouseMove, true)\n window.removeEventListener('mouseup', mouseUp, true)\n }\n }\n return () => {}\n }, [mouseDragging, onDrag, vertical])\n\n let className: string\n if (flexbox) {\n className = vertical\n ? classes.flexbox_verticalHandle\n : classes.flexbox_horizontalHandle\n } else if (vertical) {\n className = classes.verticalHandle\n } else {\n className = classes.horizontalHandle\n }\n\n return (\n <div\n data-resizer=\"true\"\n onMouseDown={event => {\n event.preventDefault()\n const pos = vertical ? event.clientX : event.clientY\n initialPosition.current = pos\n prevPos.current = pos\n setMouseDragging(true)\n onMouseDown?.(event)\n }}\n className={cx(className, originalClassName)}\n {...props}\n />\n )\n}\n\nexport default ResizeHandle\n","import React from 'react'\nimport { observer } from 'mobx-react'\nimport { Button, DialogActions, DialogContent, Typography } from '@mui/material'\nimport Dialog from './Dialog'\n\nconst ReturnToImportFormDialog = observer(function ({\n model,\n handleClose,\n}: {\n model: { clearView: () => void }\n handleClose: () => void\n}) {\n return (\n <Dialog maxWidth=\"xl\" open onClose={handleClose} title=\"Reference sequence\">\n <DialogContent>\n <Typography>\n Are you sure you want to return to the import form? This will lose\n your current view\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() => {\n model.clearView()\n handleClose()\n }}\n variant=\"contained\"\n color=\"primary\"\n autoFocus\n >\n OK\n </Button>\n <Button\n onClick={() => {\n handleClose()\n }}\n color=\"secondary\"\n variant=\"contained\"\n >\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n )\n})\n\nexport default ReturnToImportFormDialog\n","import React from 'react'\nimport escapeHTML from 'escape-html'\nimport dompurify from 'dompurify'\nimport { linkify } from '../util'\n\n// source https://github.com/sindresorhus/html-tags/blob/master/html-tags.json\n// with some random uncommon ones removed. note: we just use this to run the content\n// through dompurify without escaping if we see an htmlTag from this list\n// otherwise we escape angle brackets and things prematurely because it might be\n// something like <TRA> in VCF. Ref #657\nconst htmlTags = [\n 'a',\n 'b',\n 'br',\n 'code',\n 'div',\n 'em',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'i',\n 'img',\n 'li',\n 'p',\n 'pre',\n 'span',\n 'small',\n 'strong',\n 'table',\n 'tbody',\n 'sup',\n 'sub',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n]\n\nlet added = false\n\n// adapted from is-html\n// https://github.com/sindresorhus/is-html/blob/master/index.js\nconst full = new RegExp(htmlTags.map(tag => `<${tag}\\\\b[^>]*>`).join('|'), 'i')\nfunction isHTML(str: string) {\n return full.test(str)\n}\n\n// note this is mocked during testing, see\n// packages/__mocks__/@jbrowse/core/ui/SanitizedHTML something about dompurify\n// behavior causes errors during tests, was seen in\n// products/jbrowse-web/src/tests/Connection.test.tsx test (can delete mock to\n// see)\n//\nexport default function SanitizedHTML({\n html: pre,\n className,\n}: {\n className?: string\n html: string\n}) {\n // try to add links to the text first\n const html = linkify(pre)\n const value = isHTML(html) ? html : escapeHTML(html)\n if (!added) {\n added = true\n // see https://github.com/cure53/DOMPurify/issues/317\n // only have to add this once, and can't do it globally because dompurify\n // not yet initialized at global scope\n dompurify.addHook(\n 'afterSanitizeAttributes',\n (node: {\n tagName: string\n setAttribute: (arg0: string, arg1: string) => void\n }) => {\n if (node.tagName === 'A') {\n node.setAttribute('rel', 'noopener noreferrer')\n node.setAttribute('target', '_blank')\n }\n },\n )\n }\n\n return (\n <span\n className={className}\n dangerouslySetInnerHTML={{\n __html: dompurify.sanitize(value),\n }}\n />\n )\n}\n","import { blue, green, red, grey, orange } from '@mui/material/colors'\nimport { createTheme, ThemeOptions } from '@mui/material/styles'\nimport type {\n PaletteAugmentColorOptions,\n PaletteColor,\n} from '@mui/material/styles/createPalette'\nimport deepmerge from 'deepmerge'\n\ndeclare module '@mui/material/styles/createPalette' {\n interface Palette {\n tertiary: Palette['primary']\n quaternary: Palette['primary']\n highlight: Palette['primary']\n stopCodon?: string\n startCodon?: string\n bases: {\n A: Palette['primary']\n C: Palette['primary']\n G: Palette['primary']\n T: Palette['primary']\n }\n frames: [\n null,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n ]\n framesCDS: [\n null,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n ]\n }\n interface PaletteOptions {\n tertiary?: PaletteOptions['primary']\n quaternary?: PaletteOptions['primary']\n highlight?: PaletteOptions['primary']\n stopCodon?: string\n startCodon?: string\n bases?: {\n A?: PaletteOptions['primary']\n C?: PaletteOptions['primary']\n G?: PaletteOptions['primary']\n T?: PaletteOptions['primary']\n }\n framesCDS?: [\n null,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n ]\n frames?: [\n null,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n Palette['primary'] | undefined,\n ]\n }\n}\n\ntype Frames = [\n null,\n PaletteColor,\n PaletteColor,\n PaletteColor,\n PaletteColor,\n PaletteColor,\n PaletteColor,\n]\n\nconst refTheme = createTheme()\nconst midnight = '#0D233F'\nconst grape = '#721E63'\nconst forest = refTheme.palette.augmentColor({ color: { main: '#135560' } })\nconst mandarin = refTheme.palette.augmentColor({ color: { main: '#FFB11D' } })\nconst bases = {\n A: refTheme.palette.augmentColor({ color: green }),\n C: refTheme.palette.augmentColor({ color: blue }),\n G: refTheme.palette.augmentColor({ color: orange }),\n T: refTheme.palette.augmentColor({ color: red }),\n}\nconst framesCDS = [\n null,\n refTheme.palette.augmentColor({ color: { main: '#FF8080' } }),\n refTheme.palette.augmentColor({ color: { main: '#80FF80' } }),\n refTheme.palette.augmentColor({ color: { main: '#8080FF' } }),\n refTheme.palette.augmentColor({ color: { main: '#8080FF' } }),\n refTheme.palette.augmentColor({ color: { main: '#80FF80' } }),\n refTheme.palette.augmentColor({ color: { main: '#FF8080' } }),\n] as Frames\nconst frames = [\n null,\n refTheme.palette.augmentColor({ color: { main: '#8f8f8f' } }),\n refTheme.palette.augmentColor({ color: { main: '#adadad' } }),\n refTheme.palette.augmentColor({ color: { main: '#d8d8d8' } }),\n refTheme.palette.augmentColor({ color: { main: '#d8d8d8' } }),\n refTheme.palette.augmentColor({ color: { main: '#adadad' } }),\n refTheme.palette.augmentColor({ color: { main: '#8f8f8f' } }),\n] as Frames\nconst stopCodon = '#e22'\nconst startCodon = '#3e3'\n\nfunction stockTheme() {\n return {\n palette: {\n mode: undefined,\n primary: { main: midnight },\n secondary: { main: grape },\n tertiary: forest,\n quaternary: mandarin,\n highlight: mandarin,\n stopCodon,\n startCodon,\n bases,\n frames,\n framesCDS,\n },\n components: {\n MuiLink: {\n styleOverrides: {\n // the default link color uses theme.palette.primary.main which is\n // very bad with dark mode+midnight primary\n root: ({ theme }) => ({\n color: theme.palette.tertiary.main,\n }),\n },\n },\n },\n } satisfies ThemeOptions\n}\n\nfunction getDefaultTheme() {\n return {\n ...stockTheme(),\n name: 'Default (from config)',\n }\n}\n\nfunction getLightStockTheme() {\n return {\n ...stockTheme(),\n name: 'Light (stock)',\n }\n}\n\nfunction getDarkStockTheme() {\n return {\n name: 'Dark (stock)',\n palette: {\n mode: 'dark',\n primary: { main: midnight },\n secondary: { main: grape },\n tertiary: forest,\n quaternary: mandarin,\n highlight: mandarin,\n stopCodon,\n startCodon,\n bases,\n frames,\n framesCDS,\n },\n components: {\n MuiAppBar: {\n defaultProps: {\n enableColorOnDark: true,\n },\n styleOverrides: {\n root: ({ theme }) => {\n return theme.palette.primary.main\n },\n },\n },\n },\n } satisfies ThemeOptions & { name: string }\n}\n\nfunction getDarkMinimalTheme() {\n return {\n name: 'Dark (minimal)',\n palette: {\n mode: 'dark' as const,\n primary: { main: grey[700] },\n secondary: { main: grey[800] },\n tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }),\n quaternary: mandarin,\n highlight: mandarin,\n stopCodon,\n startCodon,\n bases,\n frames,\n framesCDS,\n },\n } satisfies ThemeOptions & { name: string }\n}\n\nfunction getMinimalTheme() {\n return {\n name: 'Light (minimal)',\n palette: {\n primary: { main: grey[900] },\n secondary: { main: grey[800] },\n tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }),\n quaternary: mandarin,\n highlight: mandarin,\n stopCodon,\n startCodon,\n bases,\n frames,\n framesCDS,\n },\n } satisfies ThemeOptions & { name: string }\n}\n\nexport const defaultThemes = {\n default: getDefaultTheme(),\n lightStock: getLightStockTheme(),\n lightMinimal: getMinimalTheme(),\n darkMinimal: getDarkMinimalTheme(),\n darkStock: getDarkStockTheme(),\n} as ThemeMap\n\nfunction overwriteArrayMerge(_: unknown, sourceArray: unknown[]) {\n return sourceArray\n}\n\nexport function createJBrowseBaseTheme(theme?: ThemeOptions): ThemeOptions {\n const themeP: ThemeOptions = {\n palette: theme?.palette,\n typography: {\n fontSize: 12,\n },\n spacing: 4,\n components: {\n MuiButton: {\n defaultProps: {\n size: 'small' as const,\n },\n styleOverrides: {\n // the default button, especially when not using variant=contained,\n // uses theme.palette.primary.main for text which is very bad with\n // dark mode+midnight primary\n //\n // keeps text secondary for darkmode, uses\n // a text-like coloring to ensure contrast\n // xref https://stackoverflow.com/a/72546130/2129219\n root: ({ theme }) =>\n theme.palette.mode === 'dark'\n ? {\n color: theme.palette.text.primary,\n }\n : undefined,\n },\n },\n MuiAccordion: {\n defaultProps: {\n disableGutters: true,\n slotProps: {\n transition: {\n timeout: 150,\n unmountOnExit: true,\n },\n },\n },\n },\n MuiFilledInput: {\n defaultProps: {\n margin: 'dense' as const,\n },\n },\n MuiFormControl: {\n defaultProps: {\n margin: 'dense' as const,\n size: 'small' as const,\n },\n },\n MuiFormHelperText: {\n defaultProps: {\n margin: 'dense' as const,\n },\n },\n\n MuiIconButton: {\n defaultProps: {\n size: 'small' as const,\n },\n },\n MuiInputBase: {\n defaultProps: {\n margin: 'dense' as const,\n },\n },\n MuiAutocomplete: {\n defaultProps: {\n size: 'small' as const,\n },\n },\n MuiInputLabel: {\n defaultProps: {\n margin: 'dense' as const,\n },\n },\n MuiToolbar: {\n defaultProps: {\n variant: 'dense' as const,\n },\n },\n MuiListItem: {\n defaultProps: {\n dense: true,\n },\n },\n MuiOutlinedInput: {\n defaultProps: {\n margin: 'dense' as const,\n },\n },\n MuiFab: {\n defaultProps: {\n size: 'small' as const,\n },\n styleOverrides: {\n secondary: {\n // @ts-expect-error\n backgroundColor: theme?.palette?.quaternary?.main,\n },\n },\n },\n MuiTable: {\n defaultProps: {\n size: 'small' as const,\n },\n },\n MuiPopover: {\n defaultProps: {\n transitionDuration: 0,\n },\n },\n MuiMenu: {\n defaultProps: {\n transitionDuration: 0,\n },\n },\n MuiMenuItem: {\n defaultProps: {\n dense: true,\n },\n },\n\n MuiTextField: {\n defaultProps: {\n margin: 'dense' as const,\n variant: 'standard' as const,\n },\n },\n MuiLink: {\n styleOverrides: {\n // the default link color uses theme.palette.primary.main which is\n // very bad with dark mode+midnight primary\n root: ({ theme }) => ({\n color: theme.palette.text.secondary,\n }),\n },\n },\n MuiCheckbox: {\n styleOverrides: {\n // the default checkbox-when-checked color uses\n // theme.palette.primary.main which is very bad with dark\n // mode+midnight primary\n //\n // keeps the forest-green checkbox by default but for darkmode, uses\n // a text-like coloring to ensure contrast xref\n // https://stackoverflow.com/a/72546130/2129219\n root: ({ theme }) =>\n theme.palette.mode === 'dark'\n ? {\n color: theme.palette.text.secondary,\n '&.Mui-checked': {\n color: theme.palette.text.secondary,\n },\n }\n : undefined,\n },\n },\n MuiRadio: {\n styleOverrides: {\n // the default checkbox-when-checked color uses\n // theme.palette.primary.main which is very bad with dark\n // mode+midnight primary\n //\n // keeps the forest-green checkbox by default but for darkmode, uses\n // a text-like coloring to ensure contrast\n // xref https://stackoverflow.com/a/72546130/2129219\n root: ({ theme }) =>\n theme.palette.mode === 'dark'\n ? {\n color: theme.palette.text.secondary,\n '&.Mui-checked': {\n color: theme.palette.text.secondary,\n },\n }\n : undefined,\n },\n },\n MuiFormLabel: {\n styleOverrides: {\n // the default checkbox-when-checked color uses\n // theme.palette.primary.main which is very bad with dark\n // mode+midnight primary\n //\n // keeps the forest-green checkbox by default but for darkmode, uses\n // a text-like coloring to ensure contrast\n // xref https://stackoverflow.com/a/72546130/2129219\n //\n\n root: ({ theme }) =>\n theme.palette.mode === 'dark'\n ? {\n color: theme.palette.text.secondary,\n '&.Mui-focused': {\n color: theme.palette.text.secondary,\n },\n }\n : undefined,\n },\n },\n MuiAccordionSummary: {\n styleOverrides: {\n root: {\n // @ts-expect-error\n backgroundColor: theme?.palette?.tertiary?.main,\n },\n content: {\n // @ts-expect-error\n color: theme?.palette?.tertiary?.contrastText,\n },\n },\n },\n MuiToggleButtonGroup: {\n defaultProps: {\n size: 'small' as const,\n },\n },\n },\n }\n return deepmerge(themeP, theme || {}, { arrayMerge: overwriteArrayMerge })\n}\n\ntype ThemeMap = Record<string, ThemeOptions>\n\nexport function createJBrowseTheme(\n configTheme: ThemeOptions = {},\n themes = defaultThemes,\n themeName = 'default',\n) {\n return createTheme(\n createJBrowseBaseTheme(\n themeName === 'default'\n ? deepmerge(themes.default!, augmentTheme(configTheme), {\n arrayMerge: overwriteArrayMerge,\n })\n : augmentThemePlus(themes[themeName]),\n ),\n )\n}\n\nfunction augmentTheme(theme: ThemeOptions = {}) {\n if (theme.palette?.tertiary) {\n theme = deepmerge(theme, {\n palette: {\n tertiary: refTheme.palette.augmentColor(\n 'color' in theme.palette.tertiary\n ? (theme.palette.tertiary as PaletteAugmentColorOptions)\n : { color: theme.palette.tertiary },\n ),\n },\n })\n }\n\n if (theme.palette?.quaternary) {\n theme = deepmerge(theme, {\n palette: {\n quaternary: refTheme.palette.augmentColor(\n 'color' in theme.palette.quaternary\n ? (theme.palette.quaternary as PaletteAugmentColorOptions)\n : { color: theme.palette.quaternary },\n ),\n },\n })\n }\n\n return theme\n}\n\n// creates some blank quaternary/tertiary colors if unsupplied by a user theme\nfunction augmentThemePlus(theme: ThemeOptions = {}) {\n theme = augmentTheme(theme)\n if (!theme.palette?.quaternary) {\n theme = deepmerge(theme, {\n palette: {\n quaternary: refTheme.palette.augmentColor({\n color: {\n main: '#aaa',\n },\n }),\n },\n })\n }\n if (!theme.palette?.tertiary) {\n theme = deepmerge(theme, {\n palette: {\n tertiary: refTheme.palette.augmentColor({\n color: {\n main: '#aaa',\n },\n }),\n },\n })\n }\n return theme\n}\n","import React, { useState, useEffect } from 'react'\nimport {\n TextField,\n MenuItem,\n InputProps as IIP,\n TextFieldProps as TFP,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\n// locals\nimport { getConf } from '../configuration'\nimport { useLocalStorage, AbstractSessionModel } from '../util'\n\nconst useStyles = makeStyles()({\n importFormEntry: {\n minWidth: 180,\n },\n})\n\nconst AssemblySelector = observer(function ({\n session,\n onChange,\n selected,\n InputProps,\n TextFieldProps,\n localStorageKey,\n helperText = 'Select assembly to view',\n}: {\n session: AbstractSessionModel\n helperText?: string\n onChange: (arg: string) => void\n selected?: string\n localStorageKey?: string\n InputProps?: IIP\n TextFieldProps?: TFP\n}) {\n const { classes } = useStyles()\n const { assemblyNames, assemblyManager } = session\n\n // constructs a localstorage key based on host/path/config to help\n // remember. non-config assists usage with e.g. embedded apps\n const config = new URLSearchParams(window.location.search).get('config')\n const [lastSelected, setLastSelected] =\n typeof jest === 'undefined' && localStorageKey\n ? useLocalStorage(\n `lastAssembly-${[\n window.location.host + window.location.pathname,\n config,\n localStorageKey,\n ].join('-')}`,\n selected,\n )\n : useState(selected)\n\n const selection = assemblyNames.includes(lastSelected || '')\n ? lastSelected\n : selected\n\n useEffect(() => {\n if (selection && selection !== selected) {\n onChange(selection)\n }\n }, [selection, onChange, selected])\n\n const error = assemblyNames.length ? '' : 'No configured assemblies'\n return (\n <TextField\n select\n label=\"Assembly\"\n variant=\"outlined\"\n helperText={error || helperText}\n value={selection || ''}\n inputProps={{ 'data-testid': 'assembly-selector' }}\n onChange={event => {\n setLastSelected(event.target.value)\n }}\n error={!!error}\n InputProps={InputProps}\n disabled={!!error}\n className={classes.importFormEntry}\n {...TextFieldProps}\n >\n {assemblyNames.map(name => {\n const assembly = assemblyManager.get(name)\n const displayName = assembly ? getConf(assembly, 'displayName') : ''\n return (\n <MenuItem key={name} value={name}>\n {displayName || name}\n </MenuItem>\n )\n })}\n </TextField>\n )\n})\n\nexport default AssemblySelector\n","import React, { useCallback, useEffect, useState } from 'react'\nimport { observer } from 'mobx-react'\nimport {\n Box,\n FormHelperText,\n InputLabel,\n Menu,\n MenuItem,\n Tooltip,\n ToggleButtonGroup,\n ToggleButton,\n ToggleButtonProps,\n} from '@mui/material'\n\n// locals\nimport {\n FileLocation,\n AbstractRootModel,\n isUriLocation,\n isAppRootModel,\n} from '../../util/types'\nimport LocalFileChooser from './LocalFileChooser'\nimport UrlChooser from './UrlChooser'\nimport { notEmpty, useLocalStorage } from '../../util'\n\n// icons\nimport ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'\n\nconst NUM_SHOWN = 2\n\nfunction ToggleButtonWithTooltip(props: ToggleButtonProps) {\n const { title, children, ...other } = props\n return (\n <Tooltip title={title || ''}>\n <ToggleButton {...other}>{children}</ToggleButton>\n </Tooltip>\n )\n}\n\nfunction shorten(str: string, len: number) {\n if (typeof str === 'string' && str.length > len) {\n return `${str.slice(0, Math.max(0, len))}…`\n }\n return str\n}\n\nconst FileSelector = observer(function (props: {\n location?: FileLocation\n setLocation: (param: FileLocation) => void\n setName?: (str: string) => void\n name?: string\n description?: string\n rootModel?: AbstractRootModel\n}) {\n const { location, name, description, rootModel, setLocation } = props\n const fileOrUrl = !location || isUriLocation(location) ? 'url' : 'file'\n const [toggleButtonValue, setToggleButtonValue] = useState(\n location && 'internetAccountId' in location && location.internetAccountId\n ? location.internetAccountId\n : fileOrUrl,\n )\n const accounts = isAppRootModel(rootModel)\n ? rootModel.internetAccounts.filter(\n f => f.type !== 'HTTPBasicInternetAccount',\n )\n : []\n\n const [recentlyUsedInternetAccounts, setRecentlyUsedInternetAccounts] =\n useLocalStorage('fileSelector-recentlyUsedInternetAccounts', [] as string[])\n\n const map = Object.fromEntries(accounts.map(a => [a.internetAccountId, a]))\n const arr = [...new Set(accounts.map(s => s.internetAccountId))].sort(\n (a, b) =>\n recentlyUsedInternetAccounts.indexOf(a) -\n recentlyUsedInternetAccounts.indexOf(b),\n )\n const shownAccounts = arr.slice(0, NUM_SHOWN)\n const hiddenAccounts = arr.slice(NUM_SHOWN)\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)\n const selectedAccount = map[toggleButtonValue]\n\n const setLocationWithAccount = useCallback(\n (location: FileLocation) => {\n setLocation({\n ...location,\n ...(selectedAccount && isUriLocation(location)\n ? { internetAccountId: selectedAccount.internetAccountId }\n : {}),\n })\n },\n [setLocation, selectedAccount],\n )\n\n useEffect(() => {\n // if you swap account selection after inputting url\n if (\n selectedAccount &&\n isUriLocation(location) &&\n location.internetAccountId !== selectedAccount.internetAccountId\n ) {\n setLocationWithAccount(location)\n }\n }, [location, selectedAccount, setLocationWithAccount])\n\n let locationInput = (\n <UrlChooser\n {...props}\n setLocation={setLocationWithAccount}\n label={selectedAccount?.selectorLabel}\n />\n )\n if (toggleButtonValue === 'file') {\n locationInput = <LocalFileChooser {...props} />\n }\n if (selectedAccount?.SelectorComponent) {\n const { SelectorComponent } = selectedAccount\n locationInput = (\n <SelectorComponent {...props} setLocation={setLocationWithAccount} />\n )\n }\n\n return (\n <>\n <Box display=\"flex\">\n <InputLabel shrink>{name}</InputLabel>\n </Box>\n <Box display=\"flex\" flexDirection=\"row\">\n <Box>\n <ToggleButtonGroup\n value={toggleButtonValue}\n exclusive\n onChange={(_event, newState) => {\n setRecentlyUsedInternetAccounts([\n ...new Set(\n [newState, ...recentlyUsedInternetAccounts].filter(notEmpty),\n ),\n ])\n if (newState) {\n setToggleButtonValue(newState)\n }\n if (isUriLocation(location)) {\n setLocationWithAccount(location)\n }\n }}\n aria-label=\"file, url, or account picker\"\n >\n {new URLSearchParams(window.location.search).get(\n 'adminKey',\n ) ? null : (\n <ToggleButton value=\"file\" aria-label=\"local file\">\n File\n </ToggleButton>\n )}\n <ToggleButton value=\"url\" aria-label=\"url\">\n URL\n </ToggleButton>\n {shownAccounts.map(id => {\n const { internetAccountId, name, toggleContents } = map[id]!\n return (\n <ToggleButtonWithTooltip\n key={id}\n value={internetAccountId}\n title={name}\n >\n {typeof toggleContents === 'string'\n ? shorten(toggleContents, 5)\n : toggleContents || shorten(name, 5)}\n </ToggleButtonWithTooltip>\n )\n })}\n {hiddenAccounts.length > 0 ? (\n // @ts-expect-error\n <ToggleButton\n onClick={event => {\n setAnchorEl(event.target as HTMLElement)\n }}\n selected={false}\n >\n More\n <ArrowDropDownIcon />\n </ToggleButton>\n ) : null}\n </ToggleButtonGroup>\n\n <Menu\n open={Boolean(anchorEl)}\n anchorEl={anchorEl}\n onClose={() => {\n setAnchorEl(null)\n }}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n transformOrigin={{ vertical: 'top', horizontal: 'center' }}\n >\n {hiddenAccounts.map(id => {\n const { internetAccountId, name } = map[id]!\n return (\n <MenuItem\n key={id}\n value={internetAccountId}\n onClick={() => {\n setRecentlyUsedInternetAccounts([\n ...new Set(\n [\n internetAccountId,\n ...recentlyUsedInternetAccounts,\n ].filter(notEmpty),\n ),\n ])\n\n setToggleButtonValue(internetAccountId)\n setAnchorEl(null)\n }}\n >\n {name}\n </MenuItem>\n )\n })}\n </Menu>\n </Box>\n </Box>\n {locationInput}\n <FormHelperText>{description}</FormHelperText>\n </>\n )\n})\n\nexport default FileSelector\n","import React, { useState, useRef, useEffect } from 'react'\nimport { drawImageOntoCanvasContext } from '../util/offscreenCanvasPonyfill'\n\nfunction PrerenderedCanvas(props: {\n width: number\n height: number\n highResolutionScaling?: number\n style?: any\n imageData?: any\n showSoftClip?: boolean\n blockKey?: string\n}) {\n const {\n width,\n height,\n highResolutionScaling = 1,\n style = {},\n imageData,\n blockKey,\n showSoftClip,\n } = props\n const [done, setDone] = useState(false)\n\n const featureCanvas = useRef<HTMLCanvasElement>(null)\n\n useEffect(() => {\n if (!imageData) {\n return\n }\n const canvas = featureCanvas.current\n if (!canvas) {\n return\n }\n const context = canvas.getContext('2d')\n if (!context) {\n return\n }\n drawImageOntoCanvasContext(imageData, context)\n setDone(true)\n }, [imageData])\n\n return (\n <canvas\n data-testid={[\n 'prerendered_canvas',\n showSoftClip ? 'softclipped' : '',\n blockKey,\n done ? 'done' : '',\n ]\n .filter(f => !!f)\n .join('_')}\n ref={featureCanvas}\n width={width * highResolutionScaling}\n height={height * highResolutionScaling}\n style={{ width, height, ...style }}\n />\n )\n}\n\nexport default PrerenderedCanvas\n","// vendored from quick-lru@6.1.1, didn't like being compiled as a 'pure-esm' nodejs dependency\n// the license is reproduced below https://github.com/sindresorhus/quick-lru/blob/main/license\n// MIT License\n\n// Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\nexport default class QuickLRU extends Map {\n constructor(options = {}) {\n super()\n\n if (!(options.maxSize && options.maxSize > 0)) {\n throw new TypeError('`maxSize` must be a number greater than 0')\n }\n\n if (typeof options.maxAge === 'number' && options.maxAge === 0) {\n throw new TypeError('`maxAge` must be a number greater than 0')\n }\n\n // TODO: Use private class fields when ESLint supports them.\n this.maxSize = options.maxSize\n this.maxAge = options.maxAge || Number.POSITIVE_INFINITY\n this.onEviction = options.onEviction\n this.cache = new Map()\n this.oldCache = new Map()\n this._size = 0\n }\n\n // TODO: Use private class methods when targeting Node.js 16.\n _emitEvictions(cache) {\n if (typeof this.onEviction !== 'function') {\n return\n }\n\n for (const [key, item] of cache) {\n this.onEviction(key, item.value)\n }\n }\n\n _deleteIfExpired(key, item) {\n if (typeof item.expiry === 'number' && item.expiry <= Date.now()) {\n if (typeof this.onEviction === 'function') {\n this.onEviction(key, item.value)\n }\n\n return this.delete(key)\n }\n\n return false\n }\n\n _getOrDeleteIfExpired(key, item) {\n const deleted = this._deleteIfExpired(key, item)\n if (!deleted) {\n return item.value\n }\n }\n\n _getItemValue(key, item) {\n return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value\n }\n\n _peek(key, cache) {\n const item = cache.get(key)\n\n return this._getItemValue(key, item)\n }\n\n _set(key, value) {\n this.cache.set(key, value)\n this._size++\n\n if (this._size >= this.maxSize) {\n this._size = 0\n this._emitEvictions(this.oldCache)\n this.oldCache = this.cache\n this.cache = new Map()\n }\n }\n\n _moveToRecent(key, item) {\n this.oldCache.delete(key)\n this._set(key, item)\n }\n\n *_entriesAscending() {\n for (const item of this.oldCache) {\n const [key, value] = item\n if (!this.cache.has(key)) {\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield item\n }\n }\n }\n\n for (const item of this.cache) {\n const [key, value] = item\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield item\n }\n }\n }\n\n get(key) {\n if (this.cache.has(key)) {\n const item = this.cache.get(key)\n\n return this._getItemValue(key, item)\n }\n\n if (this.oldCache.has(key)) {\n const item = this.oldCache.get(key)\n if (!this._deleteIfExpired(key, item)) {\n this._moveToRecent(key, item)\n return item.value\n }\n }\n }\n\n set(key, value, { maxAge = this.maxAge } = {}) {\n const expiry =\n typeof maxAge === 'number' && maxAge !== Number.POSITIVE_INFINITY\n ? Date.now() + maxAge\n : undefined\n if (this.cache.has(key)) {\n this.cache.set(key, {\n value,\n expiry,\n })\n } else {\n this._set(key, { value, expiry })\n }\n }\n\n has(key) {\n if (this.cache.has(key)) {\n return !this._deleteIfExpired(key, this.cache.get(key))\n }\n\n if (this.oldCache.has(key)) {\n return !this._deleteIfExpired(key, this.oldCache.get(key))\n }\n\n return false\n }\n\n peek(key) {\n if (this.cache.has(key)) {\n return this._peek(key, this.cache)\n }\n\n if (this.oldCache.has(key)) {\n return this._peek(key, this.oldCache)\n }\n }\n\n delete(key) {\n const deleted = this.cache.delete(key)\n if (deleted) {\n this._size--\n }\n\n return this.oldCache.delete(key) || deleted\n }\n\n clear() {\n this.cache.clear()\n this.oldCache.clear()\n this._size = 0\n }\n\n resize(newSize) {\n if (!(newSize && newSize > 0)) {\n throw new TypeError('`maxSize` must be a number greater than 0')\n }\n\n const items = [...this._entriesAscending()]\n const removeCount = items.length - newSize\n if (removeCount < 0) {\n this.cache = new Map(items)\n this.oldCache = new Map()\n this._size = items.length\n } else {\n if (removeCount > 0) {\n this._emitEvictions(items.slice(0, removeCount))\n }\n\n this.oldCache = new Map(items.slice(removeCount))\n this.cache = new Map()\n this._size = 0\n }\n\n this.maxSize = newSize\n }\n\n *keys() {\n for (const [key] of this) {\n yield key\n }\n }\n\n *values() {\n for (const [, value] of this) {\n yield value\n }\n }\n\n *[Symbol.iterator]() {\n for (const item of this.cache) {\n const [key, value] = item\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield [key, value.value]\n }\n }\n\n for (const item of this.oldCache) {\n const [key, value] = item\n if (!this.cache.has(key)) {\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield [key, value.value]\n }\n }\n }\n }\n\n *entriesDescending() {\n let items = [...this.cache]\n for (let i = items.length - 1; i >= 0; --i) {\n const item = items[i]\n const [key, value] = item\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield [key, value.value]\n }\n }\n\n items = [...this.oldCache]\n for (let i = items.length - 1; i >= 0; --i) {\n const item = items[i]\n const [key, value] = item\n if (!this.cache.has(key)) {\n const deleted = this._deleteIfExpired(key, value)\n if (!deleted) {\n yield [key, value.value]\n }\n }\n }\n }\n\n *entriesAscending() {\n for (const [key, value] of this._entriesAscending()) {\n yield [key, value.value]\n }\n }\n\n get size() {\n if (!this._size) {\n return this.oldCache.size\n }\n\n let oldCacheSize = 0\n for (const key of this.oldCache.keys()) {\n if (!this.cache.has(key)) {\n oldCacheSize++\n }\n }\n\n return Math.min(this._size + oldCacheSize, this.maxSize)\n }\n\n entries() {\n return this.entriesAscending()\n }\n\n forEach(callbackFunction, thisArgument = this) {\n for (const [key, value] of this.entriesAscending()) {\n callbackFunction.call(thisArgument, value, key, this)\n }\n }\n\n get [Symbol.toStringTag]() {\n return JSON.stringify([...this.entriesAscending()])\n }\n}\n","import React, { useEffect, useRef, useState } from 'react'\nimport isObject from 'is-object'\nimport PluginManager from '../PluginManager'\nimport type { Buffer } from 'buffer'\nimport {\n addDisposer,\n getParent,\n getSnapshot,\n getEnv as getEnvMST,\n isAlive,\n isStateTreeNode,\n hasParent,\n IAnyStateTreeNode,\n IStateTreeNode,\n Instance,\n} from 'mobx-state-tree'\nimport { reaction, IReactionPublic, IReactionOptions } from 'mobx'\nimport { Feature } from './simpleFeature'\nimport {\n isSessionModel,\n isDisplayModel,\n isViewModel,\n isTrackModel,\n AssemblyManager,\n Region,\n TypeTestedByPredicate,\n} from './types'\nimport type { Region as MUIRegion } from './types/mst'\nimport { isAbortException, checkAbortSignal } from './aborting'\nimport { BaseBlock } from './blockTypes'\nimport { isUriLocation } from './types'\n\n// has to be the full path and not the relative path to get the jest mock\nimport useMeasure from '@jbrowse/core/util/useMeasure'\nimport { colord } from './colord'\n// eslint-disable-next-line react/no-deprecated\nimport { flushSync, render } from 'react-dom'\nexport * from './types'\nexport * from './aborting'\nexport * from './when'\nexport * from './range'\nexport * from './dedupe'\n\nexport * from './offscreenCanvasPonyfill'\nexport * from './offscreenCanvasUtils'\n\nexport function useDebounce<T>(value: T, delay: number) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n\n useEffect(() => {\n const handle = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n return () => {\n clearTimeout(handle)\n }\n }, [value, delay])\n\n return debouncedValue\n}\n\n// used in ViewContainer files to get the width\nexport function useWidthSetter(\n view: { setWidth: (arg: number) => void },\n padding: string,\n) {\n const [ref, { width }] = useMeasure()\n useEffect(() => {\n if (width && isAlive(view)) {\n // sets after a requestAnimationFrame\n // https://stackoverflow.com/a/58701523/2129219\n // avoids ResizeObserver loop error being shown during development\n requestAnimationFrame(() => {\n view.setWidth(width - Number.parseInt(padding, 10) * 2)\n })\n }\n }, [padding, view, width])\n return ref\n}\n\n// https://stackoverflow.com/questions/56283920/\nexport function useDebouncedCallback<T>(\n callback: (...args: T[]) => void,\n wait = 400,\n) {\n // track args & timeout handle between calls\n const argsRef = useRef<T[]>()\n const timeout = useRef<ReturnType<typeof setTimeout>>()\n\n // make sure our timeout gets cleared if our consuming component gets\n // unmounted\n useEffect(() => {\n if (timeout.current) {\n clearTimeout(timeout.current)\n }\n }, [])\n\n return function debouncedCallback(...args: T[]) {\n // capture latest args\n argsRef.current = args\n\n // clear debounce timer\n if (timeout.current) {\n clearTimeout(timeout.current)\n }\n\n // start waiting again\n timeout.current = setTimeout(() => {\n if (argsRef.current) {\n callback(...argsRef.current)\n }\n }, wait)\n }\n}\n\n/**\n * find the first node in the hierarchy that matches the given predicate\n */\nexport function findParentThat(\n node: IAnyStateTreeNode,\n predicate: (thing: IAnyStateTreeNode) => boolean,\n) {\n if (!hasParent(node)) {\n throw new Error('node does not have parent')\n }\n let currentNode: IAnyStateTreeNode | undefined = getParent<any>(node)\n while (currentNode && isAlive(currentNode)) {\n if (predicate(currentNode)) {\n return currentNode\n }\n if (hasParent(currentNode)) {\n currentNode = getParent<any>(currentNode)\n } else {\n break\n }\n }\n throw new Error('no matching node found')\n}\n\ninterface Animation {\n lastPosition: number\n lastTime?: number\n lastVelocity?: number\n}\n\n// based on https://github.com/react-spring/react-spring/blob/cd5548a987383b8023efd620f3726a981f9e18ea/src/animated/FrameLoop.ts\nexport function springAnimate(\n fromValue: number,\n toValue: number,\n setValue: (value: number) => void,\n onFinish = () => {},\n precision = 0,\n tension = 400,\n friction = 20,\n clamp = true,\n) {\n const mass = 1\n if (!precision) {\n precision = Math.abs(toValue - fromValue) / 1000\n }\n\n let animationFrameId: number\n\n function update(animation: Animation) {\n const time = Date.now()\n let position = animation.lastPosition\n let lastTime = animation.lastTime || time\n let velocity = animation.lastVelocity || 0\n // If we lost a lot of frames just jump to the end.\n if (time > lastTime + 64) {\n lastTime = time\n }\n // http://gafferongames.com/game-physics/fix-your-timestep/\n const numSteps = Math.floor(time - lastTime)\n for (let i = 0; i < numSteps; ++i) {\n const force = -tension * (position - toValue)\n const damping = -friction * velocity\n const acceleration = (force + damping) / mass\n velocity += (acceleration * 1) / 1000\n position += (velocity * 1) / 1000\n }\n const isVelocity = Math.abs(velocity) <= precision\n const isDisplacement =\n tension !== 0 ? Math.abs(toValue - position) <= precision : true\n const isOvershooting =\n clamp && tension !== 0\n ? fromValue < toValue\n ? position > toValue\n : position < toValue\n : false\n const endOfAnimation = isOvershooting || (isVelocity && isDisplacement)\n if (endOfAnimation) {\n setValue(toValue)\n onFinish()\n } else {\n setValue(position)\n animationFrameId = requestAnimationFrame(() => {\n update({\n lastPosition: position,\n lastTime: time,\n lastVelocity: velocity,\n })\n })\n }\n }\n\n return [\n () => {\n update({ lastPosition: fromValue })\n },\n () => {\n cancelAnimationFrame(animationFrameId)\n },\n ]\n}\n\n/**\n * find the first node in the hierarchy that matches the given 'is' typescript\n * type guard predicate\n */\nexport function findParentThatIs<T extends (a: IAnyStateTreeNode) => boolean>(\n node: IAnyStateTreeNode,\n predicate: T,\n): TypeTestedByPredicate<T> {\n return findParentThat(node, predicate)\n}\n\n/**\n * get the current JBrowse session model, starting at any node in the state\n * tree\n */\nexport function getSession(node: IAnyStateTreeNode) {\n try {\n return findParentThatIs(node, isSessionModel)\n } catch (e) {\n throw new Error('no session model found!')\n }\n}\n\n/**\n * get the state model of the view in the state tree that contains the given\n * node\n */\nexport function getContainingView(node: IAnyStateTreeNode) {\n try {\n return findParentThatIs(node, isViewModel)\n } catch (e) {\n throw new Error('no containing view found')\n }\n}\n\n/**\n * get the state model of the view in the state tree that contains the given\n * node\n */\nexport function getContainingTrack(node: IAnyStateTreeNode) {\n try {\n return findParentThatIs(node, isTrackModel)\n } catch (e) {\n throw new Error('no containing track found')\n }\n}\n\n/**\n * get the state model of the display in the state tree that contains the given\n * node\n */\nexport function getContainingDisplay(node: IAnyStateTreeNode) {\n try {\n return findParentThatIs(node, isDisplayModel)\n } catch (e) {\n throw new Error('no containing display found')\n }\n}\n\n/**\n * Assemble a 1-based \"locString\" from an interbase genomic location\n * @param region - Region\n * @example\n * ```ts\n * assembleLocString({ refName: 'chr1', start: 0, end: 100 })\n * // ↳ 'chr1:1..100'\n * ```\n * @example\n * ```ts\n * assembleLocString({ assemblyName: 'hg19', refName: 'chr1', start: 0, end: 100 })\n * // ↳ '{hg19}chr1:1..100'\n * ```\n * @example\n * ```ts\n * assembleLocString({ refName: 'chr1' })\n * // ↳ 'chr1'\n * ```\n * @example\n * ```ts\n * assembleLocString({ refName: 'chr1', start: 0 })\n * // ↳ 'chr1:1..'\n * ```\n * @example\n * ```ts\n * assembleLocString({ refName: 'chr1', end: 100 })\n * // ↳ 'chr1:1..100'\n * ```\n * @example\n * ```ts\n * assembleLocString({ refName: 'chr1', start: 0, end: 1 })\n * // ↳ 'chr1:1'\n * ```\n */\nexport function assembleLocString(region: ParsedLocString) {\n return assembleLocStringFast(region, toLocale)\n}\n\n// same as assembleLocString above, but does not perform toLocaleString which\n// can slow down the speed of block calculations which use assembleLocString\n// for block.key\nexport function assembleLocStringFast(\n region: ParsedLocString,\n cb = (n: number): string | number => n,\n) {\n const { assemblyName, refName, start, end, reversed } = region\n const assemblyNameString = assemblyName ? `{${assemblyName}}` : ''\n let startString: string\n if (start !== undefined) {\n startString = `:${cb(start + 1)}`\n } else if (end !== undefined) {\n startString = ':1'\n } else {\n startString = ''\n }\n let endString: string\n if (end !== undefined) {\n endString = start !== undefined && start + 1 === end ? '' : `..${cb(end)}`\n } else {\n endString = start !== undefined ? '..' : ''\n }\n let rev = ''\n if (reversed) {\n rev = '[rev]'\n }\n return `${assemblyNameString}${refName}${startString}${endString}${rev}`\n}\n\nexport interface ParsedLocString {\n assemblyName?: string\n refName: string\n start?: number\n end?: number\n reversed?: boolean\n}\n\nexport function parseLocStringOneBased(\n locString: string,\n isValidRefName: (refName: string, assemblyName?: string) => boolean,\n): ParsedLocString {\n if (!locString) {\n throw new Error('no location string provided, could not parse')\n }\n let reversed = false\n if (locString.endsWith('[rev]')) {\n reversed = true\n locString = locString.replace(/\\[rev]$/, '')\n }\n // remove any whitespace\n locString = locString.replace(/\\s/, '')\n // refNames can have colons, refer to\n // https://samtools.github.io/hts-specs/SAMv1.pdf Appendix A\n const assemblyMatch = /({(.+)})?(.+)/.exec(locString)\n if (!assemblyMatch) {\n throw new Error(`invalid location string: \"${locString}\"`)\n }\n const [, , assemblyName2, location2] = assemblyMatch\n const assemblyName = assemblyName2!\n const location = location2!\n if (!assemblyName && location.startsWith('{}')) {\n throw new Error(`no assembly name was provided in location \"${location}\"`)\n }\n const lastColonIdx = location.lastIndexOf(':')\n if (lastColonIdx === -1) {\n if (isValidRefName(location, assemblyName)) {\n return {\n assemblyName,\n refName: location,\n reversed,\n }\n }\n throw new Error(`Unknown reference sequence \"${location}\"`)\n }\n const prefix = location.slice(0, lastColonIdx)\n const suffix = location.slice(lastColonIdx + 1)\n if (\n isValidRefName(prefix, assemblyName) &&\n isValidRefName(location, assemblyName)\n ) {\n throw new Error(`ambiguous location string: \"${locString}\"`)\n } else if (isValidRefName(prefix, assemblyName)) {\n if (suffix) {\n // see if it's a range\n const rangeMatch =\n /^(-?(\\d+|\\d{1,3}(,\\d{3})*))(\\.\\.|-)(-?(\\d+|\\d{1,3}(,\\d{3})*))$/.exec(\n suffix,\n )\n // see if it's a single point\n const singleMatch = /^(-?(\\d+|\\d{1,3}(,\\d{3})*))(\\.\\.|-)?$/.exec(suffix)\n if (rangeMatch) {\n const [, start, , , , end] = rangeMatch\n if (start !== undefined && end !== undefined) {\n return {\n assemblyName,\n refName: prefix,\n start: +start.replaceAll(',', ''),\n end: +end.replaceAll(',', ''),\n reversed,\n }\n }\n } else if (singleMatch) {\n const [, start, , , separator] = singleMatch\n if (start !== undefined) {\n if (separator) {\n // indefinite end\n return {\n assemblyName,\n refName: prefix,\n start: +start.replaceAll(',', ''),\n reversed,\n }\n }\n return {\n assemblyName,\n refName: prefix,\n start: +start.replaceAll(',', ''),\n end: +start.replaceAll(',', ''),\n reversed,\n }\n }\n } else {\n throw new Error(\n `could not parse range \"${suffix}\" on location \"${locString}\"`,\n )\n }\n } else {\n return {\n assemblyName,\n refName: prefix,\n reversed,\n }\n }\n } else if (isValidRefName(location, assemblyName)) {\n return {\n assemblyName,\n refName: location,\n reversed,\n }\n }\n throw new Error(`unknown reference sequence name in location \"${locString}\"`)\n}\n\n/**\n * Parse a 1-based location string into an interbase genomic location\n * @param locString - Location string\n * @param isValidRefName - Function that checks if a refName exists in the set\n * of all known refNames, or in the set of refNames for an assembly if\n * assemblyName is given\n * @example\n * ```ts\n * parseLocString('chr1:1..100', isValidRefName)\n * // ↳ { refName: 'chr1', start: 0, end: 100 }\n * ```\n * @example\n * ```ts\n * parseLocString('chr1:1-100', isValidRefName)\n * // ↳ { refName: 'chr1', start: 0, end: 100 }\n * ```\n * @example\n * ```ts\n * parseLocString(`{hg19}chr1:1..100`, isValidRefName)\n * // ↳ { assemblyName: 'hg19', refName: 'chr1', start: 0, end: 100 }\n * ```\n * @example\n * ```ts\n * parseLocString('chr1', isValidRefName)\n * // ↳ { refName: 'chr1' }\n * ```\n * @example\n * ```ts\n * parseLocString('chr1:1', isValidRefName)\n * // ↳ { refName: 'chr1', start: 0, end: 1 }\n * ```\n * @example\n * ```ts\n * parseLocString('chr1:1..', isValidRefName)\n * // ↳ { refName: 'chr1', start: 0}\n * ```\n */\nexport function parseLocString(\n locString: string,\n isValidRefName: (refName: string, assemblyName?: string) => boolean,\n) {\n const parsed = parseLocStringOneBased(locString, isValidRefName)\n if (typeof parsed.start === 'number') {\n parsed.start -= 1\n }\n return parsed\n}\n\nexport function compareLocs(locA: ParsedLocString, locB: ParsedLocString) {\n const assemblyComp =\n locA.assemblyName || locB.assemblyName\n ? (locA.assemblyName || '').localeCompare(locB.assemblyName || '')\n : 0\n if (assemblyComp) {\n return assemblyComp\n }\n\n const refComp =\n locA.refName || locB.refName\n ? (locA.refName || '').localeCompare(locB.refName || '')\n : 0\n if (refComp) {\n return refComp\n }\n\n if (locA.start !== undefined && locB.start !== undefined) {\n const startComp = locA.start - locB.start\n if (startComp) {\n return startComp\n }\n }\n if (locA.end !== undefined && locB.end !== undefined) {\n const endComp = locA.end - locB.end\n if (endComp) {\n return endComp\n }\n }\n return 0\n}\n\nexport function compareLocStrings(\n a: string,\n b: string,\n isValidRefName: (refName: string, assemblyName?: string) => boolean,\n) {\n const locA = parseLocString(a, isValidRefName)\n const locB = parseLocString(b, isValidRefName)\n return compareLocs(locA, locB)\n}\n\n/**\n * Ensure that a number is at least min and at most max.\n *\n * @param num -\n * @param min -\n * @param max -\n */\nexport function clamp(num: number, min: number, max: number) {\n if (num < min) {\n return min\n }\n if (num > max) {\n return max\n }\n return num\n}\n\nfunction roundToNearestPointOne(num: number) {\n return Math.round(num * 10) / 10\n}\n\n/**\n * @param bp -\n * @param region -\n * @param bpPerPx -\n */\nexport function bpToPx(\n bp: number,\n {\n reversed,\n end = 0,\n start = 0,\n }: { start?: number; end?: number; reversed?: boolean },\n bpPerPx: number,\n) {\n return roundToNearestPointOne((reversed ? end - bp : bp - start) / bpPerPx)\n}\n\nconst oneEightyOverPi = 180 / Math.PI\nconst piOverOneEighty = Math.PI / 180\nexport function radToDeg(radians: number) {\n return (radians * oneEightyOverPi) % 360\n}\nexport function degToRad(degrees: number) {\n return (degrees * piOverOneEighty) % (2 * Math.PI)\n}\n\n/**\n * @returns [x, y]\n */\nexport function polarToCartesian(rho: number, theta: number) {\n return [rho * Math.cos(theta), rho * Math.sin(theta)] as [number, number]\n}\n\n/**\n * @param x - the x\n * @param y - the y\n * @returns [rho, theta]\n */\nexport function cartesianToPolar(x: number, y: number) {\n const rho = Math.sqrt(x * x + y * y)\n const theta = Math.atan(y / x)\n return [rho, theta] as [number, number]\n}\n\nexport function featureSpanPx(\n feature: Feature,\n region: { start: number; end: number; reversed?: boolean },\n bpPerPx: number,\n): [number, number] {\n return bpSpanPx(feature.get('start'), feature.get('end'), region, bpPerPx)\n}\n\nexport function bpSpanPx(\n leftBp: number,\n rightBp: number,\n region: { start: number; end: number; reversed?: boolean },\n bpPerPx: number,\n): [number, number] {\n const start = bpToPx(leftBp, region, bpPerPx)\n const end = bpToPx(rightBp, region, bpPerPx)\n return region.reversed ? [end, start] : [start, end]\n}\n\n// do an array map of an iterable\nexport function iterMap<T, U>(\n iter: Iterable<T>,\n func: (arg: T) => U,\n sizeHint?: number,\n) {\n const results = Array.from<U>({ length: sizeHint || 0 })\n let counter = 0\n for (const item of iter) {\n results[counter] = func(item)\n counter += 1\n }\n return results\n}\n\n/**\n * Returns the index of the last element in the array where predicate is true,\n * and -1 otherwise.\n * Based on https://stackoverflow.com/a/53187807\n *\n * @param array - The source array to search in\n *\n * @param predicate - find calls predicate once for each element of the array, in\n * descending order, until it finds one where predicate returns true.\n *\n * @returns findLastIndex returns element index where predicate is true.\n * Otherwise, findLastIndex returns -1.\n */\nexport function findLastIndex<T>(\n array: T[],\n predicate: (value: T, index: number, obj: T[]) => boolean,\n): number {\n let l = array.length\n while (l--) {\n if (predicate(array[l]!, l, array)) {\n return l\n }\n }\n return -1\n}\n\nexport function findLast<T>(\n array: T[],\n predicate: (value: T, index: number, obj: T[]) => boolean,\n): T | undefined {\n let l = array.length\n while (l--) {\n if (predicate(array[l]!, l, array)) {\n return array[l]\n }\n }\n return undefined\n}\n\n/**\n * makes a mobx reaction with the given functions, that calls actions on the\n * model for each stage of execution, and to abort the reaction function when\n * the model is destroyed.\n *\n * Will call startedFunction(signal), successFunction(result), and\n * errorFunction(error) when the async reaction function starts, completes, and\n * errors respectively.\n *\n * @param self -\n * @param dataFunction -\n * @param asyncReactionFunction -\n * @param reactionOptions -\n * @param startedFunction -\n * @param successFunction -\n * @param errorFunction -\n */\nexport function makeAbortableReaction<T, U, V>(\n self: T,\n dataFunction: (arg: T) => U,\n asyncReactionFunction: (\n arg: U | undefined,\n signal: AbortSignal,\n model: T,\n handle: IReactionPublic,\n ) => Promise<V>,\n // @ts-expect-error\n reactionOptions: IReactionOptions,\n startedFunction: (aborter: AbortController) => void,\n successFunction: (arg: V) => void,\n errorFunction: (err: unknown) => void,\n) {\n let inProgress: AbortController | undefined\n\n function handleError(error: unknown) {\n if (!isAbortException(error)) {\n if (isAlive(self)) {\n errorFunction(error)\n } else {\n console.error(error)\n }\n }\n }\n\n addDisposer(\n self,\n reaction(\n () => {\n try {\n return dataFunction(self)\n } catch (e) {\n handleError(e)\n return undefined\n }\n },\n async (data, mobxReactionHandle) => {\n if (inProgress && !inProgress.signal.aborted) {\n inProgress.abort()\n }\n\n if (!isAlive(self)) {\n return\n }\n inProgress = new AbortController()\n\n const thisInProgress = inProgress\n startedFunction(thisInProgress)\n try {\n const result = await asyncReactionFunction(\n data,\n thisInProgress.signal,\n self,\n // @ts-expect-error\n mobxReactionHandle,\n )\n checkAbortSignal(thisInProgress.signal)\n if (isAlive(self)) {\n successFunction(result)\n }\n } catch (e) {\n if (!thisInProgress.signal.aborted) {\n thisInProgress.abort()\n }\n handleError(e)\n }\n },\n reactionOptions,\n ),\n )\n addDisposer(self, () => {\n if (inProgress && !inProgress.signal.aborted) {\n inProgress.abort()\n }\n })\n}\n\nexport function renameRegionIfNeeded(\n refNameMap: Record<string, string> | undefined,\n region: Region | Instance<typeof MUIRegion>,\n): Region & { originalRefName?: string } {\n if (isStateTreeNode(region) && !isAlive(region)) {\n return region\n }\n\n if (refNameMap?.[region.refName]) {\n // clone the region so we don't modify it\n region = isStateTreeNode(region)\n ? { ...getSnapshot(region) }\n : { ...region }\n\n // modify it directly in the container\n const newRef = refNameMap[region.refName]\n if (newRef) {\n return { ...region, refName: newRef, originalRefName: region.refName }\n }\n }\n return region\n}\n\nexport async function renameRegionsIfNeeded<\n ARGTYPE extends {\n assemblyName?: string\n regions?: Region[]\n signal?: AbortSignal\n adapterConfig: Record<string, unknown>\n sessionId: string\n statusCallback?: (arg: string) => void\n },\n>(assemblyManager: AssemblyManager, args: ARGTYPE) {\n const { regions = [], adapterConfig } = args\n if (!args.sessionId) {\n throw new Error('sessionId is required')\n }\n\n const assemblyNames = regions.map(region => region.assemblyName)\n const assemblyMaps = Object.fromEntries(\n await Promise.all(\n [...new Set(assemblyNames)].map(async assemblyName => {\n return [\n assemblyName,\n await assemblyManager.getRefNameMapForAdapter(\n adapterConfig,\n assemblyName,\n args,\n ),\n ]\n }),\n ),\n )\n\n return {\n ...args,\n regions: regions.map((region, i) =>\n // note: uses assemblyNames defined above since region could be dead now\n renameRegionIfNeeded(assemblyMaps[assemblyNames[i]!], region),\n ),\n }\n}\n\nexport function minmax(a: number, b: number) {\n return [Math.min(a, b), Math.max(a, b)] as const\n}\n\nexport function shorten(name: string, max = 70, short = 30) {\n return name.length > max\n ? `${name.slice(0, short)}...${name.slice(-short)}`\n : name\n}\n\nexport function stringify(\n {\n refName,\n coord,\n assemblyName,\n oob,\n }: {\n assemblyName?: string\n coord: number\n refName?: string\n oob?: boolean\n },\n useAssemblyName?: boolean,\n) {\n return [\n assemblyName && useAssemblyName ? `{${assemblyName}}` : '',\n refName\n ? `${shorten(refName)}:${toLocale(coord)}${oob ? ' (out of bounds)' : ''}`\n : '',\n ].join('')\n}\n\n// this is recommended in a later comment in\n// https://github.com/electron/electron/issues/2288 for detecting electron in a\n// renderer process, which is the one that has node enabled for us\n//\n// const isElectron = process.versions.electron\n// const i2 = process.versions.hasOwnProperty('electron')\nexport const isElectron = /electron/i.test(\n typeof navigator !== 'undefined' ? navigator.userAgent : '',\n)\n\nexport function revcom(seqString: string) {\n return reverse(complement(seqString))\n}\n\nexport function reverse(seqString: string) {\n return seqString.split('').reverse().join('')\n}\n\nexport const complement = (() => {\n const complementRegex = /[ACGT]/gi\n\n // from bioperl: tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/\n // generated with:\n // perl -MJSON -E '@l = split \"\",\"acgtrymkswhbvdnxACGTRYMKSWHBVDNX\"; print to_json({ map { my $in = $_; tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/; $in => $_ } @l})'\n const complementTable = {\n S: 'S',\n w: 'w',\n T: 'A',\n r: 'y',\n a: 't',\n N: 'N',\n K: 'M',\n x: 'x',\n d: 'h',\n Y: 'R',\n V: 'B',\n y: 'r',\n M: 'K',\n h: 'd',\n k: 'm',\n C: 'G',\n g: 'c',\n t: 'a',\n A: 'T',\n n: 'n',\n W: 'W',\n X: 'X',\n m: 'k',\n v: 'b',\n B: 'V',\n s: 's',\n H: 'D',\n c: 'g',\n D: 'H',\n b: 'v',\n R: 'Y',\n G: 'C',\n } as Record<string, string>\n\n return (seqString: string) => {\n return seqString.replaceAll(complementRegex, m => complementTable[m] || '')\n }\n})()\n\n// requires immediate execution in jest environment, because (hypothesis) it\n// otherwise listens for prerendered_canvas but reads empty pixels, and doesn't\n// get the contents of the canvas\nexport const rIC =\n typeof jest === 'undefined'\n ? // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n typeof window !== 'undefined' && window.requestIdleCallback\n ? window.requestIdleCallback\n : (cb: () => void) =>\n setTimeout(() => {\n cb()\n }, 1)\n : (cb: () => void) => {\n cb()\n }\n\n// prettier-ignore\nconst widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625]\n\n// xref https://gist.github.com/tophtucker/62f93a4658387bb61e4510c37e2e97cf\nexport function measureText(str: unknown, fontSize = 10) {\n const avg = 0.5279276315789471\n const s = String(str)\n let total = 0\n for (let i = 0; i < s.length; i++) {\n const code = s.charCodeAt(i)\n total += widths[code] ?? avg\n }\n return total * fontSize\n}\n\nexport type Frame = 1 | 2 | 3 | -1 | -2 | -3\n\nexport function getFrame(\n start: number,\n end: number,\n strand: 1 | -1,\n phase: 0 | 1 | 2,\n): Frame {\n return strand === 1\n ? ((((start + phase) % 3) + 1) as 1 | 2 | 3)\n : ((-1 * ((end - phase) % 3) - 1) as -1 | -2 | -3)\n}\n\nexport const defaultStarts = ['ATG']\nexport const defaultStops = ['TAA', 'TAG', 'TGA']\nexport const defaultCodonTable = {\n TCA: 'S',\n TCC: 'S',\n TCG: 'S',\n TCT: 'S',\n TTC: 'F',\n TTT: 'F',\n TTA: 'L',\n TTG: 'L',\n TAC: 'Y',\n TAT: 'Y',\n TAA: '*',\n TAG: '*',\n TGC: 'C',\n TGT: 'C',\n TGA: '*',\n TGG: 'W',\n CTA: 'L',\n CTC: 'L',\n CTG: 'L',\n CTT: 'L',\n CCA: 'P',\n CCC: 'P',\n CCG: 'P',\n CCT: 'P',\n CAC: 'H',\n CAT: 'H',\n CAA: 'Q',\n CAG: 'Q',\n CGA: 'R',\n CGC: 'R',\n CGG: 'R',\n CGT: 'R',\n ATA: 'I',\n ATC: 'I',\n ATT: 'I',\n ATG: 'M',\n ACA: 'T',\n ACC: 'T',\n ACG: 'T',\n ACT: 'T',\n AAC: 'N',\n AAT: 'N',\n AAA: 'K',\n AAG: 'K',\n AGC: 'S',\n AGT: 'S',\n AGA: 'R',\n AGG: 'R',\n GTA: 'V',\n GTC: 'V',\n GTG: 'V',\n GTT: 'V',\n GCA: 'A',\n GCC: 'A',\n GCG: 'A',\n GCT: 'A',\n GAC: 'D',\n GAT: 'D',\n GAA: 'E',\n GAG: 'E',\n GGA: 'G',\n GGC: 'G',\n GGG: 'G',\n GGT: 'G',\n}\n\n/**\n * take CodonTable above and generate larger codon table that includes all\n * permutations of upper and lower case nucleotides\n */\nexport function generateCodonTable(table: any) {\n const tempCodonTable: Record<string, string> = {}\n Object.keys(table).forEach(codon => {\n const aa = table[codon]\n const nucs: string[][] = []\n for (let i = 0; i < 3; i++) {\n const nuc = codon.charAt(i)\n nucs[i] = []\n nucs[i]![0] = nuc.toUpperCase()\n nucs[i]![1] = nuc.toLowerCase()\n }\n for (let i = 0; i < 2; i++) {\n const n0 = nucs[0]![i]!\n for (let j = 0; j < 2; j++) {\n const n1 = nucs[1]![j]!\n for (let k = 0; k < 2; k++) {\n const n2 = nucs[2]![k]!\n const triplet = n0 + n1 + n2\n tempCodonTable[triplet] = aa\n }\n }\n }\n })\n return tempCodonTable\n}\n\n// call statusCallback with current status and clear when finished\nexport async function updateStatus<U>(\n msg: string,\n cb: (arg: string) => void,\n fn: () => U | Promise<U>,\n) {\n cb(msg)\n const res = await fn()\n cb('')\n return res\n}\n\nexport function hashCode(str: string) {\n let hash = 0\n if (str.length === 0) {\n return hash\n }\n for (let i = 0; i < str.length; i++) {\n const chr = str.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0 // Convert to 32bit integer\n }\n return hash\n}\n\nexport function objectHash(obj: Record<string, any>) {\n return `${hashCode(JSON.stringify(obj))}`\n}\n\ninterface VirtualOffset {\n blockPosition: number\n}\ninterface Block {\n minv: VirtualOffset\n maxv: VirtualOffset\n}\n\nexport async function bytesForRegions(\n regions: Region[],\n index: {\n blocksForRange: (\n ref: string,\n start: number,\n end: number,\n ) => Promise<Block[]>\n },\n) {\n const blockResults = await Promise.all(\n regions.map(r => index.blocksForRange(r.refName, r.start, r.end)),\n )\n\n return blockResults\n .flat()\n .map(block => ({\n start: block.minv.blockPosition,\n end: block.maxv.blockPosition + 65535,\n }))\n .reduce((a, b) => a + b.end - b.start, 0)\n}\n\nexport interface ViewSnap {\n bpPerPx: number\n interRegionPaddingWidth: number\n minimumBlockWidth: number\n width: number\n offsetPx: number\n staticBlocks: { contentBlocks: BaseBlock[]; blocks: BaseBlock[] }\n displayedRegions: (IStateTreeNode & {\n start: number\n end: number\n refName: string\n reversed?: boolean\n assemblyName: string\n })[]\n}\n\n// supported adapter types by text indexer ensure that this matches the method\n// found in @jbrowse/text-indexing/util\nexport function isSupportedIndexingAdapter(type = '') {\n return [\n 'Gff3TabixAdapter',\n 'VcfTabixAdapter',\n 'Gff3Adapter',\n 'VcfAdapter',\n ].includes(type)\n}\n\nexport function getBpDisplayStr(totalBp: number) {\n if (Math.floor(totalBp / 1_000_000) > 0) {\n return `${Number.parseFloat((totalBp / 1_000_000).toPrecision(3))}Mbp`\n } else if (Math.floor(totalBp / 1_000) > 0) {\n return `${Number.parseFloat((totalBp / 1_000).toPrecision(3))}Kbp`\n } else {\n return `${toLocale(Math.floor(totalBp))}bp`\n }\n}\n\nexport function toLocale(n: number) {\n return n.toLocaleString('en-US')\n}\n\nexport function getTickDisplayStr(totalBp: number, bpPerPx: number) {\n return Math.floor(bpPerPx / 1_000) > 0\n ? `${toLocale(Number.parseFloat((totalBp / 1_000_000).toFixed(2)))}M`\n : toLocale(Math.floor(totalBp))\n}\n\nexport function getViewParams(model: IAnyStateTreeNode, exportSVG?: boolean) {\n // @ts-expect-error\n const { dynamicBlocks, staticBlocks, offsetPx } = getContainingView(model)\n const b = dynamicBlocks?.contentBlocks[0] || {}\n const staticblock = staticBlocks?.contentBlocks[0] || {}\n const staticblock1 = staticBlocks?.contentBlocks[1] || {}\n return {\n offsetPx: exportSVG ? 0 : offsetPx - staticblock.offsetPx,\n offsetPx1: exportSVG ? 0 : offsetPx - staticblock1.offsetPx,\n start: b.start as number,\n end: b.end as number,\n }\n}\n\nexport function getLayoutId({\n sessionId,\n layoutId,\n}: {\n sessionId: string\n layoutId: string\n}) {\n return `${sessionId}-${layoutId}`\n}\n\n// Hook from https://usehooks.com/useLocalStorage/\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === 'undefined') {\n return initialValue\n }\n try {\n const item = window.localStorage.getItem(key)\n return item ? JSON.parse(item) : initialValue\n } catch (error) {\n console.error(error)\n return initialValue\n }\n })\n const setValue = (value: T | ((val: T) => T)) => {\n try {\n const valueToStore =\n value instanceof Function ? value(storedValue) : value\n setStoredValue(valueToStore)\n if (typeof window !== 'undefined') {\n window.localStorage.setItem(key, JSON.stringify(valueToStore))\n }\n } catch (error) {\n console.error(error)\n }\n }\n return [storedValue, setValue] as const\n}\n\nexport function getUriLink(value: { uri: string; baseUri?: string }) {\n const { uri, baseUri = '' } = value\n let href: string\n try {\n href = new URL(uri, baseUri).href\n } catch (e) {\n href = uri\n }\n return href\n}\n\nexport function getStr(obj: unknown) {\n return isObject(obj)\n ? isUriLocation(obj)\n ? getUriLink(obj)\n : JSON.stringify(obj)\n : String(obj)\n}\n\n// tries to measure grid width without HTML tags included\nexport function coarseStripHTML(s: string) {\n return s.replaceAll(/(<([^>]+)>)/gi, '')\n}\n\n// based on autolink-js, license MIT\n// https://github.com/bryanwoods/autolink-js/blob/1418049970152c56ced73d43dcc62d80b320fb71/autolink.js#L9\nexport function linkify(s: string) {\n const pattern =\n /(^|[\\s\\n]|<[A-Za-z]*\\/?>)((?:https?|ftp):\\/\\/[-A-Z0-9+\\u0026\\u2019@#/%?=()~_|!:,.;]*[-A-Z0-9+\\u0026@#/%=~()_|])/gi\n return s.replaceAll(pattern, '$1<a href=\\'$2\\' target=\"_blank\">$2</a>')\n}\n\n// heuristic measurement for a column of a @mui/x-data-grid, pass in\n// values from a column\nexport function measureGridWidth(\n elements: unknown[],\n args?: {\n minWidth?: number\n fontSize?: number\n maxWidth?: number\n padding?: number\n stripHTML?: boolean\n },\n) {\n const {\n padding = 30,\n minWidth = 80,\n fontSize = 12,\n maxWidth = 1000,\n stripHTML = false,\n } = args || {}\n return max(\n elements\n .map(element => getStr(element))\n .map(str => (stripHTML ? coarseStripHTML(str) : str))\n .map(str => measureText(str, fontSize))\n .map(n => Math.min(Math.max(n + padding, minWidth), maxWidth)),\n )\n}\n\nexport function getEnv(obj: any) {\n return getEnvMST<{ pluginManager: PluginManager }>(obj)\n}\n\nexport function localStorageGetItem(item: string) {\n return typeof localStorage !== 'undefined'\n ? localStorage.getItem(item)\n : undefined\n}\n\nexport function localStorageSetItem(str: string, item: string) {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(str, item)\n }\n}\n\nexport function max(arr: number[], init = Number.NEGATIVE_INFINITY) {\n let max = init\n for (const entry of arr) {\n max = entry > max ? entry : max\n }\n return max\n}\n\nexport function min(arr: number[], init = Number.POSITIVE_INFINITY) {\n let min = init\n for (const entry of arr) {\n min = entry < min ? entry : min\n }\n return min\n}\n\nexport function sum(arr: number[]) {\n let sum = 0\n for (const entry of arr) {\n sum += entry\n }\n return sum\n}\n\nexport function avg(arr: number[]) {\n return sum(arr) / arr.length\n}\n\nexport function groupBy<T>(array: Iterable<T>, predicate: (v: T) => string) {\n const result = {} as Record<string, T[]>\n for (const value of array) {\n const t = predicate(value)\n if (!result[t]) {\n result[t] = []\n }\n result[t].push(value)\n }\n return result\n}\n\nexport function notEmpty<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n\nexport function mergeIntervals<T extends { start: number; end: number }>(\n intervals: T[],\n w = 5000,\n) {\n // test if there are at least 2 intervals\n if (intervals.length <= 1) {\n return intervals\n }\n\n const stack = [] as T[]\n let top = null\n\n // sort the intervals based on their start values\n intervals = intervals.sort((a, b) => a.start - b.start)\n\n // push the 1st interval into the stack\n stack.push(intervals[0]!)\n\n // start from the next interval and merge if needed\n for (let i = 1; i < intervals.length; i++) {\n // get the top element\n top = stack.at(-1)!\n\n // if the current interval doesn't overlap with the\n // stack top element, push it to the stack\n if (top.end + w < intervals[i]!.start - w) {\n stack.push(intervals[i]!)\n }\n // otherwise update the end value of the top element\n // if end of current interval is higher\n else if (top.end < intervals[i]!.end) {\n top.end = Math.max(top.end, intervals[i]!.end)\n stack.pop()\n stack.push(top)\n }\n }\n\n return stack\n}\n\ninterface BasicFeature {\n end: number\n start: number\n refName: string\n assemblyName?: string\n}\n\n// returns new array non-overlapping features\nexport function gatherOverlaps(regions: BasicFeature[], w = 5000) {\n const memo = {} as Record<string, BasicFeature[]>\n for (const x of regions) {\n if (!memo[x.refName]) {\n memo[x.refName] = []\n }\n memo[x.refName]!.push(x)\n }\n\n return Object.values(memo).flatMap(group =>\n mergeIntervals(\n group.sort((a, b) => a.start - b.start),\n w,\n ),\n )\n}\n\nexport function stripAlpha(str: string) {\n return colord(str).alpha(1).toHex()\n}\n\nexport function getStrokeProps(str: string) {\n const c = colord(str)\n return {\n strokeOpacity: c.alpha(),\n stroke: c.alpha(1).toHex(),\n }\n}\n\nexport function getFillProps(str: string) {\n const c = colord(str)\n return {\n fillOpacity: c.alpha(),\n fill: c.alpha(1).toHex(),\n }\n}\n\n// https://react.dev/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code\nexport function renderToStaticMarkup(\n node: React.ReactElement,\n createRootFn?: (elt: Element | DocumentFragment) => {\n render: (node: React.ReactElement) => unknown\n },\n) {\n const div = document.createElement('div')\n flushSync(() => {\n if (createRootFn) {\n createRootFn(div).render(node)\n } else {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n render(node, div)\n }\n })\n return div.innerHTML.replaceAll(/\\brgba\\((.+?),[^,]+?\\)/g, 'rgb($1)')\n}\n\nexport function isGzip(buf: Buffer) {\n return buf[0] === 31 && buf[1] === 139 && buf[2] === 8\n}\n\nexport {\n default as SimpleFeature,\n type Feature,\n type SimpleFeatureSerialized,\n isFeature,\n} from './simpleFeature'\n\nexport { blobToDataURL } from './blobToDataURL'\n","import { getParent, isRoot, IAnyStateTreeNode } from 'mobx-state-tree'\nimport { getSession, objectHash, getEnv } from './index'\nimport { PreFileLocation, FileLocation } from './types'\nimport { readConfObject, AnyConfigurationModel } from '../configuration'\n\n/* utility functions for use by track models and so forth */\n\nexport function getTrackAssemblyNames(\n track: IAnyStateTreeNode & { configuration: AnyConfigurationModel },\n) {\n return getConfAssemblyNames(track.configuration)\n}\n\nexport function getConfAssemblyNames(conf: AnyConfigurationModel) {\n const trackAssemblyNames = readConfObject(conf, 'assemblyNames') as\n | string[]\n | undefined\n if (!trackAssemblyNames) {\n // Check if it's an assembly sequence track\n const parent = getParent<any>(conf)\n if ('sequence' in parent) {\n return [readConfObject(parent, 'name') as string]\n } else {\n throw new Error('unknown assembly names')\n }\n }\n return trackAssemblyNames\n}\n\n/**\n * return the rpcSessionId of the highest parent node in the tree that has an\n * rpcSessionId */\n\nexport function getRpcSessionId(thisNode: IAnyStateTreeNode) {\n interface NodeWithRpcSessionId extends IAnyStateTreeNode {\n rpcSessionId: string\n }\n let highestRpcSessionId: string | undefined\n\n for (let node = thisNode; !isRoot(node); node = getParent<any>(node)) {\n if ('rpcSessionId' in node) {\n highestRpcSessionId = (node as NodeWithRpcSessionId).rpcSessionId\n }\n }\n if (!highestRpcSessionId) {\n throw new Error(\n 'getRpcSessionId failed, no parent node in the state tree has an `rpcSessionId` attribute',\n )\n }\n return highestRpcSessionId\n}\n\n/**\n * given an MST node, get the renderprops of the first parent container that\n * has renderProps\n * @param node -\n * @returns renderprops, or empty object if none found\n */\nexport function getParentRenderProps(node: IAnyStateTreeNode) {\n for (\n let currentNode = getParent<any>(node);\n !isRoot(currentNode);\n currentNode = getParent<any>(currentNode)\n ) {\n if ('renderProps' in currentNode) {\n return currentNode.renderProps()\n }\n }\n\n return {}\n}\n\nexport const UNKNOWN = 'UNKNOWN'\nexport const UNSUPPORTED = 'UNSUPPORTED'\n\nlet blobMap: Record<string, File> = {}\n\n// get a specific blob\nexport function getBlob(id: string) {\n return blobMap[id]\n}\n\n// used to export entire context to webworker\nexport function getBlobMap() {\n return blobMap\n}\n\n// used in new contexts like webworkers\nexport function setBlobMap(map: Record<string, File>) {\n blobMap = map\n}\n\nlet counter = 0\n\n// blob files are stored in a global map. the blobId is based on a combination\n// of timestamp plus counter to be unique across sessions and fast repeated\n// calls\nexport function storeBlobLocation(location: PreFileLocation) {\n if ('blob' in location) {\n const blobId = `b${+Date.now()}-${counter++}`\n blobMap[blobId] = location.blob\n return { name: location.blob.name, blobId, locationType: 'BlobLocation' }\n }\n return location\n}\n\n/**\n * creates a new location from the provided location including the appropriate suffix and location type\n * @param location - the FileLocation\n * @param suffix - the file suffix (e.g. .bam)\n * @returns the constructed location object from the provided parameters\n */\nexport function makeIndex(location: FileLocation, suffix: string) {\n if ('uri' in location) {\n return { uri: location.uri + suffix, locationType: 'UriLocation' }\n }\n\n if ('localPath' in location) {\n return {\n localPath: location.localPath + suffix,\n locationType: 'LocalPathLocation',\n }\n }\n\n return location\n}\n\n/**\n * constructs a potential index file (with suffix) from the provided file name\n * @param name - the name of the index file\n * @param typeA - one option of a potential two file suffix (e.g. CSI, BAI)\n * @param typeB - the second option of a potential two file suffix (e.g. CSI, BAI)\n * @returns a likely name of the index file for a given filename\n */\nexport function makeIndexType(\n name: string | undefined,\n typeA: string,\n typeB: string,\n) {\n return name?.toUpperCase().endsWith(typeA) ? typeA : typeB\n}\n\nexport interface AdapterConfig {\n type: string\n [key: string]: unknown\n}\n\nexport type AdapterGuesser = (\n file: FileLocation,\n index?: FileLocation,\n adapterHint?: string,\n) => AdapterConfig | undefined\n\nexport type TrackTypeGuesser = (adapterName: string) => string | undefined\n\nexport function getFileName(track: FileLocation) {\n const uri = 'uri' in track ? track.uri : undefined\n const localPath = 'localPath' in track ? track.localPath : undefined\n const blob = 'blobId' in track ? track : undefined\n return (\n blob?.name ||\n uri?.slice(uri.lastIndexOf('/') + 1) ||\n localPath?.slice(localPath.replace(/\\\\/g, '/').lastIndexOf('/') + 1) ||\n ''\n )\n}\n\nexport function guessAdapter(\n file: FileLocation,\n index: FileLocation | undefined,\n adapterHint?: string,\n model?: IAnyStateTreeNode,\n) {\n if (model) {\n const { pluginManager } = getEnv(model)\n const adapterGuesser = pluginManager.evaluateExtensionPoint(\n 'Core-guessAdapterForLocation',\n (\n _file: FileLocation,\n _index?: FileLocation,\n _adapterHint?: string,\n ): AdapterConfig | undefined => {\n return undefined\n },\n ) as AdapterGuesser\n\n const adapter = adapterGuesser(file, index, adapterHint)\n\n if (adapter) {\n return adapter\n }\n }\n\n return {\n type: UNKNOWN,\n }\n}\n\nexport function guessTrackType(\n adapterType: string,\n model?: IAnyStateTreeNode,\n): string {\n if (model) {\n const session = getSession(model)\n\n const trackTypeGuesser = getEnv(\n session,\n ).pluginManager.evaluateExtensionPoint(\n 'Core-guessTrackTypeForLocation',\n (_adapterName: string): AdapterConfig | undefined => {\n return undefined\n },\n ) as TrackTypeGuesser\n\n const trackType = trackTypeGuesser(adapterType)\n\n if (trackType) {\n return trackType\n }\n }\n return 'FeatureTrack'\n}\n\nexport function generateUnsupportedTrackConf(\n trackName: string,\n trackUrl: string,\n categories: string[] | undefined,\n) {\n const conf = {\n type: 'FeatureTrack',\n name: `${trackName} (Unsupported)`,\n description: `Support not yet implemented for \"${trackUrl}\"`,\n category: categories,\n trackId: '',\n }\n conf.trackId = objectHash(conf)\n return conf\n}\n\nexport function generateUnknownTrackConf(\n trackName: string,\n trackUrl: string,\n categories: string[] | undefined,\n) {\n const conf = {\n type: 'FeatureTrack',\n name: `${trackName} (Unknown)`,\n description: `Could not determine track type for \"${trackUrl}\"`,\n category: categories,\n trackId: '',\n }\n conf.trackId = objectHash(conf)\n return conf\n}\n\nexport function getTrackName(\n conf: AnyConfigurationModel,\n session: { assemblies: AnyConfigurationModel[] },\n) {\n const trackName = readConfObject(conf, 'name') as string\n if (!trackName && readConfObject(conf, 'type') === 'ReferenceSequenceTrack') {\n const asm = session.assemblies.find(a => a.sequence === conf)\n return asm\n ? `Reference sequence (${\n readConfObject(asm, 'displayName') || readConfObject(asm, 'name')\n })`\n : 'Reference sequence'\n }\n return trackName\n}\n","import { types } from 'mobx-state-tree'\nimport { nanoid } from '../nanoid'\n\nexport const ElementId = types.optional(types.identifier, () => nanoid())\n\nexport const NoAssemblyRegion = types\n .model('NoAssemblyRegion', {\n refName: types.string,\n start: types.number,\n end: types.number,\n reversed: types.optional(types.boolean, false),\n })\n .actions(self => ({\n setRefName(newRefName: string): void {\n self.refName = newRefName\n },\n }))\n\nexport const Region = types.compose(\n 'Region',\n NoAssemblyRegion,\n types.model({\n assemblyName: types.string,\n }),\n)\n\nexport const LocalPathLocation = types.model('LocalPathLocation', {\n locationType: types.literal('LocalPathLocation'),\n localPath: types.string,\n})\n\n// like how blobId is used to get a blob map\nexport const BlobLocation = types.model('BlobLocation', {\n locationType: types.literal('BlobLocation'),\n name: types.string,\n blobId: types.string,\n})\n\nexport const UriLocationRaw = types.model('UriLocation', {\n locationType: types.literal('UriLocation'),\n uri: types.string,\n baseUri: types.maybe(types.string),\n\n internetAccountId: types.maybe(types.string),\n\n // auths information (such as tokens) needed for using this resource.\n // if provided, these must be completely sufficient for using it\n internetAccountPreAuthorization: types.maybe(\n types.model('InternetAccountPreAuthorization', {\n internetAccountType: types.string,\n authInfo: types.frozen(),\n }),\n ),\n})\n\nexport const UriLocation = types.snapshotProcessor(UriLocationRaw, {\n postProcessor: snap => {\n // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit\n const { baseUri, ...rest } = snap as Omit<typeof snap, symbol>\n if (!baseUri) {\n return rest\n }\n return snap\n },\n})\n\nexport const FileLocation = types.snapshotProcessor(\n types.union(LocalPathLocation, UriLocation, BlobLocation),\n {\n // @ts-expect-error\n preProcessor(snap) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!snap) {\n return undefined\n }\n\n // @ts-expect-error\n // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit\n const { locationType, ...rest } = snap as Omit<typeof snap, symbol>\n if (!locationType) {\n // @ts-expect-error\n const { uri, localPath, blob } = rest\n let locationType = ''\n if (uri !== undefined) {\n locationType = 'UriLocation'\n } else if (localPath !== undefined) {\n locationType = 'LocalPathLocation'\n } else if (blob !== undefined) {\n locationType = 'BlobLocation'\n }\n\n return { ...rest, locationType }\n }\n return snap\n },\n },\n)\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport {\n IAnyStateTreeNode,\n Instance,\n getParent,\n isStateTreeNode,\n types,\n} from 'mobx-state-tree'\nimport { AnyConfigurationSchemaType } from '@jbrowse/core/configuration'\nimport { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'\n\n// locals\nimport type { BaseRootModelType } from '../RootModel/BaseRootModel'\nimport { ElementId } from '@jbrowse/core/util/types/mst'\n\n/**\n * #stateModel BaseSessionModel\n *\n * base session shared by all JBrowse products. Be careful what you include\n * here, everything will use it.\n */\nexport function BaseSessionModel<\n ROOT_MODEL_TYPE extends BaseRootModelType,\n JB_CONFIG_SCHEMA extends AnyConfigurationSchemaType,\n>(_pluginManager: PluginManager) {\n return types\n .model({\n /**\n * #property\n */\n id: ElementId,\n /**\n * #property\n */\n name: types.string,\n /**\n * #property\n */\n margin: 0,\n })\n .volatile(() => ({\n /**\n * #volatile\n * this is the globally \"selected\" object. can be anything. code that\n * wants to deal with this should examine it to see what kind of thing it\n * is.\n */\n selection: undefined as unknown,\n /**\n * #volatile\n * this is the globally \"hovered\" object. can be anything. code that\n * wants to deal with this should examine it to see what kind of thing it\n * is.\n */\n hovered: undefined as unknown,\n }))\n .views(self => ({\n /**\n * #getter\n */\n get root() {\n return getParent<ROOT_MODEL_TYPE>(self)\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get jbrowse() {\n return self.root.jbrowse\n },\n /**\n * #getter\n */\n get rpcManager() {\n return self.root.rpcManager\n },\n /**\n * #getter\n */\n get configuration(): Instance<JB_CONFIG_SCHEMA> {\n return this.jbrowse.configuration\n },\n /**\n * #getter\n */\n get adminMode() {\n return self.root.adminMode\n },\n\n /**\n * #getter\n */\n get textSearchManager() {\n return self.root.textSearchManager\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get assemblies(): Instance<BaseAssemblyConfigSchema>[] {\n return self.jbrowse.assemblies\n },\n }))\n .actions(self => ({\n /**\n * #action\n * set the global selection, i.e. the globally-selected object. can be a\n * feature, a view, just about anything\n */\n setSelection(thing: unknown) {\n self.selection = thing\n },\n\n /**\n * #action\n * clears the global selection\n */\n clearSelection() {\n self.selection = undefined\n },\n /**\n * #action\n */\n setHovered(thing: unknown) {\n self.hovered = thing\n },\n }))\n}\n\n/** Session mixin MST type for the most basic session */\nexport type BaseSessionType = ReturnType<typeof BaseSessionModel>\n\n/** Instance of the most basic possible session */\nexport type BaseSession = Instance<BaseSessionType>\n\n/** Type guard for BaseSession */\nexport function isBaseSession(thing: IAnyStateTreeNode): thing is BaseSession {\n return 'id' in thing && 'name' in thing && 'root' in thing\n}\n\n/** Type guard for whether a thing is JBrowse session */\nexport function isSession(thing: unknown): thing is BaseSession {\n return isStateTreeNode(thing) && isBaseSession(thing)\n}\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport {\n AnyConfigurationModel,\n readConfObject,\n} from '@jbrowse/core/configuration'\nimport { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'\nimport { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig'\nimport { BaseConnectionModel } from '@jbrowse/core/pluggableElementTypes/models/BaseConnectionModelFactory'\n\n// locals\nimport type { BaseRootModelType } from '../RootModel/BaseRootModel'\nimport type { SessionWithReferenceManagementType } from './ReferenceManagement'\nimport { isBaseSession } from './BaseSession'\n\n/**\n * #stateModel ConnectionManagementSessionMixin\n */\nexport function ConnectionManagementSessionMixin(pluginManager: PluginManager) {\n return types\n .model({\n /**\n * #property\n */\n connectionInstances: types.array(\n pluginManager.pluggableMstType(\n 'connection',\n 'stateModel',\n ) as BaseConnectionModel,\n ),\n })\n .views(self => ({\n /**\n * #getter\n */\n get connections(): BaseConnectionConfigModel[] {\n const { jbrowse } = self as typeof self & Instance<BaseRootModelType>\n return jbrowse.connections\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n makeConnection(\n configuration: AnyConfigurationModel,\n initialSnapshot = {},\n ) {\n const type = configuration.type as string\n if (!type) {\n throw new Error('track configuration has no `type` listed')\n }\n const name = readConfObject(configuration, 'name')\n const connectionType = pluginManager.getConnectionType(type)\n if (!connectionType) {\n throw new Error(`unknown connection type ${type}`)\n }\n const length = self.connectionInstances.push({\n ...initialSnapshot,\n name,\n // @ts-expect-error unsure why ts doesn't like `type` here, but is\n // needed\n type,\n configuration,\n })\n return self.connectionInstances[length - 1]\n },\n\n /**\n * #action\n */\n prepareToBreakConnection(configuration: AnyConfigurationModel) {\n const root = self as typeof self &\n Instance<SessionWithReferenceManagementType>\n const callbacksToDeref: (() => void)[] = []\n const derefTypeCount: Record<string, number> = {}\n const name = readConfObject(configuration, 'name')\n const connection = self.connectionInstances.find(c => c.name === name)\n if (!connection) {\n return undefined\n }\n for (const track of connection.tracks) {\n const ref = root.getReferring(track)\n root.removeReferring(ref, track, callbacksToDeref, derefTypeCount)\n }\n return [\n () => {\n callbacksToDeref.forEach(cb => {\n cb()\n })\n this.breakConnection(configuration)\n },\n derefTypeCount,\n ]\n },\n\n /**\n * #action\n */\n breakConnection(configuration: AnyConfigurationModel) {\n const name = readConfObject(configuration, 'name')\n const connection = self.connectionInstances.find(c => c.name === name)\n if (!connection) {\n throw new Error(`no connection found with name ${name}`)\n }\n self.connectionInstances.remove(connection)\n },\n\n /**\n * #action\n */\n deleteConnection(configuration: AnyConfigurationModel) {\n const { jbrowse } = self as typeof self & Instance<BaseRootModelType>\n return jbrowse.deleteConnectionConf(configuration)\n },\n\n /**\n * #action\n */\n addConnectionConf(connectionConf: AnyConfigurationModel) {\n const { jbrowse } = self as typeof self & Instance<BaseRootModelType>\n return jbrowse.addConnectionConf(connectionConf)\n },\n\n /**\n * #action\n */\n clearConnections() {\n self.connectionInstances.clear()\n },\n }))\n}\n\n/** Session mixin MST type for a session that has connections */\nexport type SessionWithConnectionsType = ReturnType<\n typeof ConnectionManagementSessionMixin\n>\n\n/** Instance of a session that has connections: `connectionInstances`,\n * `makeConnection()`, etc. */\nexport type SessionWithConnections = Instance<SessionWithConnectionsType>\n\n/** Type guard for SessionWithConnections */\nexport function isSessionWithConnections(\n session: IAnyStateTreeNode,\n): session is SessionWithConnections {\n return isBaseSession(session) && 'connectionInstances' in session\n}\n","import { lazy } from 'react'\nimport Plugin from '@jbrowse/core/Plugin'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport UCSCTrackHubConnectionF from './ucsc-trackhub'\nimport AddTrackWidgetF from './AddTrackWidget'\n\nimport AddConnectionWidgetF from './AddConnectionWidget'\nimport PluginStoreWidgetF from './PluginStoreWidget'\nimport HierarchicalTrackSelectorWidgetF from './HierarchicalTrackSelectorWidget'\n\nconst AssemblyManager = lazy(() => import('./AssemblyManager'))\n\nexport default class DataManagementPlugin extends Plugin {\n name = 'DataManagementPlugin'\n\n exports = {\n AssemblyManager,\n }\n\n install(pluginManager: PluginManager) {\n UCSCTrackHubConnectionF(pluginManager)\n AddTrackWidgetF(pluginManager)\n HierarchicalTrackSelectorWidgetF(pluginManager)\n AddConnectionWidgetF(pluginManager)\n PluginStoreWidgetF(pluginManager)\n }\n\n configure(_pluginManager: PluginManager) {}\n}\n\nexport { AssemblyManager }\n\nexport { type AddTrackModel } from './AddTrackWidget/model'\nexport { type HierarchicalTrackSelectorModel } from './HierarchicalTrackSelectorWidget'\n","import React from 'react'\nimport {\n Alert,\n Button,\n IconButton,\n Snackbar as MUISnackbar,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\n\n// icons\nimport CloseIcon from '@mui/icons-material/Close'\n\n// locals\nimport { AbstractSessionModel } from '../util'\nimport { SnackbarMessage } from './SnackbarModel'\n\ninterface SnackbarSession extends AbstractSessionModel {\n snackbarMessages: SnackbarMessage[]\n popSnackbarMessage: () => void\n}\n\nconst Snackbar = observer(function ({ session }: { session: SnackbarSession }) {\n const { snackbarMessages } = session\n const latestMessage = snackbarMessages.at(-1)\n\n const handleClose = (_event: unknown, reason?: string) => {\n if (reason !== 'clickaway') {\n session.popSnackbarMessage()\n }\n }\n return latestMessage ? (\n <MUISnackbar\n open\n onClose={handleClose}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert\n onClose={handleClose}\n action={\n latestMessage.action ? (\n <>\n <Button\n color=\"inherit\"\n onClick={e => {\n latestMessage.action?.onClick()\n handleClose(e)\n }}\n >\n {latestMessage.action.name}\n </Button>\n <IconButton color=\"inherit\" onClick={handleClose}>\n <CloseIcon />\n </IconButton>\n </>\n ) : null\n }\n severity={latestMessage.level || 'warning'}\n >\n {latestMessage.message}\n </Alert>\n </MUISnackbar>\n ) : null\n})\n\nexport default Snackbar\n","import React, { useRef, useState } from 'react'\nimport { Button, alpha } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport ArrowDropDown from '@mui/icons-material/ArrowDropDown'\n\nimport Menu, { MenuItem } from './Menu'\n\nconst useStyles = makeStyles()(theme => ({\n buttonRoot: {\n '&:hover': {\n backgroundColor: alpha(\n theme.palette.primary.contrastText,\n theme.palette.action.hoverOpacity,\n ),\n '@media (hover: none)': {\n backgroundColor: 'transparent',\n },\n },\n },\n}))\n\nconst DropDownMenu = observer(function ({\n menuTitle,\n session,\n menuItems,\n}: {\n menuTitle: string\n\n session: any\n menuItems: MenuItem[]\n}) {\n const [open, setOpen] = useState(false)\n const anchorEl = useRef(null)\n const { classes } = useStyles()\n\n function handleClose() {\n setOpen(false)\n }\n\n return (\n <>\n <Button\n ref={anchorEl}\n onClick={() => {\n setOpen(!open)\n }}\n color=\"inherit\"\n data-testid=\"dropDownMenuButton\"\n classes={{ root: classes.buttonRoot }}\n >\n {menuTitle}\n <ArrowDropDown />\n </Button>\n <Menu\n anchorEl={anchorEl.current}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n onMenuItemClick={(_event, callback) => {\n callback(session)\n handleClose()\n }}\n open={open}\n onClose={handleClose}\n menuItems={menuItems}\n />\n </>\n )\n})\n\nexport default DropDownMenu\n","import React from 'react'\nimport { observer } from 'mobx-react'\n\n// locals\nimport { readConfObject, AnyConfigurationModel } from '../configuration'\n\n// ui elements\nimport { LogoFull } from './Logo'\n\nconst Logo = observer(function ({\n session,\n}: {\n session: { configuration: AnyConfigurationModel }\n}) {\n const { configuration } = session\n const logoPath = readConfObject(configuration, 'logoPath')\n return logoPath?.uri ? (\n <img src={logoPath.uri} alt=\"Custom logo\" />\n ) : (\n <LogoFull variant=\"white\" />\n )\n})\n\nexport default Logo\n","import React from 'react'\nimport { Toolbar, Tooltip } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { SessionWithDrawerWidgets } from '@jbrowse/core/util'\nimport DropDownMenu from '@jbrowse/core/ui/DropDownMenu'\nimport EditableTypography from '@jbrowse/core/ui/EditableTypography'\nimport AppLogo from '@jbrowse/core/ui/AppLogo'\nimport { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'\nimport { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'\n\nconst useStyles = makeStyles()(theme => ({\n grow: {\n flexGrow: 1,\n },\n inputBase: {\n color: theme.palette.primary.contrastText,\n },\n inputRoot: {\n '&:hover': {\n backgroundColor: theme.palette.primary.light,\n },\n },\n inputFocused: {\n borderColor: theme.palette.secondary.main,\n backgroundColor: theme.palette.primary.light,\n },\n}))\n\ntype AppSession = SessionWithDrawerWidgets & {\n menus: {\n label: string\n menuItems: JBMenuItem[]\n }[]\n savedSessionNames?: string[]\n snackbarMessages: SnackbarMessage[]\n\n renameCurrentSession: (arg: string) => void\n popSnackbarMessage: () => unknown\n}\n\nconst AppToolbar = observer(function ({\n session,\n HeaderButtons = <div />,\n}: {\n HeaderButtons?: React.ReactElement\n session: AppSession\n}) {\n const { classes } = useStyles()\n const { savedSessionNames, name, menus } = session\n\n return (\n <Toolbar>\n {menus.map(menu => (\n <DropDownMenu\n key={menu.label}\n menuTitle={menu.label}\n menuItems={menu.menuItems}\n session={session}\n />\n ))}\n <div className={classes.grow} />\n <Tooltip title=\"Rename Session\" arrow>\n <EditableTypography\n value={name}\n setValue={newName => {\n if (savedSessionNames?.includes(newName)) {\n session.notify(\n `Cannot rename session to \"${newName}\", a saved session with that name already exists`,\n 'warning',\n )\n } else {\n session.renameCurrentSession(newName)\n }\n }}\n variant=\"body1\"\n classes={{\n inputBase: classes.inputBase,\n inputRoot: classes.inputRoot,\n inputFocused: classes.inputFocused,\n }}\n />\n </Tooltip>\n {HeaderButtons}\n <div className={classes.grow} />\n <div style={{ width: 150, maxHeight: 48 }}>\n <AppLogo session={session} />\n </div>\n </Toolbar>\n )\n})\n\nexport default AppToolbar\n","import React, { Suspense } from 'react'\nimport { observer } from 'mobx-react'\n\n// locals\nimport { SessionWithDrawerWidgets } from '@jbrowse/core/util'\n\nconst DialogQueue = observer(function ({\n session,\n}: {\n session: SessionWithDrawerWidgets\n}) {\n const { DialogComponent, DialogProps } = session\n return DialogComponent ? (\n <Suspense fallback={null}>\n <DialogComponent {...DialogProps} />\n </Suspense>\n ) : null\n})\n\nexport default DialogQueue\n","import React from 'react'\nimport { Fab, Tooltip } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { SessionWithDrawerWidgets } from '@jbrowse/core/util'\n\n// icons\nimport LaunchIcon from '@mui/icons-material/Launch'\n\nconst useStyles = makeStyles()(theme => ({\n left: {\n zIndex: 10000,\n position: 'fixed',\n bottom: theme.spacing(2),\n left: theme.spacing(2),\n },\n right: {\n zIndex: 10000,\n position: 'fixed',\n bottom: theme.spacing(2),\n right: theme.spacing(2),\n },\n}))\n\nconst AppFab = observer(function ({\n session,\n}: {\n session: SessionWithDrawerWidgets\n}) {\n const { minimized, activeWidgets, drawerPosition } = session\n const { classes } = useStyles()\n\n return activeWidgets.size > 0 && minimized ? (\n <Tooltip title=\"Open drawer widget\">\n <Fab\n className={drawerPosition === 'right' ? classes.right : classes.left}\n color=\"primary\"\n data-testid=\"drawer-maximize\"\n onClick={() => {\n session.showWidgetDrawer()\n }}\n >\n <LaunchIcon />\n </Fab>\n </Tooltip>\n ) : null\n})\n\nexport default AppFab\n","import React, { useState } from 'react'\nimport {\n Button,\n FormControl,\n MenuItem,\n Paper,\n Select,\n Typography,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\n// locals\nimport { getEnv, SessionWithDrawerWidgets } from '@jbrowse/core/util'\n\n// ui elements\nimport { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'\nimport { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'\n\ntype AppSession = SessionWithDrawerWidgets & {\n savedSessionNames: string[]\n menus: { label: string; menuItems: JBMenuItem[] }[]\n renameCurrentSession: (arg: string) => void\n snackbarMessages: SnackbarMessage[]\n popSnackbarMessage: () => unknown\n}\n\nconst useStyles = makeStyles()(theme => ({\n selectPaper: {\n padding: theme.spacing(4),\n },\n m2: {\n margin: 2,\n },\n}))\n\nconst ViewLauncher = observer(({ session }: { session: AppSession }) => {\n const { classes } = useStyles()\n const { pluginManager } = getEnv(session)\n const viewTypes = pluginManager.getElementTypeRecord('view').all()\n const [value, setValue] = useState(viewTypes[0]?.name || '')\n return (\n <Paper className={classes.selectPaper}>\n <Typography>Select a view to launch</Typography>\n <FormControl className={classes.m2}>\n <Select\n value={value}\n onChange={event => {\n setValue(event.target.value)\n }}\n >\n {viewTypes.map(({ displayName, name }) => (\n <MenuItem key={name} value={name}>\n {displayName}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <FormControl className={classes.m2}>\n <Button\n onClick={() => session.addView(value, {})}\n variant=\"contained\"\n color=\"primary\"\n >\n Launch view\n </Button>\n </FormControl>\n </Paper>\n )\n})\n\nexport default ViewLauncher\n","import React from 'react'\nimport {\n SvgIconProps,\n IconButton,\n IconButtonProps as IconButtonPropsType,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { AbstractSessionModel, getSession } from '@jbrowse/core/util'\nimport { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport {\n bindTrigger,\n bindPopover,\n usePopupState,\n} from 'material-ui-popup-state/hooks'\nimport CascadingMenu from '@jbrowse/core/ui/CascadingMenu'\n\n// icons\nimport MenuIcon from '@mui/icons-material/Menu'\nimport KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown'\nimport KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp'\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'\n\nconst ViewMenu = observer(function ({\n model,\n IconButtonProps,\n IconProps,\n}: {\n model: IBaseViewModel\n IconButtonProps?: IconButtonPropsType\n IconProps: SvgIconProps\n}) {\n const session = getSession(model) as AbstractSessionModel & {\n moveViewDown: (arg: string) => void\n moveViewUp: (arg: string) => void\n moveViewToBottom: (arg: string) => void\n moveViewToTop: (arg: string) => void\n }\n\n const popupState = usePopupState({\n popupId: 'viewMenu',\n variant: 'popover',\n })\n\n // note: This does not use CascadingMenuButton on purpose, because there was\n // a confusing bug related to it! see\n // https://github.com/GMOD/jbrowse-components/issues/4115\n //\n // Make sure to test the Breakpoint split view menu checkboxes if you intend\n // to change this\n return (\n <>\n <IconButton\n {...IconButtonProps}\n {...bindTrigger(popupState)}\n data-testid=\"view_menu_icon\"\n >\n <MenuIcon {...IconProps} fontSize=\"small\" />\n </IconButton>\n <CascadingMenu\n {...bindPopover(popupState)}\n onMenuItemClick={(_event: unknown, callback: () => void) => {\n callback()\n }}\n menuItems={[\n ...(session.views.length > 1\n ? [\n {\n label: 'View order',\n type: 'subMenu' as const,\n subMenu: [\n {\n label: 'Move view to top',\n icon: KeyboardDoubleArrowUpIcon,\n onClick: () => {\n session.moveViewToTop(model.id)\n },\n },\n {\n label: 'Move view up',\n icon: KeyboardArrowUpIcon,\n onClick: () => {\n session.moveViewUp(model.id)\n },\n },\n {\n label: 'Move view down',\n icon: KeyboardArrowDownIcon,\n onClick: () => {\n session.moveViewDown(model.id)\n },\n },\n {\n label: 'Move view to bottom',\n icon: KeyboardDoubleArrowDownIcon,\n onClick: () => {\n session.moveViewToBottom(model.id)\n },\n },\n ],\n },\n ]\n : []),\n ...model.menuItems(),\n ]}\n popupState={popupState}\n />\n </>\n )\n})\nexport default ViewMenu\n","import React from 'react'\nimport { Tooltip } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\n\n// locals\nimport EditableTypography from '@jbrowse/core/ui/EditableTypography'\nimport { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes'\n\nconst useStyles = makeStyles()(theme => ({\n input: {\n paddingBottom: 0,\n paddingTop: 2,\n },\n inputBase: {\n color: theme.palette.secondary.contrastText,\n },\n inputRoot: {\n '&:hover': {\n backgroundColor: theme.palette.secondary.light,\n },\n },\n inputFocused: {\n borderColor: theme.palette.primary.main,\n backgroundColor: theme.palette.secondary.light,\n },\n}))\nconst ViewContainerTitle = observer(function ({\n view,\n}: {\n view: IBaseViewModel\n}) {\n const { classes } = useStyles()\n return (\n <Tooltip title=\"Rename view\" arrow>\n <EditableTypography\n value={\n view.displayName ||\n // @ts-expect-error\n `${view.assemblyNames?.join(',') || 'Untitled view'}${\n view.minimized ? ' (minimized)' : ''\n }`\n }\n setValue={val => {\n view.setDisplayName(val)\n }}\n variant=\"body2\"\n classes={{\n input: classes.input,\n inputBase: classes.inputBase,\n inputRoot: classes.inputRoot,\n inputFocused: classes.inputFocused,\n }}\n />\n </Tooltip>\n )\n})\n\nexport default ViewContainerTitle\n","import React, { useEffect, useRef } from 'react'\nimport { IconButton } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\n\n// icons\nimport CloseIcon from '@mui/icons-material/Close'\nimport MinimizeIcon from '@mui/icons-material/Minimize'\nimport AddIcon from '@mui/icons-material/Add'\nimport KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'\n\n// locals\nimport ViewMenu from './ViewMenu'\nimport ViewContainerTitle from './ViewContainerTitle'\nimport { getSession } from '@jbrowse/core/util'\n\nconst useStyles = makeStyles()(theme => ({\n icon: {\n color: theme.palette.secondary.contrastText,\n },\n grow: {\n flexGrow: 1,\n },\n viewHeader: {\n display: 'flex',\n },\n viewTitle: {\n display: 'flex',\n alignItems: 'center',\n },\n}))\n\nconst ViewButtons = observer(function ({\n view,\n onClose,\n onMinimize,\n}: {\n view: IBaseViewModel\n onClose: () => void\n onMinimize: () => void\n}) {\n const { classes } = useStyles()\n return (\n <>\n <IconButton data-testid=\"minimize_view\" onClick={onMinimize}>\n {view.minimized ? (\n <AddIcon className={classes.icon} fontSize=\"small\" />\n ) : (\n <MinimizeIcon className={classes.icon} fontSize=\"small\" />\n )}\n </IconButton>\n <IconButton data-testid=\"close_view\" onClick={onClose}>\n <CloseIcon className={classes.icon} fontSize=\"small\" />\n </IconButton>\n </>\n )\n})\n\nconst ViewHeader = observer(function ({\n view,\n onClose,\n onMinimize,\n}: {\n view: IBaseViewModel\n onClose: () => void\n onMinimize: () => void\n}) {\n const { classes } = useStyles()\n const scrollRef = useRef<HTMLDivElement>(null)\n const session = getSession(view)\n\n // scroll the view into view when first mounted. note: this effect will run\n // only once, because of the empty array second param\n useEffect(() => {\n if (typeof jest === 'undefined') {\n scrollRef.current?.scrollIntoView({ block: 'center' })\n }\n }, [])\n return (\n <div ref={scrollRef} className={classes.viewHeader}>\n <ViewMenu model={view} IconProps={{ className: classes.icon }} />\n <div className={classes.grow} />\n <div className={classes.viewTitle}>\n {session.focusedViewId === view.id ? (\n <KeyboardArrowRightIcon className={classes.icon} fontSize=\"small\" />\n ) : null}\n <ViewContainerTitle view={view} />\n </div>\n <div className={classes.grow} />\n <ViewButtons onClose={onClose} onMinimize={onMinimize} view={view} />\n </div>\n )\n})\n\nexport default ViewHeader\n","import React, { useEffect } from 'react'\nimport { Paper, useTheme } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { getSession, useWidthSetter } from '@jbrowse/core/util'\nimport { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util'\n\n// locals\nimport ViewHeader from './ViewHeader'\n\nconst useStyles = makeStyles()(theme => ({\n viewContainer: {\n overflow: 'hidden',\n margin: theme.spacing(0.5),\n padding: `0 ${theme.spacing(1)} ${theme.spacing(1)}`,\n },\n focusedView: {\n background: theme.palette.secondary.main,\n },\n unfocusedView: {\n background: theme.palette.secondary.dark,\n },\n}))\n\nconst ViewContainer = observer(function ({\n view,\n onClose,\n onMinimize,\n children,\n}: {\n view: IBaseViewModel\n onClose: () => void\n onMinimize: () => void\n children: React.ReactNode\n}) {\n const theme = useTheme()\n const ref = useWidthSetter(view, theme.spacing(1))\n const { classes, cx } = useStyles()\n const session = getSession(view) as SessionWithFocusedViewAndDrawerWidgets\n\n useEffect(() => {\n function handleSelectView(e: Event) {\n if (e.target instanceof Element && ref.current?.contains(e.target)) {\n session.setFocusedViewId(view.id)\n }\n }\n\n document.addEventListener('mousedown', handleSelectView)\n document.addEventListener('keydown', handleSelectView)\n return () => {\n document.removeEventListener('mousedown', handleSelectView)\n document.removeEventListener('keydown', handleSelectView)\n }\n }, [ref, session, view])\n\n return (\n <Paper\n ref={ref}\n elevation={12}\n className={cx(\n classes.viewContainer,\n session.focusedViewId === view.id\n ? classes.focusedView\n : classes.unfocusedView,\n )}\n >\n <ViewHeader view={view} onClose={onClose} onMinimize={onMinimize} />\n <Paper>{children}</Paper>\n </Paper>\n )\n})\n\nexport default ViewContainer\n","import React, { Suspense } from 'react'\nimport { ErrorBoundary } from 'react-error-boundary'\nimport { observer } from 'mobx-react'\n\n// locals\nimport {\n getEnv,\n AbstractViewModel,\n SessionWithDrawerWidgets,\n} from '@jbrowse/core/util'\nimport { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'\n\n// ui elements\nimport ErrorMessage from '@jbrowse/core/ui/ErrorMessage'\nimport LoadingEllipses from '@jbrowse/core/ui/LoadingEllipses'\nimport { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'\n\n// locals\nimport ViewContainer from './ViewContainer'\n\ntype AppSession = SessionWithDrawerWidgets & {\n savedSessionNames: string[]\n menus: { label: string; menuItems: JBMenuItem[] }[]\n snackbarMessages: SnackbarMessage[]\n renameCurrentSession: (arg: string) => void\n popSnackbarMessage: () => unknown\n}\n\nconst ViewPanel = observer(function ({\n view,\n session,\n}: {\n view: AbstractViewModel\n session: AppSession\n}) {\n const { pluginManager } = getEnv(session)\n const viewType = pluginManager.getViewType(view.type)\n if (!viewType) {\n throw new Error(`unknown view type ${view.type}`)\n }\n const { ReactComponent } = viewType\n return (\n <ViewContainer\n view={view}\n onClose={() => {\n session.removeView(view)\n }}\n onMinimize={() => {\n view.setMinimized(!view.minimized)\n }}\n >\n {!view.minimized ? (\n <ErrorBoundary\n FallbackComponent={({ error }) => <ErrorMessage error={error} />}\n >\n <Suspense fallback={<LoadingEllipses variant=\"h6\" />}>\n <ReactComponent model={view} session={session} />\n </Suspense>\n </ErrorBoundary>\n ) : (\n false\n )}\n </ViewContainer>\n )\n})\n\nexport default ViewPanel\n","import React from 'react'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util'\nimport { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'\nimport { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'\n\n// locals\nimport ViewLauncher from './ViewLauncher'\nimport ViewPanel from './ViewPanel'\n\nconst useStyles = makeStyles()({\n viewsContainer: {\n overflowY: 'auto',\n gridRow: 'components',\n },\n})\n\ninterface Props {\n HeaderButtons?: React.ReactElement\n session: SessionWithFocusedViewAndDrawerWidgets & {\n savedSessionNames: string[]\n menus: { label: string; menuItems: JBMenuItem[] }[]\n renameCurrentSession: (arg: string) => void\n snackbarMessages: SnackbarMessage[]\n popSnackbarMessage: () => unknown\n }\n}\n\nconst ViewsContainer = observer(function ViewsContainer(props: Props) {\n const { session } = props\n const { views } = session\n const { classes } = useStyles()\n return (\n <div className={classes.viewsContainer}>\n {views.length > 0 ? (\n views.map(view => (\n <ViewPanel key={`view-${view.id}`} view={view} session={session} />\n ))\n ) : (\n <ViewLauncher {...props} />\n )}\n\n {/* blank space at the bottom of screen allows scroll */}\n <div style={{ height: 300 }} />\n </div>\n )\n})\n\nexport default ViewsContainer\n","import React, { Suspense, lazy } from 'react'\nimport { AppBar } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { observer } from 'mobx-react'\nimport { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util'\nimport Snackbar from '@jbrowse/core/ui/Snackbar'\nimport { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'\nimport { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'\n\n// locals\nimport AppToolbar from './AppToolbar'\nimport DialogQueue from './DialogQueue'\nimport AppFab from './AppFab'\nimport ViewsContainer from './ViewsContainer'\n\nconst DrawerWidget = lazy(() => import('./DrawerWidget'))\n\nconst useStyles = makeStyles()(theme => ({\n root: {\n display: 'grid',\n height: '100vh',\n width: '100%',\n colorScheme: theme.palette.mode,\n },\n appContainer: {\n gridColumn: 'main',\n display: 'grid',\n gridTemplateRows: '[menubar] min-content [components] auto',\n height: '100vh',\n },\n\n appBar: {\n flexGrow: 1,\n gridRow: 'menubar',\n },\n}))\n\ninterface Props {\n HeaderButtons?: React.ReactElement\n session: SessionWithFocusedViewAndDrawerWidgets & {\n savedSessionNames: string[]\n menus: { label: string; menuItems: JBMenuItem[] }[]\n renameCurrentSession: (arg: string) => void\n snackbarMessages: SnackbarMessage[]\n popSnackbarMessage: () => unknown\n }\n}\n\nconst LazyDrawerWidget = observer(function (props: Props) {\n const { session } = props\n return (\n <Suspense fallback={null}>\n <DrawerWidget session={session} />\n </Suspense>\n )\n})\n\nconst App = observer(function (props: Props) {\n const { session } = props\n const { classes } = useStyles()\n const { minimized, visibleWidget, drawerWidth, drawerPosition } = session\n const drawerVisible = visibleWidget && !minimized\n const d = drawerVisible ? `[drawer] ${drawerWidth}px` : undefined\n const grid =\n drawerPosition === 'right' ? ['[main] 1fr', d] : [d, '[main] 1fr']\n\n return (\n <div\n className={classes.root}\n style={{ gridTemplateColumns: grid.filter(f => !!f).join(' ') }}\n >\n {drawerVisible && drawerPosition === 'left' ? (\n <LazyDrawerWidget session={session} />\n ) : null}\n <DialogQueue session={session} />\n <div className={classes.appContainer}>\n <AppBar className={classes.appBar} position=\"static\">\n <AppToolbar {...props} />\n </AppBar>\n <ViewsContainer {...props} />\n </div>\n <AppFab session={session} />\n\n {drawerVisible && drawerPosition === 'right' ? (\n <LazyDrawerWidget session={session} />\n ) : null}\n\n <Snackbar session={session} />\n </div>\n )\n})\n\nexport { App }\n","// adapted from https://github.com/mobxjs/mobx-state-tree/blob/master/packages/mst-middlewares/src/time-traveller.ts\nimport {\n types,\n resolvePath,\n getEnv,\n onSnapshot,\n getSnapshot,\n applySnapshot,\n IDisposer,\n IAnyStateTreeNode,\n} from 'mobx-state-tree'\n\nconst MAX_HISTORY_LENGTH = 20\n\nfunction debounce(func: (...args: unknown[]) => void, timeout = 300) {\n let timer: ReturnType<typeof setTimeout>\n return (...args: unknown[]) => {\n clearTimeout(timer)\n timer = setTimeout(() => {\n func(...args)\n }, timeout)\n }\n}\n\nconst TimeTraveller = types\n .model('TimeTraveller', {\n undoIdx: -1,\n targetPath: '',\n })\n .volatile(() => ({\n history: [] as unknown[],\n notTrackingUndo: false,\n }))\n .views(self => ({\n get canUndo() {\n return self.undoIdx > 0 && !self.notTrackingUndo\n },\n get canRedo() {\n return self.undoIdx < self.history.length - 1 && !self.notTrackingUndo\n },\n }))\n .actions(self => {\n let targetStore: IAnyStateTreeNode | undefined\n let snapshotDisposer: IDisposer\n let skipNextUndoState = false\n\n return {\n // allows user code to (temporarily) stop tracking undo states\n stopTrackingUndo() {\n self.notTrackingUndo = true\n },\n // allows user code to resume tracking undo states\n resumeTrackingUndo() {\n self.notTrackingUndo = false\n },\n addUndoState(todos: unknown) {\n if (self.notTrackingUndo) {\n return\n }\n if (skipNextUndoState) {\n // skip recording if this state was caused by undo / redo\n skipNextUndoState = false\n return\n }\n self.history.splice(self.undoIdx + 1)\n self.history.push(todos)\n if (self.history.length > MAX_HISTORY_LENGTH) {\n self.history.shift()\n }\n self.undoIdx = self.history.length - 1\n },\n\n beforeDestroy() {\n snapshotDisposer()\n },\n initialize() {\n targetStore = self.targetPath\n ? resolvePath(self, self.targetPath)\n : getEnv(self).targetStore\n\n if (!targetStore) {\n throw new Error(\n 'Failed to find target store for TimeTraveller. Please provide `targetPath` property, or a `targetStore` in the environment',\n )\n }\n\n snapshotDisposer = onSnapshot(\n targetStore,\n debounce((snapshot: unknown) => {\n this.addUndoState(snapshot)\n }, 300),\n )\n if (self.history.length === 0) {\n this.addUndoState(getSnapshot(targetStore))\n }\n },\n undo() {\n self.undoIdx--\n skipNextUndoState = true\n if (targetStore) {\n applySnapshot(targetStore, self.history[self.undoIdx])\n }\n },\n redo() {\n self.undoIdx++\n skipNextUndoState = true\n if (targetStore) {\n applySnapshot(targetStore, self.history[self.undoIdx])\n }\n },\n }\n })\n\nexport default TimeTraveller\n","import { ConfigurationSchema } from '../configuration'\n\n/**\n * #config BaseRpcDriver\n */\nfunction x() {} // eslint-disable-line @typescript-eslint/no-unused-vars\n\nconst BaseRpcDriverConfigSchema = ConfigurationSchema(\n 'BaseRpcDriver',\n {\n /**\n * #slot\n */\n workerCount: {\n type: 'number',\n description:\n 'The number of workers to use. If 0 (the default) JBrowse will decide how many workers to use.',\n defaultValue: 0,\n },\n },\n { explicitlyTyped: true },\n)\nexport default BaseRpcDriverConfigSchema\n","import { ConfigurationSchema } from '../configuration'\nimport BaseRpcDriverConfigSchema from './baseRpcConfig'\n\n/**\n * #config WebWorkerRpcDriver\n */\nfunction x() {} // eslint-disable-line @typescript-eslint/no-unused-vars\n\nconst WebWorkerRpcDriverConfigSchema = ConfigurationSchema(\n 'WebWorkerRpcDriver',\n {},\n {\n /**\n * #baseConfiguration\n */\n baseConfiguration: BaseRpcDriverConfigSchema,\n explicitlyTyped: true,\n },\n)\nexport default WebWorkerRpcDriverConfigSchema\n","import { ConfigurationSchema } from '../configuration'\nimport BaseRpcDriverConfigSchema from './baseRpcConfig'\n\n/**\n * #config MainThreadRpcDriver\n */\nfunction x() {} // eslint-disable-line @typescript-eslint/no-unused-vars\n\nconst MainThreadRpcDriverConfigSchema = ConfigurationSchema(\n 'MainThreadRpcDriver',\n {},\n {\n /**\n * #baseConfiguration\n */\n baseConfiguration: BaseRpcDriverConfigSchema,\n explicitlyTyped: true,\n },\n)\nexport default MainThreadRpcDriverConfigSchema\n","import { types } from 'mobx-state-tree'\nimport { ConfigurationSchema } from '../configuration'\nimport WebWorkerRpcDriverConfigSchema from './webWorkerRpcConfig'\nimport MainThreadRpcDriverConfigSchema from './mainThreadRpcConfig'\n\n/**\n * #config RpcOptions\n */\nfunction x() {} // eslint-disable-line @typescript-eslint/no-unused-vars\n\nexport default ConfigurationSchema(\n 'RpcOptions',\n {\n /**\n * #slot\n */\n defaultDriver: {\n type: 'string',\n description:\n 'the RPC driver to use for tracks and tasks that are not configured to use a specific RPC backend',\n defaultValue: 'MainThreadRpcDriver',\n },\n /**\n * #slot\n */\n drivers: types.optional(\n types.map(\n types.union(\n MainThreadRpcDriverConfigSchema,\n WebWorkerRpcDriverConfigSchema,\n ),\n ),\n {\n MainThreadRpcDriver: { type: 'MainThreadRpcDriver' },\n WebWorkerRpcDriver: { type: 'WebWorkerRpcDriver' },\n },\n ),\n },\n {\n actions: (self: any) => ({\n addDriverConfig(configName: string, configSnapshot: { type: string }) {\n self.drivers.set(configName, configSnapshot)\n },\n }),\n },\n)\n","import { isAlive, isStateTreeNode } from 'mobx-state-tree'\nimport { clamp } from '../util'\nimport { serializeAbortSignal } from './remoteAbortSignals'\nimport PluginManager from '../PluginManager'\nimport { readConfObject, AnyConfigurationModel } from '../configuration'\n\nexport interface WorkerHandle {\n status?: string\n error?: unknown\n on?: (channel: string, callback: (message: unknown) => void) => void\n off?: (channel: string, callback: (message: unknown) => void) => void\n destroy(): void\n call(\n functionName: string,\n args?: unknown,\n options?: {\n statusCallback?(message: string): void\n timeout?: number\n rpcDriverClassName: string\n },\n ): Promise<unknown>\n}\n\nexport interface RpcDriverConstructorArgs {\n config: AnyConfigurationModel\n}\n\nfunction isClonable(thing: unknown) {\n return !(typeof thing === 'function') && !(thing instanceof Error)\n}\n\n// watches the given worker object, returns a promise that will be rejected if\n// the worker times out\nexport async function watchWorker(\n worker: WorkerHandle,\n pingTime: number,\n rpcDriverClassName: string,\n) {\n // after first ping succeeds, apply wait for timeout\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n await worker.call('ping', [], {\n timeout: pingTime * 2,\n rpcDriverClassName,\n })\n await new Promise(resolve => setTimeout(resolve, pingTime))\n }\n}\n\nfunction detectHardwareConcurrency() {\n const mainThread = typeof window !== 'undefined'\n const canDetect = mainThread && 'hardwareConcurrency' in window.navigator\n if (mainThread && canDetect) {\n return window.navigator.hardwareConcurrency\n }\n return 1\n}\nclass LazyWorker {\n workerP?: Promise<WorkerHandle> | undefined\n\n constructor(public driver: BaseRpcDriver) {}\n\n async getWorker() {\n if (!this.workerP) {\n this.workerP = this.driver\n .makeWorker()\n .then(worker => {\n watchWorker(worker, this.driver.maxPingTime, this.driver.name).catch(\n (error: unknown) => {\n console.error(\n 'worker did not respond, killing and generating new one',\n )\n console.error(error)\n worker.destroy()\n worker.status = 'killed'\n worker.error = error\n this.workerP = undefined\n },\n )\n return worker\n })\n .catch((e: unknown) => {\n this.workerP = undefined\n throw e\n })\n }\n return this.workerP\n }\n}\n\nexport default abstract class BaseRpcDriver {\n abstract name: string\n\n private lastWorkerAssignment = -1\n\n private workerAssignments = new Map<string, number>() // sessionId -> worker number\n\n abstract makeWorker(): Promise<WorkerHandle>\n\n private workerPool?: LazyWorker[]\n\n maxPingTime = 30000\n\n workerCheckFrequency = 5000\n\n config: AnyConfigurationModel\n\n constructor(args: RpcDriverConstructorArgs) {\n this.config = args.config\n }\n\n // filter the given object and just remove any non-clonable things from it\n filterArgs<THING_TYPE>(thing: THING_TYPE, sessionId: string): THING_TYPE {\n if (Array.isArray(thing)) {\n return thing\n .filter(thing => isClonable(thing))\n .map(t => this.filterArgs(t, sessionId)) as unknown as THING_TYPE\n }\n if (typeof thing === 'object' && thing !== null) {\n // AbortSignals are specially handled\n if (thing instanceof AbortSignal) {\n return serializeAbortSignal(\n thing,\n this.remoteAbort.bind(this, sessionId),\n ) as unknown as THING_TYPE\n }\n\n if (isStateTreeNode(thing) && !isAlive(thing)) {\n throw new Error('dead state tree node passed to RPC call')\n }\n\n // special case, don't try to iterate the file's subelements as the\n // object entries below would\n if (thing instanceof File) {\n return thing\n }\n\n return Object.fromEntries(\n Object.entries(thing)\n .filter(e => isClonable(e[1]))\n .map(([k, v]) => [k, this.filterArgs(v, sessionId)]),\n ) as THING_TYPE\n }\n return thing\n }\n\n async remoteAbort(sessionId: string, functionName: string, signalId: number) {\n const worker = await this.getWorker(sessionId)\n await worker.call(\n functionName,\n { signalId },\n { timeout: 1000000, rpcDriverClassName: this.name },\n )\n }\n\n createWorkerPool(): LazyWorker[] {\n const hardwareConcurrency = detectHardwareConcurrency()\n\n const workerCount =\n readConfObject(this.config, 'workerCount') ||\n clamp(1, Math.max(1, hardwareConcurrency - 1), 5)\n\n const workers = []\n for (let i = 0; i < workerCount; i++) {\n workers.push(new LazyWorker(this))\n }\n return workers\n }\n\n getWorkerPool() {\n if (!this.workerPool) {\n const res = this.createWorkerPool()\n this.workerPool = res\n return res // making this several steps makes TS happy\n }\n return this.workerPool\n }\n\n async getWorker(sessionId: string): Promise<WorkerHandle> {\n const workers = this.getWorkerPool()\n let workerNumber = this.workerAssignments.get(sessionId)\n if (workerNumber === undefined) {\n const workerAssignment = (this.lastWorkerAssignment + 1) % workers.length\n this.workerAssignments.set(sessionId, workerAssignment)\n this.lastWorkerAssignment = workerAssignment\n workerNumber = workerAssignment\n }\n\n return workers[workerNumber]!.getWorker()\n }\n\n async call(\n pluginManager: PluginManager,\n sessionId: string,\n functionName: string,\n args: {\n statusCallback?: (message: unknown) => void\n },\n options = {},\n ) {\n if (!sessionId) {\n throw new TypeError('sessionId is required')\n }\n let done = false\n const unextendedWorker = await this.getWorker(sessionId)\n const worker = pluginManager.evaluateExtensionPoint(\n 'Core-extendWorker',\n unextendedWorker,\n ) as WorkerHandle\n const rpcMethod = pluginManager.getRpcMethodType(functionName)\n if (!rpcMethod) {\n throw new Error(`unknown RPC method ${functionName}`)\n }\n const serializedArgs = await rpcMethod.serializeArguments(args, this.name)\n const filteredAndSerializedArgs = this.filterArgs(serializedArgs, sessionId)\n\n // now actually call the worker\n const callP = worker\n .call(functionName, filteredAndSerializedArgs, {\n timeout: 5 * 60 * 1000, // 5 minutes\n statusCallback: args.statusCallback,\n rpcDriverClassName: this.name,\n ...options,\n })\n .finally(() => {\n done = true\n })\n\n // check every 5 seconds to see if the worker has been killed, and\n // reject the killedP promise if it has\n let killedCheckInterval: ReturnType<typeof setInterval>\n const killedP = new Promise((resolve, reject) => {\n killedCheckInterval = setInterval(() => {\n // must've been killed\n if (worker.status === 'killed') {\n reject(\n new Error(\n `operation timed out, worker process stopped responding, ${worker.error}`,\n ),\n )\n } else if (done) {\n resolve(true)\n }\n }, this.workerCheckFrequency)\n }).finally(() => {\n clearInterval(killedCheckInterval)\n })\n\n // the result is a race between the actual result promise, and the \"killed\"\n // promise. the killed promise will only actually win if the worker was\n // killed before the call could return\n const resultP = Promise.race([callP, killedP])\n return rpcMethod.deserializeReturn(resultP, args, this.name)\n }\n}\n","import { deserializeError } from 'serialize-error'\nimport Rpc from 'librpc-web-mod'\n\n// locals\nimport { nanoid } from '../util/nanoid'\nimport BaseRpcDriver, { RpcDriverConstructorArgs } from './BaseRpcDriver'\nimport { PluginDefinition } from '../PluginLoader'\n\ninterface WebWorkerRpcDriverConstructorArgs extends RpcDriverConstructorArgs {\n makeWorkerInstance: () => Worker\n}\n\ninterface Options {\n statusCallback?: (arg0: unknown) => void\n rpcDriverClassName: string\n}\n\nclass WebWorkerHandle extends Rpc.Client {\n destroy(): void {\n this.workers[0]!.terminate()\n }\n\n async call(funcName: string, args: Record<string, unknown>, opts: Options) {\n const { statusCallback, rpcDriverClassName } = opts\n const channel = `message-${nanoid()}`\n const listener = (message: unknown) => {\n statusCallback?.(message)\n }\n this.on(channel, listener)\n const result = await super.call(\n funcName,\n { ...args, channel, rpcDriverClassName },\n opts,\n )\n this.off(channel, listener)\n return result\n }\n}\n\nexport default class WebWorkerRpcDriver extends BaseRpcDriver {\n name = 'WebWorkerRpcDriver'\n\n makeWorkerInstance: () => Worker\n\n constructor(\n args: WebWorkerRpcDriverConstructorArgs,\n public workerBootConfiguration: {\n plugins: PluginDefinition[]\n windowHref: string\n },\n ) {\n super(args)\n this.makeWorkerInstance = args.makeWorkerInstance\n }\n\n async makeWorker() {\n // note that we are making a Rpc.Client connection with a worker pool of\n // one for each worker, because we want to do our own state-group-aware\n // load balancing rather than using librpc's builtin round-robin\n const instance = this.makeWorkerInstance()\n\n // @ts-ignore this is used to avoid warning in jbrowse-web startup\n // (because this file is referred to via src, declare.d.ts file is in\n // e.g. products/jbrowse-web)\n const worker = new WebWorkerHandle({ workers: [instance] })\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n if (isSafari) {\n // xref https://github.com/GMOD/jbrowse-components/issues/3245\n // eslint-disable-next-line no-console\n console.log(\n 'console logging the webworker handle avoids the track going into an infinite loading state, this is a hacky workaround for safari',\n instance,\n )\n }\n\n // send the worker its boot configuration using info from the pluginManager\n return new Promise((resolve: (w: WebWorkerHandle) => void, reject) => {\n const listener = (e: MessageEvent) => {\n switch (e.data.message) {\n case 'ready': {\n resolve(worker)\n worker.workers[0]!.removeEventListener('message', listener)\n break\n }\n case 'readyForConfig': {\n worker.workers[0]!.postMessage({\n message: 'config',\n config: this.workerBootConfiguration,\n })\n break\n }\n case 'error': {\n reject(deserializeError(e.data.error))\n break\n }\n // No default\n }\n }\n worker.workers[0]!.addEventListener('message', listener)\n })\n }\n}\n","import BaseRpcDriver, { RpcDriverConstructorArgs } from './BaseRpcDriver'\nimport PluginManager from '../PluginManager'\n\nclass DummyHandle {\n destroy(): void {}\n\n async call(\n _functionName: string,\n _filteredArgs?: Record<string, unknown>,\n _options = {},\n ): Promise<unknown> {\n return undefined\n }\n}\n\n/**\n * Stub RPC driver class that runs RPC functions in-band in the main thread.\n *\n * @param rpcFuncs - object containing runnable rpc functions\n */\nexport default class MainThreadRpcDriver extends BaseRpcDriver {\n name = 'MainThreadRpcDriver'\n\n makeWorker: () => Promise<DummyHandle>\n\n constructor(args: RpcDriverConstructorArgs) {\n super(args)\n this.makeWorker = async (): Promise<DummyHandle> => new DummyHandle()\n }\n\n async call(\n pm: PluginManager,\n sessionId: string,\n funcName: string,\n args: Record<string, unknown>,\n ) {\n if (!sessionId) {\n throw new TypeError('sessionId is required')\n }\n const rpcMethod = pm.getRpcMethodType(funcName)\n if (!rpcMethod) {\n throw new Error(`unknown RPC method ${funcName}`)\n }\n const serializedArgs = await rpcMethod.serializeArguments(args, this.name)\n const result = await rpcMethod.execute(serializedArgs, this.name)\n return rpcMethod.deserializeReturn(result, args, this.name)\n }\n}\n","import PluginManager from '../PluginManager'\nimport { readConfObject, AnyConfigurationModel } from '../configuration'\nimport rpcConfigSchema from './configSchema'\nimport WebWorkerRpcDriver from './WebWorkerRpcDriver'\nimport MainThreadRpcDriver from './MainThreadRpcDriver'\n\ntype DriverClass = WebWorkerRpcDriver | MainThreadRpcDriver\ninterface BackendConfigurations {\n WebWorkerRpcDriver?: Omit<\n ConstructorParameters<typeof WebWorkerRpcDriver>[0],\n 'config'\n >\n MainThreadRpcDriver?: Omit<\n ConstructorParameters<typeof MainThreadRpcDriver>[0],\n 'config'\n >\n}\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst DriverClasses = {\n WebWorkerRpcDriver,\n MainThreadRpcDriver,\n}\n\nexport default class RpcManager {\n static configSchema = rpcConfigSchema\n\n driverObjects: Map<string, DriverClass>\n\n constructor(\n public pluginManager: PluginManager,\n public mainConfiguration: AnyConfigurationModel,\n public backendConfigurations: BackendConfigurations,\n ) {\n this.driverObjects = new Map()\n }\n\n getDriver(backendName: keyof typeof DriverClasses) {\n const driver = this.driverObjects.get(backendName)\n if (driver) {\n return driver\n }\n const config = this.mainConfiguration.drivers.get('WebWorkerRpcDriver')\n if (backendName === 'MainThreadRpcDriver') {\n const backendConfiguration =\n this.backendConfigurations.MainThreadRpcDriver\n\n if (!backendConfiguration) {\n throw new Error(\n `requested RPC driver \"${backendName}\" is missing config`,\n )\n }\n const newDriver = new MainThreadRpcDriver({\n ...backendConfiguration,\n config,\n })\n this.driverObjects.set(backendName, newDriver)\n return newDriver\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n else if (backendName === 'WebWorkerRpcDriver') {\n const backendConfiguration = this.backendConfigurations.WebWorkerRpcDriver\n if (!backendConfiguration) {\n throw new Error(\n `requested RPC driver \"${backendName}\" is missing config`,\n )\n }\n const newDriver = new WebWorkerRpcDriver(\n { ...backendConfiguration, config },\n {\n plugins: this.pluginManager.runtimePluginDefinitions,\n windowHref: window.location.href,\n },\n )\n this.driverObjects.set(backendName, newDriver)\n return newDriver\n } else {\n throw new Error(`requested RPC driver \"${backendName}\" is not installed`)\n }\n }\n\n async getDriverForCall(\n _sessionId: string,\n _functionName: string,\n args: { rpcDriverName?: string },\n ) {\n const backendName =\n args.rpcDriverName ||\n readConfObject(this.mainConfiguration, 'defaultDriver')\n\n return this.getDriver(backendName)\n }\n\n async call(\n sessionId: string,\n functionName: string,\n args: Record<string, unknown>,\n opts = {},\n ) {\n if (!sessionId) {\n throw new Error('sessionId is required')\n }\n const driverForCall = await this.getDriverForCall(\n sessionId,\n functionName,\n args,\n )\n return driverForCall.call(\n this.pluginManager,\n sessionId,\n functionName,\n args,\n opts,\n )\n }\n}\n","import React, { useState, lazy } from 'react'\nimport { observer } from 'mobx-react'\nimport { Button, alpha } from '@mui/material'\nimport { makeStyles } from 'tss-react/mui'\nimport { AbstractSessionModel } from '@jbrowse/core/util'\n\n// icons\nimport ShareIcon from '@mui/icons-material/Share'\n\nconst useStyles = makeStyles()(theme => ({\n shareDiv: {\n textAlign: 'center',\n paddingLeft: '2px',\n },\n shareButton: {\n backgroundColor: alpha(\n theme.palette.primary.contrastText,\n theme.palette.action.hoverOpacity,\n ),\n '&:hover': {\n '@media (hover: none)': {\n backgroundColor: 'transparent',\n },\n },\n },\n}))\n\nconst ShareDialog = lazy(() => import('./ShareDialog'))\n\nconst ShareButton = observer(function (props: {\n session: AbstractSessionModel & { shareURL: string }\n}) {\n const [open, setOpen] = useState(false)\n const { session } = props\n const { classes } = useStyles()\n\n return (\n <div className={classes.shareDiv}>\n <Button\n onClick={async () => {\n setOpen(true)\n }}\n size=\"small\"\n color=\"inherit\"\n startIcon={<ShareIcon />}\n classes={{ root: classes.shareButton }}\n >\n Share\n </Button>\n {open ? (\n <React.Suspense fallback={null}>\n <ShareDialog\n handleClose={() => {\n setOpen(false)\n }}\n session={session}\n />\n </React.Suspense>\n ) : null}\n </div>\n )\n})\n\nexport default ShareButton\n","import React, { useEffect } from 'react'\nimport { observer } from 'mobx-react'\nimport { onSnapshot } from 'mobx-state-tree'\nimport { useQueryParam, StringParam } from 'use-query-params'\nimport { CssBaseline, ThemeProvider } from '@mui/material'\n\n// core\nimport { App } from '@jbrowse/app-core'\nimport PluginManager from '@jbrowse/core/PluginManager'\n\n// locals\nimport ShareButton from './ShareButton'\nimport { WebSessionModel } from '../sessionModel'\n\nconst JBrowse = observer(function ({\n pluginManager,\n}: {\n pluginManager: PluginManager\n}) {\n const [adminKey] = useQueryParam('adminKey', StringParam)\n const [adminServer] = useQueryParam('adminServer', StringParam)\n const [configPath] = useQueryParam('config', StringParam)\n const [, setSessionId] = useQueryParam('session', StringParam)\n const { rootModel } = pluginManager\n const { error, jbrowse } = rootModel || {}\n const session = rootModel?.session as WebSessionModel | undefined\n const currentSessionId = session?.id\n\n useEffect(() => {\n setSessionId(`local-${currentSessionId}`, 'replaceIn')\n // @ts-expect-error\n window.JBrowseRootModel = rootModel\n // @ts-expect-error\n window.JBrowseSession = session\n }, [currentSessionId, rootModel, session, setSessionId])\n\n useEffect(() => {\n if (!jbrowse || !adminKey) {\n return\n }\n return onSnapshot(jbrowse, async snapshot => {\n try {\n const response = await fetch(adminServer || '/updateConfig', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n adminKey,\n configPath,\n config: snapshot,\n }),\n })\n if (!response.ok) {\n const message = await response.text()\n throw new Error(`HTTP ${response.status} (${message})`)\n }\n } catch (e) {\n session?.notify(`Admin server error: ${e}`)\n }\n })\n }, [jbrowse, session, adminKey, adminServer, configPath])\n\n if (error) {\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n throw error\n }\n if (!rootModel) {\n throw new Error('No rootModel found')\n }\n if (!session) {\n throw new Error('No session found')\n }\n\n return (\n <ThemeProvider theme={session.theme}>\n <CssBaseline />\n <App\n // @ts-expect-error see comments on interface for AbstractSessionModel\n session={session}\n HeaderButtons={<ShareButton session={session} />}\n />\n </ThemeProvider>\n )\n})\n\nexport default JBrowse\n","import { types, addDisposer, Instance } from 'mobx-state-tree'\nimport { autorun } from 'mobx'\nimport PluginLoader, {\n PluginDefinition,\n PluginRecord,\n} from '@jbrowse/core/PluginLoader'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { nanoid } from '@jbrowse/core/util/nanoid'\n\n// locals\nimport { readSessionFromDynamo } from './sessionSharing'\nimport { addRelativeUris, checkPlugins, fromUrlSafeB64, readConf } from './util'\n\nexport interface SessionTriagedInfo {\n snap: unknown\n origin: string\n reason: PluginDefinition[]\n}\n\nconst SessionLoader = types\n .model({\n configPath: types.maybe(types.string),\n sessionQuery: types.maybe(types.string),\n password: types.maybe(types.string),\n adminKey: types.maybe(types.string),\n loc: types.maybe(types.string),\n sessionTracks: types.maybe(types.string),\n assembly: types.maybe(types.string),\n tracks: types.maybe(types.string),\n tracklist: types.maybe(types.boolean),\n highlight: types.maybe(types.string),\n nav: types.maybe(types.boolean),\n initialTimestamp: types.number,\n })\n .volatile(() => ({\n sessionTriaged: undefined as SessionTriagedInfo | undefined,\n configSnapshot: undefined as Record<string, unknown> | undefined,\n sessionSnapshot: undefined as Record<string, unknown> | undefined,\n sessionSpec: undefined as Record<string, unknown> | undefined,\n blankSession: false,\n runtimePlugins: [] as PluginRecord[],\n sessionPlugins: [] as PluginRecord[],\n sessionError: undefined as unknown,\n configError: undefined as unknown,\n bc1:\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n window.BroadcastChannel\n ? new window.BroadcastChannel('jb_request_session')\n : undefined,\n bc2:\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n window.BroadcastChannel\n ? new window.BroadcastChannel('jb_respond_session')\n : undefined,\n }))\n .views(self => ({\n get isSharedSession() {\n return !!self.sessionQuery?.startsWith('share-')\n },\n\n get isSpecSession() {\n return !!self.sessionQuery?.startsWith('spec-')\n },\n\n get isJb1StyleSession() {\n return !!self.loc\n },\n\n get isEncodedSession() {\n return !!self.sessionQuery?.startsWith('encoded-')\n },\n\n get isJsonSession() {\n return !!self.sessionQuery?.startsWith('json-')\n },\n\n get isLocalSession() {\n return !!self.sessionQuery?.startsWith('local-')\n },\n\n get ready() {\n return Boolean(this.isSessionLoaded && !self.configError)\n },\n\n get error() {\n return self.configError || self.sessionError\n },\n\n get isSessionLoaded() {\n return Boolean(\n self.sessionError ||\n self.sessionSnapshot ||\n self.blankSession ||\n self.sessionSpec,\n )\n },\n get isConfigLoaded() {\n return Boolean(self.configError || self.configSnapshot)\n },\n\n get sessionTracksParsed() {\n return self.sessionTracks ? JSON.parse(self.sessionTracks) : []\n },\n }))\n .actions(self => ({\n setSessionQuery(session?: any) {\n self.sessionQuery = session\n },\n setConfigError(error: unknown) {\n self.configError = error\n },\n setSessionError(error: unknown) {\n self.sessionError = error\n },\n setRuntimePlugins(plugins: PluginRecord[]) {\n self.runtimePlugins = plugins\n },\n setSessionPlugins(plugins: PluginRecord[]) {\n self.sessionPlugins = plugins\n },\n setConfigSnapshot(snap: Record<string, unknown>) {\n self.configSnapshot = snap\n },\n\n setBlankSession(flag: boolean) {\n self.blankSession = flag\n },\n setSessionTriaged(args?: SessionTriagedInfo) {\n self.sessionTriaged = args\n },\n setSessionSnapshotSuccess(snap: Record<string, unknown>) {\n self.sessionSnapshot = snap\n },\n }))\n .actions(self => ({\n async fetchPlugins(config: { plugins: PluginDefinition[] }) {\n try {\n const pluginLoader = new PluginLoader(config.plugins, {\n fetchESM: url => import(/* webpackIgnore:true */ url),\n })\n pluginLoader.installGlobalReExports(window)\n const runtimePlugins = await pluginLoader.load(window.location.href)\n self.setRuntimePlugins([...runtimePlugins])\n } catch (e) {\n console.error(e)\n self.setConfigError(e)\n }\n },\n async fetchSessionPlugins(snap: { sessionPlugins?: PluginDefinition[] }) {\n try {\n const pluginLoader = new PluginLoader(snap.sessionPlugins || [], {\n fetchESM: url => import(/* webpackIgnore:true */ url),\n })\n pluginLoader.installGlobalReExports(window)\n const plugins = await pluginLoader.load(window.location.href)\n self.setSessionPlugins([...plugins])\n } catch (e) {\n console.error(e)\n self.setConfigError(e)\n }\n },\n\n // passed\n async setSessionSnapshot(\n snap: { sessionPlugins?: PluginDefinition[]; id: string },\n userAcceptedConfirmation?: boolean,\n ) {\n try {\n const { sessionPlugins = [] } = snap\n const sessionPluginsAllowed = await checkPlugins(sessionPlugins)\n if (sessionPluginsAllowed || userAcceptedConfirmation) {\n await this.fetchSessionPlugins(snap)\n self.setSessionSnapshotSuccess(snap)\n } else {\n self.setSessionTriaged({\n snap,\n origin: 'session',\n reason: sessionPlugins,\n })\n }\n } catch (e) {\n console.error(e)\n self.setConfigError(e)\n }\n },\n\n async fetchConfig() {\n // @ts-expect-error\n\n let { configPath = window.__jbrowseConfigPath || 'config.json' } = self\n\n // @ts-expect-error\n\n if (window.__jbrowseCacheBuster) {\n configPath += `?rand=${Math.random()}`\n }\n\n const text = await openLocation({\n uri: configPath,\n locationType: 'UriLocation',\n }).readFile('utf8')\n const config = JSON.parse(text)\n const configUri = new URL(configPath, window.location.href)\n addRelativeUris(config, configUri)\n\n // cross origin config check\n if (configUri.hostname !== window.location.hostname) {\n const configPlugins = config.plugins || []\n const configPluginsAllowed = await checkPlugins(configPlugins)\n if (!configPluginsAllowed) {\n self.setSessionTriaged({\n snap: config,\n origin: 'config',\n reason: configPlugins,\n })\n return\n }\n }\n await this.fetchPlugins(config)\n self.setConfigSnapshot(config)\n },\n\n async fetchSessionStorageSession() {\n const sessionStr = sessionStorage.getItem('current')\n const query = self.sessionQuery!.replace('local-', '')\n\n // check if\n if (sessionStr) {\n const sessionSnap = JSON.parse(sessionStr).session || {}\n if (query === sessionSnap.id) {\n return this.setSessionSnapshot(sessionSnap)\n }\n }\n\n if (self.bc1) {\n self.bc1.postMessage(query)\n try {\n const result = await new Promise<Record<string, unknown>>(\n (resolve, reject) => {\n if (self.bc2) {\n self.bc2.onmessage = msg => {\n resolve(msg.data)\n }\n }\n setTimeout(() => {\n reject(new Error('timeout'))\n }, 1000)\n },\n )\n await this.setSessionSnapshot({ ...result, id: nanoid() })\n } catch (e) {\n // the broadcast channels did not find the session in another tab\n // clear session param, so just ignore\n }\n }\n throw new Error('Local storage session not found')\n },\n\n async fetchSharedSession() {\n const defaultURL = 'https://share.jbrowse.org/api/v1/'\n const decryptedSession = await readSessionFromDynamo(\n // @ts-expect-error\n `${readConf(self.configSnapshot, 'shareURL', defaultURL)}load`,\n self.sessionQuery || '',\n self.password || '',\n )\n\n const session = JSON.parse(await fromUrlSafeB64(decryptedSession))\n await this.setSessionSnapshot({ ...session, id: nanoid() })\n },\n\n async decodeEncodedUrlSession() {\n const session = JSON.parse(\n // @ts-expect-error\n await fromUrlSafeB64(self.sessionQuery.replace('encoded-', '')),\n )\n await this.setSessionSnapshot({ ...session, id: nanoid() })\n },\n\n decodeSessionSpec() {\n if (!self.sessionQuery) {\n return\n }\n self.sessionSpec = JSON.parse(self.sessionQuery.replace('spec-', ''))\n },\n\n decodeJb1StyleSession() {\n const {\n loc,\n tracks,\n assembly,\n tracklist,\n nav,\n highlight,\n sessionTracksParsed: sessionTracks,\n } = self\n if (loc) {\n self.sessionSpec = {\n sessionTracks,\n views: [\n {\n type: 'LinearGenomeView',\n tracks: tracks?.split(','),\n sessionTracks,\n loc,\n assembly,\n tracklist,\n nav,\n highlight: highlight?.split(' '),\n },\n ],\n }\n }\n },\n\n async decodeJsonUrlSession() {\n // @ts-expect-error\n const session = JSON.parse(self.sessionQuery.replace('json-', ''))\n await this.setSessionSnapshot({ ...session.session, id: nanoid() })\n },\n\n async afterCreate() {\n try {\n // rename the current autosave from previously loaded jbrowse session\n // into previousAutosave on load\n const { configPath } = self\n const lastAutosave = localStorage.getItem(`autosave-${configPath}`)\n if (lastAutosave) {\n localStorage.setItem(`previousAutosave-${configPath}`, lastAutosave)\n }\n } catch (e) {\n console.error('failed to create previousAutosave', e)\n }\n\n try {\n // fetch config\n await this.fetchConfig()\n } catch (e) {\n console.error(e)\n self.setConfigError(e)\n return\n }\n\n addDisposer(\n self,\n autorun(async () => {\n try {\n const {\n isLocalSession,\n isEncodedSession,\n isSpecSession,\n isSharedSession,\n isJsonSession,\n isJb1StyleSession,\n sessionQuery,\n configSnapshot,\n } = self\n if (!configSnapshot) {\n return\n }\n\n if (self.bc1) {\n self.bc1.onmessage = msg => {\n const r =\n JSON.parse(sessionStorage.getItem('current') || '{}')\n .session || {}\n if (r.id === msg.data && self.bc2) {\n self.bc2.postMessage(r)\n }\n }\n }\n\n if (isSharedSession) {\n await this.fetchSharedSession()\n } else if (isSpecSession) {\n this.decodeSessionSpec()\n } else if (isJb1StyleSession) {\n this.decodeJb1StyleSession()\n } else if (isEncodedSession) {\n await this.decodeEncodedUrlSession()\n } else if (isJsonSession) {\n await this.decodeJsonUrlSession()\n } else if (isLocalSession) {\n await this.fetchSessionStorageSession()\n } else if (sessionQuery) {\n // if there was a sessionQuery and we don't recognize it\n throw new Error('unrecognized session format')\n } else {\n // placeholder for session loaded, but none found\n self.setBlankSession(true)\n }\n } catch (e) {\n console.error(e)\n self.setSessionError(e)\n }\n }),\n )\n },\n }))\n\nexport type SessionLoaderModel = Instance<typeof SessionLoader>\n\nexport default SessionLoader\n\ninterface ViewSpec {\n type: string\n tracks?: string[]\n assembly: string\n loc: string\n}\n\n// use extension point named e.g. LaunchView-LinearGenomeView to initialize an\n// LGV session\nexport function loadSessionSpec(\n {\n views,\n sessionTracks = [],\n }: {\n views: ViewSpec[]\n sessionTracks: unknown[]\n },\n pluginManager: PluginManager,\n) {\n return async () => {\n const { rootModel } = pluginManager\n if (!rootModel) {\n throw new Error('rootModel not initialized')\n }\n try {\n // @ts-expect-error\n rootModel.setSession({\n name: `New session ${new Date().toLocaleString()}`,\n })\n\n // @ts-expect-error\n sessionTracks.forEach(track => rootModel.session.addTrackConf(track))\n\n await Promise.all(\n views.map(view =>\n pluginManager.evaluateAsyncExtensionPoint(`LaunchView-${view.type}`, {\n ...view,\n session: rootModel.session,\n }),\n ),\n )\n } catch (e) {\n console.error(e)\n rootModel.session?.notify(`${e}`)\n }\n }\n}\n","import React from 'react'\nimport { ErrorMessage } from '@jbrowse/core/ui'\nimport NoConfigMessage from './NoConfigMessage'\n\nexport default function StartScreenErrorMessage({ error }: { error: unknown }) {\n return /HTTP 404 fetching config.json/.exec(`${error}`) ? (\n <div>\n <h1>It worked!</h1>\n <p\n style={{\n margin: 8,\n padding: 8,\n background: '#9f9',\n border: '1px solid green',\n }}\n >\n JBrowse 2 is installed. Your next step is to add and configure an\n assembly. Follow our{' '}\n <a href=\"https://jbrowse.org/jb2/docs/quickstart_web/\">\n quick start guide\n </a>{' '}\n to continue or browse the sample data{' '}\n <a href=\"?config=test_data/volvox/config.json\">here</a>.\n </p>\n {process.env.NODE_ENV === 'development' ? <NoConfigMessage /> : null}\n </div>\n ) : (\n <div>\n <h1>JBrowse Error</h1>\n <ErrorMessage error={error} />\n </div>\n )\n}\n","// this is in a separate module here so it can be mocked out by jest. the\n// import.meta.url is not well recognized by jest and we use MainThreadRpc in\n// tests anyways right now\n//\n// note: this uses webpack 5 native worker modules\n//\n// see https://github.com/cmdcolin/cra-webpack5-web-worker-example for simple example\n// and docs https://webpack.js.org/guides/web-workers/\n//\n// also note: the craco config for webpack publicPath: 'auto' is needed for\n// these workers\nexport default function makeWorkerInstance() {\n return new Worker(new URL('./rpcWorker', import.meta.url))\n}\n","import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { JBrowseModelF } from '@jbrowse/app-core'\nimport { getSnapshot, resolveIdentifier, types } from 'mobx-state-tree'\nimport clone from 'clone'\n\n// locals\nimport { removeAttr } from './util'\n\n// poke some things for testing (this stuff will eventually be removed)\n// @ts-expect-error\nwindow.getSnapshot = getSnapshot\n// @ts-expect-error\nwindow.resolveIdentifier = resolveIdentifier\n\n/**\n * #stateModel JBrowseWebConfigModel\n * #category root\n * the rootModel.jbrowse state model for JBrowse Web\n */\nexport default function JBrowseWeb({\n pluginManager,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n assemblyConfigSchema: AnyConfigurationSchemaType\n}) {\n return types.snapshotProcessor(\n JBrowseModelF({ pluginManager, assemblyConfigSchema }),\n {\n postProcessor(snapshot: Record<string, any>) {\n return removeAttr(clone(snapshot), 'baseUri')\n },\n },\n )\n}\n","import { getParent, types, Instance, IAnyType } from 'mobx-state-tree'\nimport AbortablePromiseCache from '@gmod/abortable-promise-cache'\n\n// locals\nimport { getConf, AnyConfigurationModel } from '../configuration'\nimport {\n BaseOptions,\n BaseRefNameAliasAdapter,\n RegionsAdapter,\n} from '../data_adapters/BaseAdapter'\nimport PluginManager from '../PluginManager'\nimport { when, Region, Feature } from '../util'\nimport QuickLRU from '../util/QuickLRU'\nimport RpcManager from '../rpc/RpcManager'\nimport { adapterConfigCacheKey } from '../data_adapters/dataAdapterCache'\n\ntype AdapterConf = Record<string, unknown>\n\n/* biome-ignore lint/complexity/useRegexLiterals: */\nconst refNameRegex = new RegExp(\n '[0-9A-Za-z!#$%&+./:;?@^_|~-][0-9A-Za-z!#$%&*+./:;=?@^_|~-]*',\n)\n\n// Based on the UCSC Genome Browser chromosome color palette:\n// https://github.com/ucscGenomeBrowser/kent/blob/a50ed53aff81d6fb3e34e6913ce18578292bc24e/src/hg/inc/chromColors.h\n// Some colors darkened to have at least a 3:1 contrast ratio on a white\n// background\nconst refNameColors = [\n 'rgb(153, 102, 0)',\n 'rgb(102, 102, 0)',\n 'rgb(153, 153, 30)',\n 'rgb(204, 0, 0)',\n 'rgb(255, 0, 0)',\n 'rgb(255, 0, 204)',\n 'rgb(165, 132, 132)', // originally 'rgb(255, 204, 204)'\n 'rgb(204, 122, 0)', // originally rgb(255, 153, 0)'\n 'rgb(178, 142, 0)', // originally 'rgb(255, 204, 0)'\n 'rgb(153, 153, 0)', // originally 'rgb(255, 255, 0)'\n 'rgb(122, 153, 0)', // originally 'rgb(204, 255, 0)'\n 'rgb(0, 165, 0)', // originally 'rgb(0, 255, 0)'\n 'rgb(53, 128, 0)',\n 'rgb(0, 0, 204)',\n 'rgb(96, 145, 242)', // originally 'rgb(102, 153, 255)'\n 'rgb(107, 142, 178)', // originally 'rgb(153, 204, 255)'\n 'rgb(0, 165, 165)', // originally 'rgb(0, 255, 255)'\n 'rgb(122, 153, 153)', // originally 'rgb(204, 255, 255)'\n 'rgb(153, 0, 204)',\n 'rgb(204, 51, 255)',\n 'rgb(173, 130, 216)', // originally 'rgb(204, 153, 255)'\n 'rgb(102, 102, 102)',\n 'rgb(145, 145, 145)', // originally 'rgb(153, 153, 153)'\n 'rgb(142, 142, 142)', // originally 'rgb(204, 204, 204)'\n 'rgb(142, 142, 107)', // originally 'rgb(204, 204, 153)'\n 'rgb(96, 163, 48)', // originally 'rgb(121, 204, 61)'\n]\n\nasync function loadRefNameMap(\n assembly: Assembly,\n adapterConfig: unknown,\n options: BaseOptions,\n signal?: AbortSignal,\n) {\n const { sessionId } = options\n await when(() => !!(assembly.regions && assembly.refNameAliases), {\n signal,\n name: 'when assembly ready',\n })\n\n const refNames = (await assembly.rpcManager.call(\n sessionId || 'assemblyRpc',\n 'CoreGetRefNames',\n {\n adapterConfig,\n signal,\n ...options,\n },\n { timeout: 1000000 },\n )) as string[]\n\n const { refNameAliases } = assembly\n if (!refNameAliases) {\n throw new Error(`error loading assembly ${assembly.name}'s refNameAliases`)\n }\n\n const refNameMap = Object.fromEntries(\n refNames.map(name => {\n checkRefName(name)\n return [assembly.getCanonicalRefName(name), name]\n }),\n )\n\n return {\n forwardMap: refNameMap,\n reverseMap: Object.fromEntries(\n Object.entries(refNameMap).map(([canonicalName, adapterName]) => [\n adapterName,\n canonicalName,\n ]),\n ),\n }\n}\n\n// Valid refName pattern from https://samtools.github.io/hts-specs/SAMv1.pdf\nfunction checkRefName(refName: string) {\n if (!refNameRegex.test(refName)) {\n throw new Error(`Encountered invalid refName: \"${refName}\"`)\n }\n}\n\ntype RefNameAliases = Record<string, string>\n\ninterface CacheData {\n adapterConf: unknown\n self: Assembly\n sessionId: string\n options: BaseOptions\n}\n\nexport interface RefNameMap {\n forwardMap: RefNameAliases\n reverseMap: RefNameAliases\n}\n\nexport interface BasicRegion {\n start: number\n end: number\n refName: string\n assemblyName: string\n}\n\n/**\n * #stateModel Assembly\n */\nexport default function assemblyFactory(\n assemblyConfigType: IAnyType,\n pluginManager: PluginManager,\n) {\n const adapterLoads = new AbortablePromiseCache<CacheData, RefNameMap>({\n cache: new QuickLRU({ maxSize: 1000 }),\n\n // @ts-expect-error\n async fill(\n args: CacheData,\n signal?: AbortSignal,\n statusCallback?: (arg: string) => void,\n ) {\n const { adapterConf, self, options } = args\n return loadRefNameMap(\n self,\n adapterConf,\n { ...options, statusCallback },\n signal,\n )\n },\n })\n return types\n .model({\n /**\n * #property\n */\n configuration: types.safeReference(assemblyConfigType),\n })\n .volatile(() => ({\n error: undefined as unknown,\n loadingP: undefined as Promise<void> | undefined,\n volatileRegions: undefined as BasicRegion[] | undefined,\n refNameAliases: undefined as RefNameAliases | undefined,\n lowerCaseRefNameAliases: undefined as RefNameAliases | undefined,\n cytobands: undefined as Feature[] | undefined,\n }))\n .views(self => ({\n /**\n * #method\n */\n getConf(arg: string) {\n return self.configuration ? getConf(self, arg) : undefined\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get initialized() {\n // @ts-expect-error\n self.load()\n return !!self.refNameAliases\n },\n\n /**\n * #getter\n */\n get name(): string {\n return self.getConf('name') || ''\n },\n\n /**\n * #getter\n */\n get regions() {\n // @ts-expect-error\n self.load()\n return self.volatileRegions\n },\n\n /**\n * #getter\n */\n get aliases(): string[] {\n return self.getConf('aliases') || []\n },\n\n /**\n * #getter\n */\n get displayName(): string | undefined {\n return self.getConf('displayName')\n },\n /**\n * #getter\n */\n hasName(name: string) {\n return this.allAliases.includes(name)\n },\n\n /**\n * #getter\n */\n get allAliases() {\n return [this.name, ...this.aliases]\n },\n\n /**\n * #getter\n * note: lowerCaseRefNameAliases not included here: this allows the list\n * of refnames to be just the \"normal casing\", but things like\n * getCanonicalRefName can resolve a lower-case name if needed\n */\n get allRefNames() {\n return !self.refNameAliases\n ? undefined\n : Object.keys(self.refNameAliases)\n },\n /**\n * #getter\n */\n get lowerCaseRefNames() {\n return !self.lowerCaseRefNameAliases\n ? undefined\n : Object.keys(self.lowerCaseRefNameAliases)\n },\n\n /**\n * #getter\n */\n get allRefNamesWithLowerCase() {\n return this.allRefNames && this.lowerCaseRefNames\n ? [...new Set([...this.allRefNames, ...this.lowerCaseRefNames])]\n : undefined\n },\n /**\n * #getter\n */\n get rpcManager(): RpcManager {\n return getParent<any>(self, 2).rpcManager\n },\n /**\n * #getter\n */\n get refNameColors() {\n const colors: string[] = self.getConf('refNameColors') || []\n return colors.length === 0 ? refNameColors : colors\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get refNames() {\n return self.regions?.map(region => region.refName)\n },\n }))\n .views(self => ({\n /**\n * #method\n */\n getCanonicalRefName(refName: string) {\n if (!self.refNameAliases || !self.lowerCaseRefNameAliases) {\n throw new Error(\n 'aliases not loaded, we expect them to be loaded before getCanonicalRefName can be called',\n )\n }\n\n return (\n self.refNameAliases[refName] || self.lowerCaseRefNameAliases[refName]\n )\n },\n /**\n * #method\n */\n getRefNameColor(refName: string) {\n if (!self.refNames) {\n return undefined\n }\n const idx = self.refNames.indexOf(refName)\n return idx === -1\n ? undefined\n : self.refNameColors[idx % self.refNameColors.length]\n },\n /**\n * #method\n */\n isValidRefName(refName: string) {\n if (!self.refNameAliases) {\n throw new Error(\n 'isValidRefName cannot be called yet, the assembly has not finished loading',\n )\n }\n return !!this.getCanonicalRefName(refName)\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setLoaded({\n regions,\n refNameAliases,\n lowerCaseRefNameAliases,\n cytobands,\n }: {\n regions: Region[]\n refNameAliases: RefNameAliases\n lowerCaseRefNameAliases: RefNameAliases\n cytobands: Feature[]\n }) {\n this.setRegions(regions)\n this.setRefNameAliases(refNameAliases, lowerCaseRefNameAliases)\n this.setCytobands(cytobands)\n },\n /**\n * #action\n */\n setError(e: unknown) {\n self.error = e\n },\n /**\n * #action\n */\n setRegions(regions: Region[]) {\n self.volatileRegions = regions\n },\n /**\n * #action\n */\n setRefNameAliases(\n aliases: RefNameAliases,\n lowerCaseAliases: RefNameAliases,\n ) {\n self.refNameAliases = aliases\n self.lowerCaseRefNameAliases = lowerCaseAliases\n },\n /**\n * #action\n */\n setCytobands(cytobands: Feature[]) {\n self.cytobands = cytobands\n },\n /**\n * #action\n */\n setLoadingP(p?: Promise<void>) {\n self.loadingP = p\n },\n /**\n * #action\n */\n load() {\n if (!self.loadingP) {\n self.loadingP = this.loadPre().catch((e: unknown) => {\n this.setLoadingP(undefined)\n this.setError(e)\n })\n }\n return self.loadingP\n },\n /**\n * #action\n */\n async loadPre() {\n const conf = self.configuration\n const refNameAliasesAdapterConf = conf?.refNameAliases?.adapter\n const cytobandAdapterConf = conf?.cytobands?.adapter\n const sequenceAdapterConf = conf?.sequence.adapter\n const assemblyName = self.name\n\n const regions = await getAssemblyRegions({\n config: sequenceAdapterConf,\n pluginManager,\n })\n\n const adapterRegionsWithAssembly = regions.map(r => {\n checkRefName(r.refName)\n return { ...r, assemblyName }\n })\n const refNameAliases = {} as Record<string, string>\n\n const refNameAliasCollection = await getRefNameAliases({\n config: refNameAliasesAdapterConf,\n pluginManager,\n })\n\n for (const { refName, aliases, override } of refNameAliasCollection) {\n for (const alias of aliases) {\n checkRefName(alias)\n refNameAliases[alias] = refName\n }\n // the override field is supplied by a RefNameAliasAdapter to make\n // the refName field returned by the adapter to be used as the\n // primary names for this assembly\n if (override) {\n refNameAliases[refName] = refName\n }\n }\n // add identity to the refNameAliases list\n for (const region of adapterRegionsWithAssembly) {\n // this ||= means that if the refNameAliasAdapter already set a\n // mapping for the primary region to be an alias\n refNameAliases[region.refName] ||= region.refName\n }\n const lowerCaseRefNameAliases = Object.fromEntries(\n Object.entries(refNameAliases).map(([key, val]) => [\n key.toLowerCase(),\n val,\n ]),\n )\n\n this.setLoaded({\n refNameAliases,\n regions: adapterRegionsWithAssembly.map(r => ({\n ...r,\n refName: refNameAliases[r.refName] || r.refName,\n })),\n lowerCaseRefNameAliases,\n cytobands: await getCytobands({\n config: cytobandAdapterConf,\n pluginManager,\n }),\n })\n },\n }))\n .views(self => ({\n /**\n * #method\n */\n getAdapterMapEntry(adapterConf: AdapterConf, options: BaseOptions) {\n const { signal, statusCallback, ...rest } = options\n if (!options.sessionId) {\n throw new Error('sessionId is required')\n }\n return adapterLoads.get(\n adapterConfigCacheKey(adapterConf),\n {\n adapterConf,\n self,\n options: rest,\n } as CacheData,\n\n // signal intentionally not passed here, fixes issues like #2221.\n // alternative fix #2540 was proposed but non-working currently\n undefined,\n statusCallback,\n )\n },\n\n /**\n * #method\n * get Map of `canonical-name -> adapter-specific-name`\n */\n async getRefNameMapForAdapter(\n adapterConf: AdapterConf,\n opts: BaseOptions,\n ) {\n if (!opts.sessionId) {\n throw new Error('sessionId is required')\n }\n const map = await this.getAdapterMapEntry(adapterConf, opts)\n return map.forwardMap\n },\n\n /**\n * #method\n * get Map of `adapter-specific-name -> canonical-name`\n */\n async getReverseRefNameMapForAdapter(\n adapterConf: AdapterConf,\n opts: BaseOptions,\n ) {\n const map = await this.getAdapterMapEntry(adapterConf, opts)\n return map.reverseMap\n },\n }))\n}\n\nasync function getRefNameAliases({\n config,\n pluginManager,\n signal,\n}: {\n config: AnyConfigurationModel\n pluginManager: PluginManager\n signal?: AbortSignal\n}) {\n const type = pluginManager.getAdapterType(config.type)!\n const CLASS = await type.getAdapterClass()\n const adapter = new CLASS(\n config,\n undefined,\n pluginManager,\n ) as BaseRefNameAliasAdapter\n return adapter.getRefNameAliases({ signal })\n}\n\nasync function getCytobands({\n config,\n pluginManager,\n}: {\n config: AnyConfigurationModel\n pluginManager: PluginManager\n}) {\n const type = pluginManager.getAdapterType(config.type)!\n const CLASS = await type.getAdapterClass()\n const adapter = new CLASS(config, undefined, pluginManager)\n\n // @ts-expect-error\n return adapter.getData()\n}\n\nasync function getAssemblyRegions({\n config,\n pluginManager,\n signal,\n}: {\n config: AnyConfigurationModel\n pluginManager: PluginManager\n signal?: AbortSignal\n}) {\n const type = pluginManager.getAdapterType(config.type)!\n const CLASS = await type.getAdapterClass()\n const adapter = new CLASS(config, undefined, pluginManager) as RegionsAdapter\n return adapter.getRegions({ signal })\n}\n\nexport type AssemblyModel = ReturnType<typeof assemblyFactory>\nexport type Assembly = Instance<AssemblyModel>\n","import { lazy } from 'react'\nimport {\n addDisposer,\n cast,\n getSnapshot,\n getType,\n types,\n IAnyStateTreeNode,\n SnapshotIn,\n Instance,\n IAnyType,\n} from 'mobx-state-tree'\n\nimport { saveAs } from 'file-saver'\nimport { observable, autorun } from 'mobx'\nimport assemblyConfigSchemaFactory from '@jbrowse/core/assemblyManager/assemblyConfigSchema'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport RpcManager from '@jbrowse/core/rpc/RpcManager'\nimport TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'\nimport { AbstractSessionModel, SessionWithWidgets } from '@jbrowse/core/util'\nimport { MenuItem } from '@jbrowse/core/ui'\n\n// icons\nimport AddIcon from '@mui/icons-material/Add'\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport AppsIcon from '@mui/icons-material/Apps'\nimport FileCopyIcon from '@mui/icons-material/FileCopy'\nimport FolderOpenIcon from '@mui/icons-material/FolderOpen'\nimport GetAppIcon from '@mui/icons-material/GetApp'\nimport PublishIcon from '@mui/icons-material/Publish'\nimport ExtensionIcon from '@mui/icons-material/Extension'\nimport StorageIcon from '@mui/icons-material/Storage'\nimport SaveIcon from '@mui/icons-material/Save'\nimport UndoIcon from '@mui/icons-material/Undo'\nimport RedoIcon from '@mui/icons-material/Redo'\nimport { Cable } from '@jbrowse/core/ui/Icons'\n\n// other\nimport makeWorkerInstance from '../makeWorkerInstance'\nimport jbrowseWebFactory from '../jbrowseModel'\nimport { filterSessionInPlace } from '../util'\nimport packageJSON from '../../package.json'\nimport {\n BaseSession,\n BaseSessionType,\n SessionWithDialogs,\n InternetAccountsRootModelMixin,\n BaseRootModelFactory,\n} from '@jbrowse/product-core'\nimport { HistoryManagementMixin, RootAppMenuMixin } from '@jbrowse/app-core'\nimport { hydrateRoot, createRoot } from 'react-dom/client'\nimport { AssemblyManager } from '@jbrowse/plugin-data-management'\n\n// locals\nconst SetDefaultSession = lazy(() => import('../components/SetDefaultSession'))\nconst PreferencesDialog = lazy(() => import('../components/PreferencesDialog'))\n\nexport interface Menu {\n label: string\n menuItems: MenuItem[]\n}\n\ntype AssemblyConfig = ReturnType<typeof assemblyConfigSchemaFactory>\ntype SessionModelFactory = (args: {\n pluginManager: PluginManager\n assemblyConfigSchema: AssemblyConfig\n}) => IAnyType\n\n/**\n * #stateModel JBrowseWebRootModel\n *\n * composed of\n * - [BaseRootModel](../baserootmodel)\n * - [InternetAccountsMixin](../internetaccountsmixin)\n * - [HistoryManagementMixin](../historymanagementmixin)\n * - [RootAppMenuMixin](../rootappmenumixin)\n *\n * note: many properties of the root model are available through the session,\n * and we generally prefer using the session model (via e.g. getSession) over\n * the root model (via e.g. getRoot) in plugin code\n */\nexport default function RootModel({\n pluginManager,\n sessionModelFactory,\n adminMode = false,\n}: {\n pluginManager: PluginManager\n sessionModelFactory: SessionModelFactory\n adminMode?: boolean\n}) {\n const assemblyConfigSchema = assemblyConfigSchemaFactory(pluginManager)\n const jbrowseModelType = jbrowseWebFactory({\n pluginManager,\n assemblyConfigSchema,\n })\n const sessionModelType = sessionModelFactory({\n pluginManager,\n assemblyConfigSchema,\n })\n return types\n .compose(\n BaseRootModelFactory({\n pluginManager,\n jbrowseModelType,\n sessionModelType,\n assemblyConfigSchema,\n }),\n InternetAccountsRootModelMixin(pluginManager),\n HistoryManagementMixin(),\n RootAppMenuMixin(),\n )\n .props({\n /**\n * #property\n */\n configPath: types.maybe(types.string),\n })\n .volatile(self => ({\n version: packageJSON.version,\n hydrateFn: hydrateRoot,\n createRootFn: createRoot,\n pluginsUpdated: false,\n rpcManager: new RpcManager(\n pluginManager,\n self.jbrowse.configuration.rpc,\n {\n WebWorkerRpcDriver: { makeWorkerInstance },\n MainThreadRpcDriver: {},\n },\n ),\n savedSessionsVolatile: observable.map<\n string,\n { name: string; [key: string]: unknown }\n >({}),\n textSearchManager: new TextSearchManager(pluginManager),\n error: undefined as unknown,\n }))\n .views(self => ({\n /**\n * #getter\n */\n get savedSessions() {\n return [...self.savedSessionsVolatile.values()]\n },\n /**\n * #method\n */\n localStorageId(name: string) {\n return `localSaved-${name}-${self.configPath}`\n },\n /**\n * #getter\n */\n get autosaveId() {\n return `autosave-${self.configPath}`\n },\n /**\n * #getter\n */\n get previousAutosaveId() {\n return `previousAutosave-${self.configPath}`\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get savedSessionNames() {\n return self.savedSessions.map(session => session.name)\n },\n /**\n * #getter\n */\n get currentSessionId() {\n const locationUrl = new URL(window.location.href)\n const params = new URLSearchParams(locationUrl.search)\n return params.get('session')?.split('local-')[1]\n },\n }))\n\n .actions(self => ({\n afterCreate() {\n for (const [key, val] of Object.entries(localStorage)\n .filter(([key, _val]) => key.startsWith('localSaved-'))\n .filter(([key]) => key.includes(self.configPath || 'undefined'))) {\n try {\n const { session } = JSON.parse(val)\n self.savedSessionsVolatile.set(key, session)\n } catch (e) {\n console.error('bad session encountered', key, val)\n }\n }\n addDisposer(\n self,\n autorun(() => {\n for (const [, val] of self.savedSessionsVolatile.entries()) {\n try {\n const key = self.localStorageId(val.name)\n localStorage.setItem(key, JSON.stringify({ session: val }))\n } catch (e) {\n // @ts-expect-error\n if (e.code === '22' || e.code === '1024') {\n alert(\n 'Local storage is full! Please use the \"Open sessions\" panel to remove old sessions',\n )\n }\n }\n }\n }),\n )\n\n addDisposer(\n self,\n autorun(\n () => {\n if (!self.session) {\n return\n }\n const snapshot = getSnapshot(self.session as BaseSession)\n const s = JSON.stringify\n sessionStorage.setItem('current', s({ session: snapshot }))\n localStorage.setItem(\n `autosave-${self.configPath}`,\n s({\n session: {\n ...snapshot,\n name: `${snapshot.name}-autosaved`,\n },\n }),\n )\n\n // this check is not able to be modularized into it's own autorun\n // at current time because it depends on session storage snapshot\n // being set above\n if (self.pluginsUpdated) {\n window.location.reload()\n }\n },\n { delay: 400 },\n ),\n )\n },\n /**\n * #action\n */\n setSession(sessionSnapshot?: SnapshotIn<BaseSessionType>) {\n const oldSession = self.session\n self.session = cast(sessionSnapshot)\n if (self.session) {\n // validate all references in the session snapshot\n try {\n filterSessionInPlace(self.session, getType(self.session))\n } catch (error) {\n // throws error if session filtering failed\n self.session = oldSession\n throw error\n }\n }\n },\n\n /**\n * #action\n */\n setPluginsUpdated(flag: boolean) {\n self.pluginsUpdated = flag\n },\n /**\n * #action\n */\n setDefaultSession() {\n const { defaultSession } = self.jbrowse\n const newSession = {\n ...defaultSession,\n name: `${defaultSession.name} ${new Date().toLocaleString()}`,\n }\n\n this.setSession(newSession)\n },\n /**\n * #action\n */\n renameCurrentSession(sessionName: string) {\n if (self.session) {\n const snapshot = JSON.parse(JSON.stringify(getSnapshot(self.session)))\n snapshot.name = sessionName\n this.setSession(snapshot)\n }\n },\n /**\n * #action\n */\n addSavedSession(session: { name: string }) {\n const key = self.localStorageId(session.name)\n self.savedSessionsVolatile.set(key, session)\n },\n /**\n * #action\n */\n removeSavedSession(session: { name: string }) {\n const key = self.localStorageId(session.name)\n localStorage.removeItem(key)\n self.savedSessionsVolatile.delete(key)\n },\n /**\n * #action\n */\n duplicateCurrentSession() {\n if (self.session) {\n const snapshot = JSON.parse(JSON.stringify(getSnapshot(self.session)))\n let newSnapshotName = `${self.session.name} (copy)`\n if (self.savedSessionNames.includes(newSnapshotName)) {\n let newSnapshotCopyNumber = 2\n do {\n newSnapshotName = `${self.session.name} (copy ${newSnapshotCopyNumber})`\n newSnapshotCopyNumber += 1\n } while (self.savedSessionNames.includes(newSnapshotName))\n }\n snapshot.name = newSnapshotName\n this.setSession(snapshot)\n }\n },\n /**\n * #action\n */\n activateSession(name: string) {\n const localId = self.localStorageId(name)\n const newSessionSnapshot = localStorage.getItem(localId)\n if (!newSessionSnapshot) {\n throw new Error(\n `Can't activate session ${name}, it is not in the savedSessions`,\n )\n }\n\n this.setSession(JSON.parse(newSessionSnapshot).session)\n },\n /**\n * #action\n */\n saveSessionToLocalStorage() {\n if (self.session) {\n const key = self.localStorageId(self.session.name)\n self.savedSessionsVolatile.set(key, getSnapshot(self.session))\n }\n },\n loadAutosaveSession() {\n const previousAutosave = localStorage.getItem(self.previousAutosaveId)\n const autosavedSession = previousAutosave\n ? JSON.parse(previousAutosave).session\n : {}\n const { name } = autosavedSession\n autosavedSession.name = `${name.replace('-autosaved', '')}-restored`\n this.setSession(autosavedSession)\n },\n /**\n * #action\n */\n setError(error?: unknown) {\n self.error = error\n },\n }))\n .volatile(self => ({\n menus: [\n {\n label: 'File',\n menuItems: [\n {\n label: 'New session',\n icon: AddIcon,\n\n onClick: (session: any) => {\n const lastAutosave = localStorage.getItem(self.autosaveId)\n if (lastAutosave) {\n localStorage.setItem(self.previousAutosaveId, lastAutosave)\n }\n session.setDefaultSession()\n },\n },\n {\n label: 'Import session…',\n icon: PublishIcon,\n onClick: (session: SessionWithWidgets) => {\n const widget = session.addWidget(\n 'ImportSessionWidget',\n 'importSessionWidget',\n )\n session.showWidget(widget)\n },\n },\n {\n label: 'Export session',\n icon: GetAppIcon,\n onClick: (session: IAnyStateTreeNode) => {\n const sessionBlob = new Blob(\n [JSON.stringify({ session: getSnapshot(session) }, null, 2)],\n { type: 'text/plain;charset=utf-8' },\n )\n saveAs(sessionBlob, 'session.json')\n },\n },\n {\n label: 'Open session…',\n icon: FolderOpenIcon,\n onClick: (session: SessionWithWidgets) => {\n const widget = session.addWidget(\n 'SessionManager',\n 'sessionManager',\n )\n session.showWidget(widget)\n },\n },\n {\n label: 'Save session',\n icon: SaveIcon,\n onClick: (session: SessionWithWidgets) => {\n self.saveSessionToLocalStorage()\n session.notify(`Saved session \"${session.name}\"`, 'success')\n },\n },\n {\n label: 'Duplicate session',\n icon: FileCopyIcon,\n onClick: (session: AbstractSessionModel) => {\n if (session.duplicateCurrentSession) {\n session.duplicateCurrentSession()\n }\n },\n },\n { type: 'divider' },\n {\n label: 'Open track...',\n icon: StorageIcon,\n onClick: (session: SessionWithWidgets) => {\n if (session.views.length === 0) {\n session.notify('Please open a view to add a track first')\n } else if (session.views.length > 0) {\n const widget = session.addWidget(\n 'AddTrackWidget',\n 'addTrackWidget',\n { view: session.views[0]!.id },\n )\n session.showWidget(widget)\n if (session.views.length > 1) {\n session.notify(\n 'This will add a track to the first view. Note: if you want to open a track in a specific view open the track selector for that view and use the add track (plus icon) in the bottom right',\n )\n }\n }\n },\n },\n {\n label: 'Open connection...',\n icon: Cable,\n onClick: (session: SessionWithWidgets) => {\n session.showWidget(\n session.addWidget(\n 'AddConnectionWidget',\n 'addConnectionWidget',\n ),\n )\n },\n },\n { type: 'divider' },\n {\n label: 'Return to splash screen',\n icon: AppsIcon,\n onClick: () => {\n self.setSession(undefined)\n },\n },\n ],\n },\n ...(adminMode\n ? [\n {\n label: 'Admin',\n menuItems: [\n {\n label: 'Open assembly manager',\n onClick: () =>\n self.session.queueDialog((onClose: () => void) => [\n AssemblyManager,\n { onClose, rootModel: self },\n ]),\n },\n {\n label: 'Set default session',\n onClick: () =>\n self.session.queueDialog((onClose: () => void) => [\n SetDefaultSession,\n { rootModel: self, onClose },\n ]),\n },\n ],\n },\n ]\n : []),\n {\n label: 'Add',\n menuItems: [],\n },\n {\n label: 'Tools',\n menuItems: [\n {\n label: 'Undo',\n icon: UndoIcon,\n onClick: () => {\n if (self.history.canUndo) {\n self.history.undo()\n }\n },\n },\n {\n label: 'Redo',\n icon: RedoIcon,\n onClick: () => {\n if (self.history.canRedo) {\n self.history.redo()\n }\n },\n },\n { type: 'divider' },\n {\n label: 'Plugin store',\n icon: ExtensionIcon,\n onClick: () => {\n if (self.session) {\n self.session.showWidget(\n self.session.addWidget(\n 'PluginStoreWidget',\n 'pluginStoreWidget',\n ),\n )\n }\n },\n },\n {\n label: 'Preferences',\n icon: SettingsIcon,\n onClick: () => {\n if (self.session) {\n ;(self.session as SessionWithDialogs).queueDialog(\n handleClose => [\n PreferencesDialog,\n {\n session: self.session,\n handleClose,\n },\n ],\n )\n }\n },\n },\n ],\n },\n ] as Menu[],\n adminMode,\n }))\n}\n\nexport type WebRootModelType = ReturnType<typeof RootModel>\nexport type WebRootModel = Instance<WebRootModelType>\n","import { ConfigurationSchema } from '../configuration'\nimport PluginManager from '../PluginManager'\n\n/**\n * #config BaseAssembly\n * #category assemblyManagement\n * This corresponds to the assemblies section of the config\n */\nfunction assemblyConfigSchema(pluginManager: PluginManager) {\n return ConfigurationSchema(\n 'BaseAssembly',\n {\n /**\n * #slot\n * aliases are \"reference name aliases\" e.g. aliases for hg38 might be\n * \"GRCh38\"\n */\n aliases: {\n type: 'stringArray',\n defaultValue: [],\n description: 'Other possible names for the assembly',\n },\n\n /**\n * #slot\n * sequence refers to a reference sequence track that has an adapter\n * containing, importantly, a sequence adapter such as\n * IndexedFastaAdapter\n */\n sequence: pluginManager.getTrackType('ReferenceSequenceTrack')!\n .configSchema,\n\n /**\n * #slot\n */\n refNameColors: {\n type: 'stringArray',\n defaultValue: [],\n description:\n 'Define custom colors for each reference sequence. Will cycle through this list if there are not enough colors for every sequence.',\n },\n\n refNameAliases: ConfigurationSchema(\n 'RefNameAliases',\n {\n /**\n * #slot refNameAliases.adapter\n * refNameAliases help resolve e.g. chr1 and 1 as the same entity the\n * data for refNameAliases are fetched from an adapter, that is\n * commonly a tsv like chromAliases.txt from UCSC or similar\n */\n adapter: pluginManager.pluggableConfigSchemaType('adapter'),\n },\n {\n preProcessSnapshot: snap => {\n // allow refNameAliases to be unspecified\n if (!snap.adapter) {\n return { adapter: { type: 'RefNameAliasAdapter' } }\n }\n return snap\n },\n },\n ),\n cytobands: ConfigurationSchema(\n 'Cytoband',\n {\n /**\n * #slot cytobands.adapter\n * cytoband data is fetched from an adapter, and can be displayed by\n * a view type as ideograms\n */\n adapter: pluginManager.pluggableConfigSchemaType('adapter'),\n },\n {\n preProcessSnapshot: snap => {\n // allow cytoBand to be unspecified\n return !snap.adapter\n ? { adapter: { type: 'CytobandAdapter' } }\n : snap\n },\n },\n ),\n\n /**\n * #slot\n */\n displayName: {\n type: 'string',\n defaultValue: '',\n description:\n 'A human readable display name for the assembly e.g. \"Homo sapiens (hg38)\" while the assembly name may just be \"hg38\"',\n },\n },\n {\n /**\n * #identifier name\n * the name acts as a unique identifier in the config, so it cannot be\n * duplicated. it usually a short human readable \"id\" like hg38, but you\n * can also optionally customize the assembly \"displayName\" config slot\n */\n explicitIdentifier: 'name',\n },\n )\n}\n\nexport default assemblyConfigSchema\nexport type BaseAssemblyConfigSchema = ReturnType<typeof assemblyConfigSchema>\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'\nimport { cast, getParent, getSnapshot } from 'mobx-state-tree'\nimport RpcManager from '@jbrowse/core/rpc/RpcManager'\nimport {\n AnyConfigurationModel,\n readConfObject,\n} from '@jbrowse/core/configuration'\nimport { PluginDefinition } from '@jbrowse/core/PluginLoader'\nimport { toJS } from 'mobx'\n\n// locals\nimport { JBrowseConfigF } from '../JBrowseConfig'\n\n/**\n * #stateModel AppCoreJBrowseModel\n * note that JBrowseRootConfig is a config model, but config models are MST\n * trees themselves, which is why this stateModel is allowed to extend it\n *\n * the AppCoreJBrowseModel is generally on a property named rootModel.jbrowse\n *\n * extends\n * - [JBrowseRootConfig](/docs/config/jbrowserootconfig)\n\n */\nexport function JBrowseModelF({\n pluginManager,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n assemblyConfigSchema: BaseAssemblyConfigSchema\n}) {\n return JBrowseConfigF({ pluginManager, assemblyConfigSchema })\n .views(self => ({\n /**\n * #getter\n */\n get assemblyNames(): string[] {\n return self.assemblies.map(assembly => readConfObject(assembly, 'name'))\n },\n /**\n * #getter\n */\n get rpcManager(): RpcManager {\n return getParent<any>(self).rpcManager\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n addAssemblyConf(conf: AnyConfigurationModel) {\n const { name } = conf\n if (!name) {\n throw new Error('Can\\'t add assembly with no \"name\"')\n }\n if (self.assemblyNames.includes(name)) {\n throw new Error(\n `Can't add assembly with name \"${name}\", an assembly with that name already exists`,\n )\n }\n const length = self.assemblies.push({\n ...conf,\n sequence: {\n type: 'ReferenceSequenceTrack',\n trackId: `${name}-${Date.now()}`,\n ...conf.sequence,\n },\n })\n return self.assemblies[length - 1]\n },\n /**\n * #action\n */\n removeAssemblyConf(assemblyName: string) {\n const toRemove = self.assemblies.find(a => a.name === assemblyName)\n if (toRemove) {\n self.assemblies.remove(toRemove)\n }\n },\n /**\n * #action\n */\n addTrackConf(trackConf: AnyConfigurationModel) {\n const { type } = trackConf\n if (!type) {\n throw new Error(`unknown track type ${type}`)\n }\n const length = self.tracks.push(trackConf)\n return self.tracks[length - 1]\n },\n /**\n * #action\n */\n addConnectionConf(connectionConf: AnyConfigurationModel) {\n const { type } = connectionConf\n if (!type) {\n throw new Error(`unknown connection type ${type}`)\n }\n const length = self.connections.push(connectionConf)\n return self.connections[length - 1]\n },\n /**\n * #action\n */\n deleteConnectionConf(configuration: AnyConfigurationModel) {\n const elt = self.connections.find(conn => conn.id === configuration.id)\n return self.connections.remove(elt)\n },\n /**\n * #action\n */\n deleteTrackConf(trackConf: AnyConfigurationModel) {\n const elt = self.tracks.find(t => t.trackId === trackConf.trackId)\n return self.tracks.remove(elt)\n },\n /**\n * #action\n */\n addPlugin(pluginDefinition: PluginDefinition) {\n self.plugins.push(pluginDefinition)\n\n const rootModel = getParent<any>(self)\n rootModel.setPluginsUpdated(true)\n },\n /**\n * #action\n */\n removePlugin(pluginDefinition: PluginDefinition) {\n self.plugins = cast(\n self.plugins.filter(\n plugin =>\n // @ts-expect-error\n plugin.url !== pluginDefinition.url ||\n // @ts-expect-error\n plugin.umdUrl !== pluginDefinition.umdUrl ||\n // @ts-expect-error\n plugin.cjsUrl !== pluginDefinition.cjsUrl ||\n // @ts-expect-error\n plugin.esmUrl !== pluginDefinition.esmUrl,\n ),\n )\n\n getParent<any>(self).setPluginsUpdated(true)\n },\n\n /**\n * #action\n */\n setDefaultSessionConf(sessionConf: AnyConfigurationModel) {\n const newDefault =\n getParent<any>(self).session.name === sessionConf.name\n ? getSnapshot(sessionConf)\n : toJS(sessionConf)\n\n if (!newDefault.name) {\n throw new Error(`unable to set default session to ${newDefault.name}`)\n }\n\n self.defaultSession = cast(newDefault)\n },\n /**\n * #action\n */\n addInternetAccountConf(internetAccountConf: AnyConfigurationModel) {\n const { type } = internetAccountConf\n if (!type) {\n throw new Error(`unknown internetAccount type ${type}`)\n }\n const length = self.internetAccounts.push(internetAccountConf)\n return self.internetAccounts[length - 1]\n },\n /**\n * #action\n */\n deleteInternetAccountConf(configuration: AnyConfigurationModel) {\n const elt = self.internetAccounts.find(a => a.id === configuration.id)\n return self.internetAccounts.remove(elt)\n },\n }))\n}\n","import {\n AnyConfigurationSchemaType,\n ConfigurationSchema,\n} from '@jbrowse/core/configuration'\n\nimport { PluginDefinition } from '@jbrowse/core/PluginLoader'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport RpcManager from '@jbrowse/core/rpc/RpcManager'\nimport {\n FormatAboutConfigSchemaFactory,\n FormatDetailsConfigSchemaFactory,\n HierarchicalConfigSchemaFactory,\n} from '@jbrowse/product-core'\nimport { types } from 'mobx-state-tree'\n\n/**\n * #config JBrowseRootConfig\n * #category root\n *\n * this is a config model representing a config.json (for jbrowse-web) or\n * somefile.jbrowse (for jbrowse-desktop, where configs have the .jbrowse\n * extension)\n *\n * includes\n * - [FormatDetails](../formatdetails) for global (instead of per-track)\n * feature detail formatters\n * - [FormatAbout](../formatabout) for global (instead of per-track) about\n * track formatters\n * - [HierarchicalConfigSchema](../hierarchicalconfigschema) for track selector\n * configs\n *\n * also includes any pluginManager.pluginConfigurationSchemas(), so plugins\n * that have a configurationSchema field on their class are mixed into this\n * object\n */\nexport function JBrowseConfigF({\n pluginManager,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n assemblyConfigSchema: AnyConfigurationSchemaType\n}) {\n return types.model('JBrowseConfig', {\n configuration: ConfigurationSchema('Root', {\n /**\n * #slot configuration.rpc\n */\n rpc: RpcManager.configSchema,\n\n /**\n * #slot configuration.highResolutionScaling\n */\n highResolutionScaling: {\n type: 'number',\n defaultValue: 2,\n },\n\n formatDetails: FormatDetailsConfigSchemaFactory(),\n formatAbout: FormatAboutConfigSchemaFactory(),\n\n /*\n * #slot configuration.shareURL\n */\n shareURL: {\n type: 'string',\n defaultValue: 'https://share.jbrowse.org/api/v1/',\n },\n /**\n * #slot configuration.disableAnalytics\n */\n disableAnalytics: {\n type: 'boolean',\n defaultValue: false,\n },\n\n hierarchical: HierarchicalConfigSchemaFactory(),\n /**\n * #slot configuration.theme\n */\n theme: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot configuration.extraThemes\n */\n extraThemes: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot configuration.logoPath\n */\n logoPath: {\n type: 'fileLocation',\n defaultValue: { uri: '', locationType: 'UriLocation' },\n },\n ...pluginManager.pluginConfigurationSchemas(),\n }),\n /**\n * #slot\n * defines plugins of the format\n * ```typescript\n * type PluginDefinition=\n * { umdUrl: string, name:string } |\n * { url: string, name: string } |\n * { esmUrl: string } |\n * { cjsUrl: string } |\n * { umdLoc: { uri: string } } |\n * { esmLoc: { uri: string } } |\n * ```\n */\n plugins: types.array(types.frozen<PluginDefinition>()),\n /**\n * #slot\n * configuration of the assemblies in the instance, see BaseAssembly\n */\n assemblies: types.array(assemblyConfigSchema),\n /**\n * #slot\n * track configuration is an array of track config schemas. multiple\n * instances of a track can exist that use the same configuration\n */\n tracks: types.array(pluginManager.pluggableConfigSchemaType('track')),\n /**\n * #slot\n * configuration for internet accounts, see InternetAccounts\n */\n internetAccounts: types.array(\n pluginManager.pluggableConfigSchemaType('internet account'),\n ),\n /**\n * #slot\n * configuration for aggregate text search adapters (created by e.g.\n * jbrowse text-index, but can be a pluggable TextSearchAdapter type)\n */\n aggregateTextSearchAdapters: types.array(\n pluginManager.pluggableConfigSchemaType('text search adapter'),\n ),\n\n /**\n * #slot\n * configuration for connections\n */\n connections: types.array(\n pluginManager.pluggableConfigSchemaType('connection'),\n ),\n\n /**\n * #slot\n */\n defaultSession: types.optional(types.frozen(), {\n name: 'New Session',\n }),\n })\n}\n","import { ConfigurationSchema } from '@jbrowse/core/configuration'\n/**\n * #config FormatDetails\n * generally exists on the tracks in the config.json or as a 'session' config as\n * configuration.formatDetails\n */\nexport function FormatDetailsConfigSchemaFactory() {\n return ConfigurationSchema('FormatDetails', {\n /**\n * #slot configuration.formatDetails.feature\n */\n feature: {\n type: 'frozen',\n description: 'adds extra fields to the feature details',\n defaultValue: {},\n contextVariable: ['feature'],\n },\n /**\n * #slot configuration.formatDetails.subfeatures\n */\n subfeatures: {\n type: 'frozen',\n description: 'adds extra fields to the subfeatures of a feature',\n defaultValue: {},\n contextVariable: ['feature'],\n },\n /**\n * #slot configuration.formatDetails.depth\n */\n depth: {\n type: 'number',\n defaultValue: 2,\n description:\n 'depth to iterate the formatDetails->subfeatures callback on subfeatures (used for example to only apply the callback to the first layer of subfeatures)',\n },\n /**\n * #slot configuration.formatDetails.maxDepth\n */\n maxDepth: {\n type: 'number',\n defaultValue: 10000,\n description: 'hide subfeatures greater than a certain depth',\n },\n })\n}\n","import { ConfigurationSchema } from '@jbrowse/core/configuration'\n/**\n * #config FormatAbout\n * generally exists on the config.json or root config as configuration.formatAbout\n */\nexport function FormatAboutConfigSchemaFactory() {\n return ConfigurationSchema('FormatAbout', {\n /**\n * #slot configuration.formatAbout.config\n */\n config: {\n type: 'frozen',\n description: 'formats configuration object in about dialog',\n defaultValue: {},\n contextVariable: ['config'],\n },\n /**\n * #slot configuration.formatAbout.hideUris\n */\n\n hideUris: {\n type: 'boolean',\n defaultValue: false,\n },\n })\n}\n","import { ConfigurationSchema } from '@jbrowse/core/configuration'\n\n/**\n * #config HierarchicalConfigSchema\n * generally exists on the config.json or root config as configuration.hierarchical\n */\nexport function HierarchicalConfigSchemaFactory() {\n return ConfigurationSchema('hierarchical', {\n sort: ConfigurationSchema('hierarchicalSort', {\n /**\n * #slot configuration.hierarchical.sort.trackNames\n */\n trackNames: {\n type: 'boolean',\n defaultValue: false,\n },\n /**\n * #slot configuration.hierarchical.sort.categories\n */\n categories: {\n type: 'boolean',\n defaultValue: false,\n },\n }),\n defaultCollapsed: ConfigurationSchema('defaultCollapsed', {\n /**\n * #slot configuration.hierarchical.defaultCollapsed.categoryNames\n */\n categoryNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot configuration.hierarchical.defaultCollapsed.topLevelCategories\n */\n topLevelCategories: {\n type: 'boolean',\n defaultValue: false,\n },\n /**\n * #slot configuration.hierarchical.defaultCollapsed.subCategories\n */\n subCategories: {\n type: 'boolean',\n defaultValue: false,\n },\n }),\n })\n}\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport assemblyManagerFactory, {\n BaseAssemblyConfigSchema,\n} from '@jbrowse/core/assemblyManager'\nimport RpcManager from '@jbrowse/core/rpc/RpcManager'\nimport {\n IAnyType,\n Instance,\n SnapshotIn,\n cast,\n getSnapshot,\n isStateTreeNode,\n types,\n} from 'mobx-state-tree'\nimport TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'\n\n/**\n * #stateModel BaseRootModel\n * #category root\n * factory function for the Base-level root model shared by all products\n */\nexport function BaseRootModelFactory({\n pluginManager,\n jbrowseModelType,\n sessionModelType,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n jbrowseModelType: IAnyType\n sessionModelType: IAnyType\n assemblyConfigSchema: BaseAssemblyConfigSchema\n}) {\n return types\n .model('BaseRootModel', {\n /**\n * #property\n * `jbrowse` is a mapping of the config.json into the in-memory state\n * tree\n */\n jbrowse: jbrowseModelType,\n\n /**\n * #property\n * `session` encompasses the currently active state of the app, including\n * views open, tracks open in those views, etc.\n */\n session: types.maybe(sessionModelType),\n /**\n * #property\n */\n sessionPath: types.optional(types.string, ''),\n\n /**\n * #property\n */\n assemblyManager: types.optional(\n assemblyManagerFactory(assemblyConfigSchema, pluginManager),\n {},\n ),\n })\n .volatile(self => ({\n rpcManager: new RpcManager(\n pluginManager,\n self.jbrowse.configuration.rpc,\n {\n MainThreadRpcDriver: {},\n },\n ),\n\n adminMode: false,\n error: undefined as unknown,\n textSearchManager: new TextSearchManager(pluginManager),\n pluginManager,\n }))\n .actions(self => ({\n /**\n * #action\n */\n setError(error: unknown) {\n self.error = error\n },\n /**\n * #action\n */\n setSession(sessionSnapshot?: SnapshotIn<IAnyType>) {\n self.session = cast(sessionSnapshot)\n },\n /**\n * #action\n */\n setDefaultSession() {\n this.setSession(self.jbrowse.defaultSession)\n },\n /**\n * #action\n */\n setSessionPath(path: string) {\n self.sessionPath = path\n },\n /**\n * #action\n */\n renameCurrentSession(newName: string) {\n if (self.session) {\n const snapshot = JSON.parse(JSON.stringify(getSnapshot(self.session)))\n snapshot.name = newName\n this.setSession(snapshot)\n }\n },\n }))\n}\n\nexport type BaseRootModelType = ReturnType<typeof BaseRootModelFactory>\nexport type BaseRootModel = Instance<BaseRootModelType>\n\n/** Type guard for checking if something is a JB root model */\nexport function isRootModel(thing: unknown): thing is BaseRootModelType {\n return (\n isStateTreeNode(thing) &&\n 'session' in thing &&\n 'jbrowse' in thing &&\n 'assemblyManager' in thing\n )\n}\n","import {\n addDisposer,\n cast,\n getParent,\n types,\n Instance,\n IAnyType,\n} from 'mobx-state-tree'\nimport { when } from '../util'\nimport { reaction } from 'mobx'\nimport { readConfObject, AnyConfigurationModel } from '../configuration'\nimport assemblyFactory, { Assembly } from './assembly'\nimport PluginManager from '../PluginManager'\nimport RpcManager from '../rpc/RpcManager'\n\ntype AdapterConf = Record<string, unknown>\n\n/**\n * #stateModel AssemblyManager\n */\nfunction assemblyManagerFactory(conf: IAnyType, pm: PluginManager) {\n type Conf = Instance<typeof conf> // this is type any, try to narrow...\n return types\n .model({\n /**\n * #property\n * this is automatically managed by an autorun which looks in the parent\n * session.assemblies, session.sessionAssemblies, and\n * session.temporaryAssemblies\n */\n assemblies: types.array(assemblyFactory(conf, pm)),\n })\n .views(self => ({\n get assemblyNameMap() {\n const obj = {} as Record<string, Assembly>\n for (const assembly of self.assemblies) {\n for (const name of assembly.allAliases) {\n obj[name] = assembly\n }\n }\n return obj\n },\n }))\n .views(self => ({\n /**\n * #method\n */\n get(asmName: string) {\n return self.assemblyNameMap[asmName]\n },\n\n /**\n * #getter\n */\n get assemblyNamesList() {\n return this.assemblyList.map(asm => asm.name)\n },\n\n /**\n * #getter\n * looks at jbrowse.assemblies, session.sessionAssemblies, and\n * session.temporaryAssemblies to load from\n */\n get assemblyList() {\n // name is the explicit identifier and can be accessed without getConf,\n // hence the union with {name:string}\n const {\n jbrowse: { assemblies },\n session: { sessionAssemblies = [], temporaryAssemblies = [] } = {},\n } = getParent<any>(self)\n return [\n ...assemblies,\n ...sessionAssemblies,\n ...temporaryAssemblies,\n ] as AnyConfigurationModel[]\n },\n\n get rpcManager(): RpcManager {\n return getParent<any>(self).rpcManager\n },\n }))\n .views(self => ({\n /**\n * #method\n * use this method instead of assemblyManager.get(assemblyName)\n * to get an assembly with regions loaded\n */\n async waitForAssembly(assemblyName: string) {\n if (!assemblyName) {\n throw new Error('no assembly name supplied to waitForAssembly')\n }\n let assembly = self.get(assemblyName)\n if (!assembly) {\n try {\n await when(() => Boolean(self.get(assemblyName)), { timeout: 1000 })\n assembly = self.get(assemblyName)\n } catch (e) {\n // ignore\n }\n }\n\n if (!assembly) {\n return undefined\n }\n await assembly.load()\n await when(\n () =>\n !!(assembly.regions && assembly.refNameAliases) || !!assembly.error,\n )\n if (assembly.error) {\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n throw assembly.error\n }\n return assembly\n },\n\n /**\n * #method\n */\n async getRefNameMapForAdapter(\n adapterConf: AdapterConf,\n assemblyName: string | undefined,\n opts: { signal?: AbortSignal; sessionId: string },\n ) {\n if (assemblyName) {\n const asm = await this.waitForAssembly(assemblyName)\n return asm?.getRefNameMapForAdapter(adapterConf, opts)\n }\n return {}\n },\n\n /**\n * #method\n */\n async getReverseRefNameMapForAdapter(\n adapterConf: AdapterConf,\n assemblyName: string | undefined,\n opts: { signal?: AbortSignal; sessionId: string },\n ) {\n if (assemblyName) {\n const asm = await this.waitForAssembly(assemblyName)\n return asm?.getReverseRefNameMapForAdapter(adapterConf, opts)\n }\n return {}\n },\n\n /**\n * #method\n */\n isValidRefName(refName: string, assemblyName: string) {\n const assembly = self.get(assemblyName)\n if (assembly) {\n return assembly.isValidRefName(refName)\n }\n throw new Error(\n `Failed to look up refName ${refName} on ${assemblyName} because assembly does not exist`,\n )\n },\n }))\n .actions(self => ({\n afterAttach() {\n addDisposer(\n self,\n reaction(\n () => self.assemblyList,\n assemblyConfs => {\n self.assemblies.forEach(asm => {\n if (!asm.configuration) {\n this.removeAssembly(asm)\n }\n })\n assemblyConfs.forEach(conf => {\n if (\n !self.assemblies.some(\n a => a.name === readConfObject(conf, 'name'),\n )\n ) {\n this.addAssembly(conf)\n }\n })\n },\n { fireImmediately: true, name: 'assemblyManagerAfterAttach' },\n ),\n )\n },\n\n /**\n * #action\n * private: you would generally want to add to manipulate\n * jbrowse.assemblies, session.sessionAssemblies, or\n * session.temporaryAssemblies instead of using this directly\n */\n removeAssembly(asm: Assembly) {\n self.assemblies.remove(asm)\n },\n\n /**\n * #action\n * private: you would generally want to add to manipulate\n * jbrowse.assemblies, session.sessionAssemblies, or\n * session.temporaryAssemblies instead of using this directly\n *\n * this can take an active instance of an assembly, in which case it is\n * referred to, or it can take an identifier e.g. assembly name, which is\n * used as a reference. snapshots cannot be used\n */\n addAssembly(configuration: Conf) {\n self.assemblies.push({ configuration })\n },\n\n /**\n * #action\n * private: you would generally want to add to manipulate\n * jbrowse.assemblies, session.sessionAssemblies, or\n * session.temporaryAssemblies instead of using this directly\n */\n replaceAssembly(idx: number, configuration: Conf) {\n self.assemblies[idx] = cast({ configuration })\n },\n }))\n}\n\nexport default assemblyManagerFactory\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport { UriLocation } from '@jbrowse/core/util'\nimport { autorun } from 'mobx'\nimport { Instance, addDisposer, types } from 'mobx-state-tree'\nimport { BaseRootModel } from './BaseRootModel'\n\n/**\n * #stateModel InternetAccountsMixin\n * #category root\n */\nexport function InternetAccountsRootModelMixin(pluginManager: PluginManager) {\n return types\n .model({\n /**\n * #property\n */\n internetAccounts: types.array(\n pluginManager.pluggableMstType('internet account', 'stateModel'),\n ),\n })\n .actions(self => ({\n /**\n * #action\n */\n initializeInternetAccount(\n internetAccountConfig: AnyConfigurationModel,\n initialSnapshot = {},\n ) {\n const internetAccountType = pluginManager.getInternetAccountType(\n internetAccountConfig.type,\n )\n if (!internetAccountType) {\n throw new Error(\n `unknown internet account type ${internetAccountConfig.type}`,\n )\n }\n\n const length = self.internetAccounts.push({\n ...initialSnapshot,\n type: internetAccountConfig.type,\n configuration: internetAccountConfig,\n })\n return self.internetAccounts[length - 1]\n },\n\n /**\n * #action\n */\n createEphemeralInternetAccount(\n internetAccountId: string,\n initialSnapshot: Record<string, unknown>,\n url: string,\n ) {\n let hostUri: string | undefined\n\n try {\n hostUri = new URL(url).origin\n } catch (e) {\n // ignore\n }\n const internetAccountSplit = internetAccountId.split('-')\n const configuration = {\n type: internetAccountSplit[0]!,\n internetAccountId: internetAccountId,\n name: internetAccountSplit.slice(1).join('-'),\n description: '',\n domains: hostUri ? [hostUri] : [],\n }\n const type = pluginManager.getInternetAccountType(configuration.type)!\n const internetAccount = type.stateModel.create({\n ...initialSnapshot,\n type: configuration.type,\n configuration,\n })\n self.internetAccounts.push(internetAccount)\n return internetAccount\n },\n /**\n * #action\n */\n findAppropriateInternetAccount(location: UriLocation) {\n // find the existing account selected from menu\n const selectedId = location.internetAccountId\n if (selectedId) {\n const selectedAccount = self.internetAccounts.find(account => {\n return account.internetAccountId === selectedId\n })\n if (selectedAccount) {\n return selectedAccount\n }\n }\n\n // if no existing account or not found, try to find working account\n for (const account of self.internetAccounts) {\n const handleResult = account.handlesLocation(location)\n if (handleResult) {\n return account\n }\n }\n\n // if still no existing account, create ephemeral config to use\n return selectedId\n ? this.createEphemeralInternetAccount(selectedId, {}, location.uri)\n : null\n },\n }))\n .actions(self => ({\n afterCreate() {\n addDisposer(\n self,\n autorun(() => {\n const { jbrowse } = self as typeof self & BaseRootModel\n jbrowse.internetAccounts.forEach(self.initializeInternetAccount)\n }),\n )\n },\n }))\n}\n\nexport type RootModelWithInternetAccountsType = ReturnType<\n typeof InternetAccountsRootModelMixin\n>\nexport type RootModelWithInternetAccounts =\n Instance<RootModelWithInternetAccountsType>\n","import TimeTraveller from '@jbrowse/core/util/TimeTraveller'\nimport type { BaseRootModel } from '@jbrowse/product-core'\nimport { autorun } from 'mobx'\nimport { addDisposer, types } from 'mobx-state-tree'\n\n/**\n * #stateModel HistoryManagementMixin\n * #category root\n */\nexport function HistoryManagementMixin() {\n return types\n .model({\n /**\n * #property\n * used for undo/redo\n */\n history: types.optional(TimeTraveller, { targetPath: '../session' }),\n })\n .actions(self => ({\n afterCreate() {\n document.addEventListener('keydown', e => {\n if (\n self.history.canRedo &&\n // ctrl+shift+z or cmd+shift+z\n (((e.ctrlKey || e.metaKey) && e.shiftKey && e.code === 'KeyZ') ||\n // ctrl+y\n (e.ctrlKey && !e.shiftKey && e.code === 'KeyY')) &&\n document.activeElement?.tagName.toUpperCase() !== 'INPUT'\n ) {\n self.history.redo()\n }\n if (\n self.history.canUndo &&\n // ctrl+z or cmd+z\n (e.ctrlKey || e.metaKey) &&\n !e.shiftKey &&\n e.code === 'KeyZ' &&\n document.activeElement?.tagName.toUpperCase() !== 'INPUT'\n ) {\n self.history.undo()\n }\n })\n addDisposer(\n self,\n autorun(() => {\n const { session } = self as typeof self & BaseRootModel\n if (session) {\n // we use a specific initialization routine after session is\n // created to get it to start tracking itself sort of related\n // issue here\n // https://github.com/mobxjs/mobx-state-tree/issues/1089#issuecomment-441207911\n self.history.initialize()\n }\n }),\n )\n },\n }))\n}\n","import { MenuItem } from '@jbrowse/core/ui/Menu'\nimport { types } from 'mobx-state-tree'\n\nexport interface Menu {\n label: string\n menuItems: MenuItem[]\n}\n\n/**\n * #stateModel RootAppMenuMixin\n */\nexport function RootAppMenuMixin() {\n return types.model({}).actions(s => {\n const self = s as { menus: Menu[] }\n return {\n /**\n * #action\n */\n setMenus(newMenus: Menu[]) {\n self.menus = newMenus\n },\n /**\n * #action\n * Add a top-level menu\n *\n * @param menuName - Name of the menu to insert.\n *\n * @returns The new length of the top-level menus array\n */\n appendMenu(menuName: string) {\n return self.menus.push({ label: menuName, menuItems: [] })\n },\n /**\n * #action\n * Insert a top-level menu\n *\n * @param menuName - Name of the menu to insert.\n *\n * @param position - Position to insert menu. If negative, counts from th\n * end, e.g. `insertMenu('My Menu', -1)` will insert the menu as the\n * second-to-last one.\n *\n * @returns The new length of the top-level menus array\n */\n insertMenu(menuName: string, position: number) {\n self.menus.splice(\n (position < 0 ? self.menus.length : 0) + position,\n 0,\n {\n label: menuName,\n menuItems: [],\n },\n )\n return self.menus.length\n },\n /**\n * #action\n * Add a menu item to a top-level menu\n *\n * @param menuName - Name of the top-level menu to append to.\n *\n * @param menuItem - Menu item to append.\n *\n * @returns The new length of the menu\n */\n appendToMenu(menuName: string, menuItem: MenuItem) {\n const menu = self.menus.find(m => m.label === menuName)\n if (!menu) {\n self.menus.push({ label: menuName, menuItems: [menuItem] })\n return 1\n }\n return menu.menuItems.push(menuItem)\n },\n /**\n * #action\n * Insert a menu item into a top-level menu\n *\n * @param menuName - Name of the top-level menu to insert into\n *\n * @param menuItem - Menu item to insert\n *\n * @param position - Position to insert menu item. If negative, counts\n * from the end, e.g. `insertMenu('My Menu', -1)` will insert the menu as\n * the second-to-last one.\n *\n * @returns The new length of the menu\n */\n insertInMenu(menuName: string, menuItem: MenuItem, position: number) {\n const menu = self.menus.find(m => m.label === menuName)\n if (!menu) {\n self.menus.push({ label: menuName, menuItems: [menuItem] })\n return 1\n }\n const insertPosition =\n position < 0 ? menu.menuItems.length + position : position\n menu.menuItems.splice(insertPosition, 0, menuItem)\n return menu.menuItems.length\n },\n /**\n * #action\n * Add a menu item to a sub-menu\n *\n * @param menuPath - Path to the sub-menu to add to, starting with the\n * top-level menu (e.g. `['File', 'Insert']`).\n *\n * @param menuItem - Menu item to append.\n *\n * @returns The new length of the sub-menu\n */\n appendToSubMenu(menuPath: string[], menuItem: MenuItem) {\n let topMenu = self.menus.find(m => m.label === menuPath[0])\n if (!topMenu) {\n const idx = this.appendMenu(menuPath[0]!)\n topMenu = self.menus[idx - 1]!\n }\n let { menuItems: subMenu } = topMenu\n const pathSoFar = [menuPath[0]]\n menuPath.slice(1).forEach(menuName => {\n pathSoFar.push(menuName)\n let sm = subMenu.find(mi => 'label' in mi && mi.label === menuName)\n if (!sm) {\n const idx = subMenu.push({ label: menuName, subMenu: [] })\n sm = subMenu[idx - 1]!\n }\n if (!('subMenu' in sm)) {\n throw new Error(\n `\"${menuName}\" in path \"${pathSoFar}\" is not a subMenu`,\n )\n }\n subMenu = sm.subMenu\n })\n return subMenu.push(menuItem)\n },\n /**\n * #action\n * Insert a menu item into a sub-menu\n *\n * @param menuPath - Path to the sub-menu to add to, starting with the\n * top-level menu (e.g. `['File', 'Insert']`).\n *\n * @param menuItem - Menu item to insert.\n *\n * @param position - Position to insert menu item. If negative, counts\n * from the end, e.g. `insertMenu('My Menu', -1)` will insert the menu as\n * the second-to-last one.\n *\n * @returns The new length of the sub-menu\n */\n insertInSubMenu(\n menuPath: string[],\n menuItem: MenuItem,\n position: number,\n ) {\n let topMenu = self.menus.find(m => m.label === menuPath[0])\n if (!topMenu) {\n const idx = this.appendMenu(menuPath[0]!)\n topMenu = self.menus[idx - 1]!\n }\n let { menuItems: subMenu } = topMenu\n const pathSoFar = [menuPath[0]]\n menuPath.slice(1).forEach(menuName => {\n pathSoFar.push(menuName)\n let sm = subMenu.find(mi => 'label' in mi && mi.label === menuName)\n if (!sm) {\n const idx = subMenu.push({ label: menuName, subMenu: [] })\n sm = subMenu[idx - 1]!\n }\n if (!('subMenu' in sm)) {\n throw new Error(\n `\"${menuName}\" in path \"${pathSoFar}\" is not a subMenu`,\n )\n }\n subMenu = sm.subMenu\n })\n subMenu.splice(position, 0, menuItem)\n return subMenu.length\n },\n }\n })\n}\n","/** MST props, views, actions, etc related to managing connections */\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport {\n TrackViewModel,\n getContainingView,\n isSessionModelWithWidgets,\n} from '@jbrowse/core/util'\nimport {\n IAnyStateTreeNode,\n Instance,\n getMembers,\n getParent,\n getSnapshot,\n getType,\n isModelType,\n isReferenceType,\n types,\n walk,\n} from 'mobx-state-tree'\n\nimport type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes'\n// locals\nimport { isBaseSession } from './BaseSession'\n\nexport interface ReferringNode {\n node: IAnyStateTreeNode\n key: string\n}\n\n/**\n * #stateModel ReferenceManagementSessionMixin\n */\nexport function ReferenceManagementSessionMixin(_pluginManager: PluginManager) {\n return types\n .model('ReferenceManagementSessionMixin', {})\n .views(self => ({\n /**\n * #method\n * See if any MST nodes currently have a types.reference to this object.\n *\n * @param object - object\n * @returns An array where the first element is the node referring\n * to the object and the second element is they property name the node is\n * using to refer to the object\n */\n getReferring(object: IAnyStateTreeNode) {\n const refs: ReferringNode[] = []\n walk(getParent(self), node => {\n if (isModelType(getType(node))) {\n const members = getMembers(node)\n Object.entries(members.properties).forEach(([key, value]) => {\n if (isReferenceType(value) && node[key] === object) {\n refs.push({ node, key })\n }\n })\n }\n })\n return refs\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n removeReferring(\n referring: ReferringNode[],\n track: BaseTrackConfig,\n callbacks: ((arg: string) => void)[],\n dereferenceTypeCount: Record<string, number>,\n ) {\n referring.forEach(({ node }) => {\n let dereferenced = false\n try {\n // If a view is referring to the track config, remove the track\n // from the view\n const type = 'open track(s)'\n const view = getContainingView(node) as TrackViewModel\n callbacks.push(() => {\n view.hideTrack(track.trackId)\n })\n dereferenced = true\n if (!dereferenceTypeCount[type]) {\n dereferenceTypeCount[type] = 0\n }\n dereferenceTypeCount[type] += 1\n } catch (err1) {\n // ignore\n }\n\n if (isSessionModelWithWidgets(self) && self.widgets.has(node.id)) {\n // If a configuration editor widget has the track config\n // open, close the widget\n const type = 'configuration editor widget(s)'\n if (isSessionModelWithWidgets(self)) {\n callbacks.push(() => {\n self.hideWidget(node)\n })\n }\n dereferenced = true\n if (!dereferenceTypeCount[type]) {\n dereferenceTypeCount[type] = 0\n }\n dereferenceTypeCount[type] += 1\n }\n if (!dereferenced) {\n throw new Error(\n `Error when closing this connection, the following node is still referring to a track configuration: ${JSON.stringify(\n getSnapshot(node),\n )}`,\n )\n }\n })\n },\n }))\n}\n\n/** Session mixin MST type for a session that manages multiple views */\nexport type SessionWithReferenceManagementType = ReturnType<\n typeof ReferenceManagementSessionMixin\n>\n\n/** Instance of a session with MST reference management (`getReferring()`, `removeReferring()`) */\nexport type SessionWithReferenceManagement =\n Instance<SessionWithReferenceManagementType>\n\n/** Type guard for SessionWithReferenceManagement */\nexport function isSessionWithReferenceManagement(\n thing: IAnyStateTreeNode,\n): thing is SessionWithReferenceManagement {\n return (\n isBaseSession(thing) &&\n 'getReferring' in thing &&\n typeof thing.getReferring === 'function' &&\n 'removeReferring' in thing &&\n typeof thing.removeReferring === 'function'\n )\n}\n","import {\n IAnyStateTreeNode,\n Instance,\n addDisposer,\n isAlive,\n types,\n} from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util'\nimport { autorun } from 'mobx'\nimport {\n AnyConfigurationModel,\n isConfigurationModel,\n} from '@jbrowse/core/configuration'\nimport { isBaseSession } from './BaseSession'\n\nconst minDrawerWidth = 128\n\n/**\n * #stateModel DrawerWidgetSessionMixin\n */\nexport function DrawerWidgetSessionMixin(pluginManager: PluginManager) {\n const widgetStateModelType = pluginManager.pluggableMstType(\n 'widget',\n 'stateModel',\n )\n type WidgetStateModel = Instance<typeof widgetStateModelType>\n return types\n .model({\n /**\n * #property\n */\n drawerPosition: types.optional(\n types.string,\n () => localStorageGetItem('drawerPosition') || 'right',\n ),\n /**\n * #property\n */\n drawerWidth: types.optional(\n types.refinement(types.integer, width => width >= minDrawerWidth),\n 384,\n ),\n /**\n * #property\n */\n widgets: types.map(widgetStateModelType),\n /**\n * #property\n */\n activeWidgets: types.map(types.safeReference(widgetStateModelType)),\n\n /**\n * #property\n */\n minimized: types.optional(types.boolean, false),\n })\n .views(self => ({\n /**\n * #getter\n */\n get visibleWidget() {\n if (isAlive(self)) {\n // returns most recently added item in active widgets\n return [...self.activeWidgets.values()][self.activeWidgets.size - 1]\n }\n return undefined\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setDrawerPosition(arg: string) {\n self.drawerPosition = arg\n localStorage.setItem('drawerPosition', arg)\n },\n\n /**\n * #action\n */\n updateDrawerWidth(drawerWidth: number) {\n if (drawerWidth === self.drawerWidth) {\n return self.drawerWidth\n }\n let newDrawerWidth = drawerWidth\n if (newDrawerWidth < minDrawerWidth) {\n newDrawerWidth = minDrawerWidth\n }\n self.drawerWidth = newDrawerWidth\n return newDrawerWidth\n },\n\n /**\n * #action\n */\n resizeDrawer(distance: number) {\n if (self.drawerPosition === 'left') {\n distance *= -1\n }\n const oldDrawerWidth = self.drawerWidth\n const newDrawerWidth = this.updateDrawerWidth(oldDrawerWidth - distance)\n return oldDrawerWidth - newDrawerWidth\n },\n\n /**\n * #action\n */\n addWidget(\n typeName: string,\n id: string,\n initialState = {},\n conf?: unknown,\n ) {\n const typeDefinition = pluginManager.getElementType('widget', typeName)\n if (!typeDefinition) {\n throw new Error(`unknown widget type ${typeName}`)\n }\n const data = {\n ...initialState,\n id,\n type: typeName,\n configuration: conf || { type: typeName },\n }\n self.widgets.set(id, data)\n return self.widgets.get(id)\n },\n\n /**\n * #action\n */\n showWidget(widget: WidgetStateModel) {\n if (self.activeWidgets.has(widget.id)) {\n self.activeWidgets.delete(widget.id)\n }\n self.activeWidgets.set(widget.id, widget)\n self.minimized = false\n },\n\n /**\n * #action\n */\n hasWidget(widget: WidgetStateModel) {\n return self.activeWidgets.has(widget.id)\n },\n\n /**\n * #action\n */\n hideWidget(widget: WidgetStateModel) {\n self.activeWidgets.delete(widget.id)\n },\n\n /**\n * #action\n */\n minimizeWidgetDrawer() {\n self.minimized = true\n },\n /**\n * #action\n */\n showWidgetDrawer() {\n self.minimized = false\n },\n /**\n * #action\n */\n hideAllWidgets() {\n self.activeWidgets.clear()\n },\n\n /**\n * #action\n * opens a configuration editor to configure the given thing,\n * and sets the current task to be configuring it\n * @param configuration -\n */\n editConfiguration(configuration: AnyConfigurationModel) {\n if (!isConfigurationModel(configuration)) {\n throw new Error(\n 'must pass a configuration model to editConfiguration',\n )\n }\n const editor = this.addWidget(\n 'ConfigurationEditorWidget',\n 'configEditor',\n { target: configuration },\n )\n this.showWidget(editor)\n },\n\n afterAttach() {\n addDisposer(\n self,\n autorun(() => {\n localStorageSetItem('drawerPosition', self.drawerPosition)\n }),\n )\n },\n }))\n}\n\n/** Session mixin MST type for a session that manages drawer widgets */\nexport type SessionWithDrawerWidgetsType = ReturnType<\n typeof DrawerWidgetSessionMixin\n>\n\n/** Instance of a session that manages drawer widgets */\nexport type SessionWithDrawerWidgets = Instance<SessionWithDrawerWidgetsType>\n\n/** Type guard for SessionWithDrawerWidgets */\nexport function isSessionWithDrawerWidgets(\n session: IAnyStateTreeNode,\n): session is SessionWithDrawerWidgets {\n return (\n isBaseSession(session) &&\n 'widgets' in session &&\n 'drawerPosition' in session\n )\n}\n","import React, { lazy } from 'react'\nimport { types } from 'mobx-state-tree'\nimport { observable } from 'mobx'\n\n// locals\nimport { NotificationLevel, SnackAction } from '../util/types'\n\n// icons\nimport Report from '@mui/icons-material/Report'\n\n// lazies\nconst ErrorMessageStackTraceDialog = lazy(\n () => import('@jbrowse/core/ui/ErrorMessageStackTraceDialog'),\n)\n\nexport interface SnackbarMessage {\n message: string\n level?: NotificationLevel\n action?: SnackAction\n}\n\n/**\n * #stateModel SnackbarModel\n * #category session\n */\nexport default function SnackbarModel() {\n return types\n .model({})\n .volatile(() => ({\n /**\n * #volatile\n */\n snackbarMessages: observable.array<SnackbarMessage>(),\n }))\n .views(self => ({\n /**\n * #getter\n */\n get snackbarMessageSet() {\n return new Map(self.snackbarMessages.map(s => [s.message, s]))\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n notify(message: string, level?: NotificationLevel, action?: SnackAction) {\n this.pushSnackbarMessage(message, level, action)\n if (level === 'info' || level === 'success') {\n setTimeout(() => {\n this.removeSnackbarMessage(message)\n }, 5000)\n }\n },\n\n /**\n * #action\n */\n notifyError(errorMessage: string, error?: unknown, extra?: unknown) {\n this.notify(errorMessage, 'error', {\n name: <Report />,\n onClick: () => {\n // @ts-expect-error\n self.queueDialog((onClose: () => void) => [\n ErrorMessageStackTraceDialog,\n {\n onClose,\n error,\n extra,\n },\n ])\n },\n })\n },\n /**\n * #action\n */\n pushSnackbarMessage(\n message: string,\n level?: NotificationLevel,\n action?: SnackAction,\n ) {\n if (action || !self.snackbarMessageSet.has(message)) {\n self.snackbarMessages.push({ message, level, action })\n }\n },\n /**\n * #action\n */\n popSnackbarMessage() {\n return self.snackbarMessages.pop()\n },\n /**\n * #action\n */\n removeSnackbarMessage(message: string) {\n const element = self.snackbarMessageSet.get(message)\n if (element !== undefined) {\n self.snackbarMessages.remove(element)\n }\n },\n }))\n}\n","import { lazy } from 'react'\nimport clone from 'clone'\nimport { PluginDefinition } from '@jbrowse/core/PluginLoader'\nimport {\n getConf,\n AnyConfigurationModel,\n readConfObject,\n AnyConfiguration,\n} from '@jbrowse/core/configuration'\nimport { AssemblyManager, JBrowsePlugin } from '@jbrowse/core/util/types'\nimport { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util'\nimport { autorun } from 'mobx'\nimport {\n addDisposer,\n cast,\n getParent,\n getSnapshot,\n types,\n SnapshotIn,\n Instance,\n} from 'mobx-state-tree'\nimport TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport {\n DialogQueueSessionMixin,\n DrawerWidgetSessionMixin,\n MultipleViewsSessionMixin,\n ReferenceManagementSessionMixin,\n SessionTracksManagerSessionMixin,\n ThemeManagerSessionMixin,\n} from '@jbrowse/product-core'\nimport {\n AppFocusMixin,\n SessionAssembliesMixin,\n TemporaryAssembliesMixin,\n} from '@jbrowse/app-core'\nimport { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes'\nimport { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'\nimport { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig'\nimport SnackbarModel from '@jbrowse/core/ui/SnackbarModel'\n\n// icons\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport CopyIcon from '@mui/icons-material/FileCopy'\nimport DeleteIcon from '@mui/icons-material/Delete'\nimport InfoIcon from '@mui/icons-material/Info'\n\n// locals\nimport { WebSessionConnectionsMixin } from '../SessionConnections'\n\n// lazies\nconst AboutDialog = lazy(() => import('./AboutDialog'))\n\n/**\n * #stateModel BaseWebSession\n * used for \"web based\" products, including jbrowse-web and react-app\n * composed of\n * - [ReferenceManagementSessionMixin](../referencemanagementsessionmixin)\n * - [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin)\n * - [DialogQueueSessionMixin](../dialogqueuesessionmixin)\n * - [ThemeManagerSessionMixin](../thememanagersessionmixin)\n * - [MultipleViewsSessionMixin](../multipleviewssessionmixin)\n * - [SessionTracksManagerSessionMixin](../sessiontracksmanagersessionmixin)\n * - [SessionAssembliesMixin](../sessionassembliesmixin)\n * - [TemporaryAssembliesMixin](../temporaryassembliesmixin)\n * - [WebSessionConnectionsMixin](../websessionconnectionsmixin)\n * - [AppFocusMixin](../appfocusmixin)\n */\nexport function BaseWebSession({\n pluginManager,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n assemblyConfigSchema: BaseAssemblyConfigSchema\n}) {\n const sessionModel = types\n .compose(\n 'WebCoreSessionModel',\n types.compose(\n 'WebCoreSessionModelGroupA',\n ReferenceManagementSessionMixin(pluginManager),\n DrawerWidgetSessionMixin(pluginManager),\n DialogQueueSessionMixin(pluginManager),\n ThemeManagerSessionMixin(pluginManager),\n MultipleViewsSessionMixin(pluginManager),\n ),\n types.compose(\n 'WebCoreSessionModelGroupB',\n SessionTracksManagerSessionMixin(pluginManager),\n SessionAssembliesMixin(pluginManager, assemblyConfigSchema),\n TemporaryAssembliesMixin(pluginManager, assemblyConfigSchema),\n WebSessionConnectionsMixin(pluginManager),\n AppFocusMixin(),\n SnackbarModel(),\n ),\n )\n .props({\n /**\n * #property\n */\n margin: 0,\n /**\n * #property\n */\n sessionPlugins: types.array(types.frozen()),\n })\n .volatile((/* self */) => ({\n /**\n * #volatile\n */\n sessionThemeName: localStorageGetItem('themeName') || 'default',\n /**\n * #volatile\n * this is the current \"task\" that is being performed in the UI.\n * this is usually an object of the form\n * `{ taskName: \"configure\", target: thing_being_configured }`\n */\n task: undefined,\n }))\n .views(self => ({\n /**\n * #getter\n */\n get tracks(): AnyConfigurationModel[] {\n return [...self.sessionTracks, ...self.jbrowse.tracks]\n },\n /**\n * #getter\n */\n get root() {\n return getParent<any>(self)\n },\n /**\n * #getter\n * list of sessionAssemblies and jbrowse config assemblies, does not\n * include temporaryAssemblies. basically the list to be displayed in a\n * AssemblySelector dropdown\n */\n get assemblies(): Instance<BaseAssemblyConfigSchema[]> {\n return [...self.jbrowse.assemblies, ...self.sessionAssemblies]\n },\n /**\n * #getter\n * list of config connections and session connections\n */\n get connections(): BaseConnectionConfigModel[] {\n return [...self.jbrowse.connections, ...self.sessionConnections]\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setName(str: string) {\n self.name = str\n },\n }))\n\n .views(self => ({\n /**\n * #getter\n * list of sessionAssemblies and jbrowse config assemblies, does not\n * include temporaryAssemblies. basically the list to be displayed in a\n * AssemblySelector dropdown\n */\n get assemblyNames() {\n return self.assemblies.map(f => readConfObject(f, 'name') as string)\n },\n /**\n * #getter\n */\n get version() {\n return self.root.version\n },\n /**\n * #getter\n */\n get shareURL() {\n return getConf(self.jbrowse, 'shareURL')\n },\n /**\n * #getter\n */\n get textSearchManager(): TextSearchManager {\n return self.root.textSearchManager\n },\n /**\n * #getter\n */\n get assemblyManager(): AssemblyManager {\n return self.root.assemblyManager\n },\n /**\n * #getter\n */\n get savedSessions() {\n return self.root.savedSessions\n },\n /**\n * #getter\n */\n get previousAutosaveId() {\n return self.root.previousAutosaveId\n },\n /**\n * #getter\n */\n get savedSessionNames() {\n return self.root.savedSessionNames\n },\n /**\n * #getter\n */\n get history() {\n return self.root.history\n },\n /**\n * #getter\n */\n get menus() {\n return self.root.menus\n },\n /**\n * #method\n */\n renderProps() {\n return {\n theme: self.theme,\n highResolutionScaling: getConf(self, 'highResolutionScaling'),\n }\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n addAssemblyConf(conf: AnyConfiguration) {\n self.jbrowse.addAssemblyConf(conf)\n },\n /**\n * #action\n */\n addSessionPlugin(plugin: JBrowsePlugin) {\n if (self.sessionPlugins.some(p => p.name === plugin.name)) {\n throw new Error('session plugin cannot be installed twice')\n }\n self.sessionPlugins.push(plugin)\n self.root.setPluginsUpdated(true)\n },\n\n /**\n * #action\n */\n removeSessionPlugin(pluginDefinition: PluginDefinition) {\n self.sessionPlugins = cast(\n self.sessionPlugins.filter(\n plugin =>\n // @ts-expect-error\n plugin.url !== pluginDefinition.url ||\n // @ts-expect-error\n plugin.umdUrl !== pluginDefinition.umdUrl ||\n // @ts-expect-error\n plugin.cjsUrl !== pluginDefinition.cjsUrl ||\n // @ts-expect-error\n plugin.esmUrl !== pluginDefinition.esmUrl,\n ),\n )\n getParent<any>(self).setPluginsUpdated(true)\n },\n\n /**\n * #action\n */\n addSavedSession(sessionSnapshot: SnapshotIn<typeof self>) {\n return self.root.addSavedSession(sessionSnapshot)\n },\n\n /**\n * #action\n */\n removeSavedSession(sessionSnapshot: { name: string }) {\n return self.root.removeSavedSession(sessionSnapshot)\n },\n\n /**\n * #action\n */\n renameCurrentSession(sessionName: string) {\n return self.root.renameCurrentSession(sessionName)\n },\n\n /**\n * #action\n */\n duplicateCurrentSession() {\n return self.root.duplicateCurrentSession()\n },\n /**\n * #action\n */\n activateSession(sessionName: string) {\n return self.root.activateSession(sessionName)\n },\n\n /**\n * #action\n */\n setDefaultSession() {\n return self.root.setDefaultSession()\n },\n\n /**\n * #action\n */\n saveSessionToLocalStorage() {\n return self.root.saveSessionToLocalStorage()\n },\n\n /**\n * #action\n */\n loadAutosaveSession() {\n return self.root.loadAutosaveSession()\n },\n\n /**\n * #action\n */\n setSession(sessionSnapshot: SnapshotIn<typeof self>) {\n return self.root.setSession(sessionSnapshot)\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n editTrackConfiguration(configuration: AnyConfigurationModel) {\n const { adminMode, sessionTracks } = self\n if (!adminMode && !sessionTracks.includes(configuration)) {\n throw new Error(\"Can't edit the configuration of a non-session track\")\n }\n self.editConfiguration(configuration)\n },\n }))\n .views(self => ({\n /**\n * #method\n */\n getTrackActionMenuItems(config: BaseTrackConfig) {\n const { adminMode, sessionTracks } = self\n const canEdit =\n adminMode || sessionTracks.find(t => t.trackId === config.trackId)\n\n // disable if it is a reference sequence track\n const isRefSeq = config.type === 'ReferenceSequenceTrack'\n return [\n {\n label: 'About track',\n priority: 1002,\n onClick: () => {\n self.queueDialog(handleClose => [\n AboutDialog,\n { config, handleClose },\n ])\n },\n icon: InfoIcon,\n },\n {\n label: 'Settings',\n priority: 1001,\n disabled: !canEdit,\n onClick: () => {\n self.editTrackConfiguration(config)\n },\n icon: SettingsIcon,\n },\n {\n label: 'Delete track',\n priority: 1000,\n disabled: !canEdit || isRefSeq,\n onClick: () => self.deleteTrackConf(config),\n icon: DeleteIcon,\n },\n {\n label: 'Copy track',\n priority: 999,\n disabled: isRefSeq,\n onClick: () => {\n interface Display {\n displayId: string\n }\n const snap = clone(getSnapshot(config)) as {\n [key: string]: unknown\n displays: Display[]\n }\n const now = Date.now()\n snap.trackId += `-${now}`\n snap.displays.forEach(display => {\n display.displayId += `-${now}`\n })\n // the -sessionTrack suffix to trackId is used as metadata for\n // the track selector to store the track in a special category,\n // and default category is also cleared\n if (!self.adminMode) {\n snap.trackId += '-sessionTrack'\n snap.category = undefined\n }\n snap.name += ' (copy)'\n self.addTrackConf(snap)\n },\n icon: CopyIcon,\n },\n ]\n },\n }))\n .actions(self => ({\n afterAttach() {\n addDisposer(\n self,\n autorun(() => {\n localStorageSetItem('drawerPosition', self.drawerPosition)\n localStorageSetItem('themeName', self.themeName)\n }),\n )\n },\n }))\n\n const extendedSessionModel = pluginManager.evaluateExtensionPoint(\n 'Core-extendSession',\n sessionModel,\n ) as typeof sessionModel\n\n return types.snapshotProcessor(extendedSessionModel, {\n // @ts-expect-error\n preProcessor(snapshot) {\n // @ts-expect-error\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const { connectionInstances, ...rest } = snapshot || {}\n // connectionInstances schema changed from object to an array, so any\n // old connectionInstances as object is in snapshot, filter it out\n // https://github.com/GMOD/jbrowse-components/issues/1903\n return !Array.isArray(connectionInstances) ? rest : snapshot\n },\n })\n}\n","/** MST mixin for managing a queue of dialogs at the level of the session */\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { DialogComponentType } from '@jbrowse/core/util'\nimport { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'\nimport { isBaseSession } from './BaseSession'\n\n/**\n * #stateModel DialogQueueSessionMixin\n */\nexport function DialogQueueSessionMixin(_pluginManager: PluginManager) {\n return types\n .model('DialogQueueSessionMixin', {})\n .volatile(() => ({\n queueOfDialogs: [] as [DialogComponentType, unknown][],\n }))\n .views(self => ({\n /**\n * #getter\n */\n get DialogComponent() {\n return self.queueOfDialogs[0]?.[0]\n },\n /**\n * #getter\n */\n get DialogProps() {\n return self.queueOfDialogs[0]?.[1]\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n removeActiveDialog() {\n self.queueOfDialogs = self.queueOfDialogs.slice(1)\n },\n /**\n * #action\n */\n queueDialog(\n cb: (doneCallback: () => void) => [DialogComponentType, unknown],\n ) {\n const [component, props] = cb(() => {\n this.removeActiveDialog()\n })\n self.queueOfDialogs = [...self.queueOfDialogs, [component, props]]\n },\n }))\n}\n\n/** Session mixin MST type for a session that has `queueOfDialogs`, etc. */\nexport type SessionWithDialogsType = ReturnType<typeof DialogQueueSessionMixin>\n\n/** Instance of a session that has dialogs */\nexport type SessionWithDialogs = Instance<SessionWithDialogsType>\n\n/** Type guard for SessionWithDialogs */\nexport function isSessionWithDialogs(\n session: IAnyStateTreeNode,\n): session is SessionWithDialogs {\n return isBaseSession(session) && 'queueOfDialogs' in session\n}\n","import {\n IAnyStateTreeNode,\n Instance,\n addDisposer,\n types,\n} from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { getConf } from '@jbrowse/core/configuration'\nimport { createJBrowseTheme, defaultThemes } from '@jbrowse/core/ui'\nimport { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util'\nimport { ThemeOptions } from '@mui/material'\nimport { autorun } from 'mobx'\n\n// locals\nimport { BaseSession } from './BaseSession'\n\ntype ThemeMap = Record<string, ThemeOptions>\n\n/**\n * #stateModel ThemeManagerSessionMixin\n */\nexport function ThemeManagerSessionMixin(_pluginManager: PluginManager) {\n return types\n .model({})\n .volatile(() => ({\n sessionThemeName: localStorageGetItem('themeName') || 'default',\n }))\n .views(s => ({\n /**\n * #method\n */\n allThemes(): ThemeMap {\n const self = s as typeof s & BaseSession\n const extraThemes = getConf(self.jbrowse, 'extraThemes')\n return { ...defaultThemes, ...extraThemes }\n },\n /**\n * #getter\n */\n get themeName() {\n const { sessionThemeName } = s\n const all = this.allThemes()\n return all[sessionThemeName] ? sessionThemeName : 'default'\n },\n /**\n * #getter\n */\n get theme() {\n const self = s as typeof s & BaseSession\n const configTheme = getConf(self.jbrowse, 'theme')\n const all = this.allThemes()\n return createJBrowseTheme(configTheme, all, this.themeName)\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setThemeName(name: string) {\n self.sessionThemeName = name\n },\n afterAttach() {\n addDisposer(\n self,\n autorun(() => {\n localStorageSetItem('themeName', self.themeName)\n }),\n )\n },\n }))\n}\n\n/** Session mixin MST type for a session that supports theming */\nexport type SessionWithThemesType = ReturnType<typeof ThemeManagerSessionMixin>\n\n/** Instance of a session that has theming support */\nexport type SessionWithThemes = Instance<SessionWithThemesType>\n\n/** Type guard for SessionWithThemes */\nexport function isSessionWithThemes(\n session: IAnyStateTreeNode,\n): session is SessionWithThemes {\n return 'theme' in session\n}\n","import {\n IAnyStateTreeNode,\n Instance,\n cast,\n getSnapshot,\n types,\n} from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport { Region } from '@jbrowse/core/util'\nimport { DrawerWidgetSessionMixin } from './DrawerWidgets'\nimport { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes'\nimport { IBaseViewModelWithDisplayedRegions } from '@jbrowse/core/pluggableElementTypes/models/BaseViewModel'\n\n// locals\nimport { BaseSessionModel, isBaseSession } from './BaseSession'\n\n/**\n * #stateModel MultipleViewsSessionMixin\n * composed of\n * - [BaseSessionModel](../basesessionmodel)\n * - [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin)\n */\nexport function MultipleViewsSessionMixin(pluginManager: PluginManager) {\n return types\n .compose(\n BaseSessionModel(pluginManager),\n DrawerWidgetSessionMixin(pluginManager),\n )\n .props({\n /**\n * #property\n */\n views: types.array(pluginManager.pluggableMstType('view', 'stateModel')),\n })\n .actions(self => ({\n /**\n * #action\n */\n moveViewDown(id: string) {\n const idx = self.views.findIndex(v => v.id === id)\n if (idx !== -1 && idx < self.views.length - 1) {\n self.views.splice(idx, 2, self.views[idx + 1], self.views[idx])\n }\n },\n /**\n * #action\n */\n moveViewUp(id: string) {\n const idx = self.views.findIndex(view => view.id === id)\n if (idx > 0) {\n self.views.splice(idx - 1, 2, self.views[idx], self.views[idx - 1])\n }\n },\n /**\n * #action\n */\n moveViewToTop(id: string) {\n const idx = self.views.findIndex(view => view.id === id)\n self.views = cast([\n self.views[idx],\n ...self.views.filter(view => view.id !== id),\n ])\n },\n\n /**\n * #action\n */\n moveViewToBottom(id: string) {\n const idx = self.views.findIndex(view => view.id === id)\n self.views = cast([\n ...self.views.filter(view => view.id !== id),\n self.views[idx],\n ])\n },\n\n /**\n * #action\n */\n addView(typeName: string, initialState = {}) {\n const typeDefinition = pluginManager.getElementType('view', typeName)\n if (!typeDefinition) {\n throw new Error(`unknown view type ${typeName}`)\n }\n\n const length = self.views.push({\n ...initialState,\n type: typeName,\n })\n return self.views[length - 1]\n },\n\n /**\n * #action\n */\n removeView(view: IBaseViewModel) {\n for (const [, widget] of self.activeWidgets) {\n if (widget.view && widget.view.id === view.id) {\n self.hideWidget(widget)\n }\n }\n self.views.remove(view)\n },\n\n /**\n * #action\n */\n addLinearGenomeViewOfAssembly(assemblyName: string, initialState = {}) {\n return this.addViewOfAssembly(\n 'LinearGenomeView',\n assemblyName,\n initialState,\n )\n },\n\n /**\n * #action\n */\n addViewOfAssembly(\n viewType: string,\n assemblyName: string,\n initialState: Record<string, unknown> = {},\n ) {\n const asm = self.assemblies.find(\n s => readConfObject(s, 'name') === assemblyName,\n )\n if (!asm) {\n throw new Error(\n `Could not add view of assembly \"${assemblyName}\", assembly name not found`,\n )\n }\n return this.addView(viewType, {\n ...initialState,\n displayRegionsFromAssemblyName: readConfObject(asm, 'name'),\n })\n },\n\n /**\n * #action\n */\n addViewFromAnotherView(\n viewType: string,\n otherView: IBaseViewModelWithDisplayedRegions,\n initialState: { displayedRegions?: Region[] } = {},\n ) {\n const state = { ...initialState }\n state.displayedRegions = getSnapshot(otherView.displayedRegions)\n return this.addView(viewType, state)\n },\n }))\n}\n\n/** Session mixin MST type for a session that manages multiple views */\nexport type SessionWithMultipleViewsType = ReturnType<\n typeof MultipleViewsSessionMixin\n>\n\n/** Instance of a session with multiple views */\nexport type SessionWithMultipleViews = Instance<SessionWithMultipleViewsType>\n\n/** Type guard for SessionWithMultipleViews */\nexport function isSessionWithMultipleViews(\n session: IAnyStateTreeNode,\n): session is SessionWithMultipleViews {\n return isBaseSession(session) && 'views' in session\n}\n","import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport {\n AnyConfiguration,\n AnyConfigurationModel,\n} from '@jbrowse/core/configuration'\n\n// locals\nimport { TracksManagerSessionMixin } from './Tracks'\nimport { isBaseSession } from './BaseSession'\n\n/**\n * #stateModel SessionTracksManagerSessionMixin\n */\nexport function SessionTracksManagerSessionMixin(pluginManager: PluginManager) {\n return TracksManagerSessionMixin(pluginManager)\n .named('SessionTracksManagerSessionMixin')\n .props({\n /**\n * #property\n */\n sessionTracks: types.array(\n pluginManager.pluggableConfigSchemaType('track'),\n ),\n })\n .views(self => ({\n /**\n * #getter\n */\n get tracks(): AnyConfigurationModel[] {\n return [...self.sessionTracks, ...self.jbrowse.tracks]\n },\n }))\n .actions(self => {\n const {\n addTrackConf: superAddTrackConf,\n deleteTrackConf: superDeleteTrackConf,\n } = self\n return {\n /**\n * #action\n */\n addTrackConf(trackConf: AnyConfiguration) {\n if (self.adminMode) {\n return superAddTrackConf(trackConf)\n }\n\n const { trackId, type } = trackConf as {\n type: string\n trackId: string\n }\n if (!type) {\n throw new Error(`unknown track type ${type}`)\n }\n const track = self.sessionTracks.find(t => t.trackId === trackId)\n if (track) {\n return track\n }\n const length = self.sessionTracks.push(trackConf)\n return self.sessionTracks[length - 1]\n },\n\n /**\n * #action\n */\n deleteTrackConf(trackConf: AnyConfigurationModel) {\n // try to delete it in the main config if in admin mode\n const found = superDeleteTrackConf(trackConf)\n if (found) {\n return found\n }\n // if not found or not in admin mode, try to delete it in the\n // sessionTracks\n const { trackId } = trackConf\n const idx = self.sessionTracks.findIndex(t => t.trackId === trackId)\n if (idx === -1) {\n return undefined\n }\n return self.sessionTracks.splice(idx, 1)\n },\n }\n })\n}\n\n/** Session mixin MST type for a session that has `sessionTracks` */\nexport type SessionWithSessionTracksType = ReturnType<\n typeof SessionTracksManagerSessionMixin\n>\n\n/** Instance of a session that has `sessionTracks` */\nexport type SessionWithSessionTracks = Instance<SessionWithSessionTracksType>\n\n/** Type guard for SessionWithSessionTracks */\nexport function isSessionWithSessionTracks(\n thing: IAnyStateTreeNode,\n): thing is SessionWithSessionTracks {\n return isBaseSession(thing) && 'sessionTracks' in thing\n}\n","import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport {\n AnyConfiguration,\n AnyConfigurationModel,\n} from '@jbrowse/core/configuration'\nimport { BaseSessionModel, isBaseSession } from './BaseSession'\nimport { ReferenceManagementSessionMixin } from './ReferenceManagement'\n\n/**\n * #stateModel TracksManagerSessionMixin\n * composed of\n * - BaseSessionModel\n * - ReferenceManagementSessionMixin\n */\nexport function TracksManagerSessionMixin(pluginManager: PluginManager) {\n return types\n .compose(\n 'TracksManagerSessionMixin',\n BaseSessionModel(pluginManager),\n ReferenceManagementSessionMixin(pluginManager),\n )\n .views(self => ({\n /**\n * #getter\n */\n get tracks(): AnyConfigurationModel[] {\n return self.jbrowse.tracks\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n addTrackConf(trackConf: AnyConfiguration) {\n return self.jbrowse.addTrackConf(trackConf)\n },\n\n /**\n * #action\n */\n deleteTrackConf(trackConf: AnyConfigurationModel) {\n const callbacksToDereferenceTrack: (() => void)[] = []\n const dereferenceTypeCount: Record<string, number> = {}\n const referring = self.getReferring(trackConf)\n self.removeReferring(\n referring,\n trackConf,\n callbacksToDereferenceTrack,\n dereferenceTypeCount,\n )\n callbacksToDereferenceTrack.forEach(cb => {\n cb()\n })\n if (self.adminMode) {\n return self.jbrowse.deleteTrackConf(trackConf)\n }\n },\n }))\n}\n\n/** Session mixin MST type for a session that has tracks */\nexport type SessionWithTracksType = ReturnType<typeof TracksManagerSessionMixin>\n\n/** Instance of a session that has tracks */\nexport type SessionWithTracks = Instance<SessionWithTracksType>\n\n/** Type guard for SessionWithTracks */\nexport function isSessionWithTracks(\n thing: IAnyStateTreeNode,\n): thing is SessionWithTracks {\n return isBaseSession(thing) && 'tracks' in thing\n}\n","import { types } from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { AnyConfiguration } from '@jbrowse/core/configuration'\nimport { BaseSession } from '@jbrowse/product-core'\nimport { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'\n\n/**\n * #stateModel SessionAssembliesMixin\n * #category root\n */\nexport function SessionAssembliesMixin(\n pluginManager: PluginManager,\n assemblyConfigSchemasType: BaseAssemblyConfigSchema,\n) {\n return types\n .model({\n /**\n * #property\n */\n sessionAssemblies: types.array(assemblyConfigSchemasType),\n })\n .actions(s => {\n const self = s as typeof s & BaseSession\n return {\n /**\n * #action\n */\n addSessionAssembly(conf: AnyConfiguration) {\n const asm = self.sessionAssemblies.find(f => f.name === conf.name)\n if (asm) {\n console.warn(`Assembly ${conf.name} already exists`)\n return asm\n }\n const length = self.sessionAssemblies.push(conf)\n return self.sessionAssemblies[length - 1]\n },\n\n /**\n * #action\n */\n removeSessionAssembly(assemblyName: string) {\n const elt = self.sessionAssemblies.find(a => a.name === assemblyName)\n if (elt) {\n self.sessionAssemblies.remove(elt)\n }\n },\n }\n })\n}\n","import { types } from 'mobx-state-tree'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { AnyConfiguration } from '@jbrowse/core/configuration'\nimport { BaseSession } from '@jbrowse/product-core'\n\n/**\n * #stateModel TemporaryAssembliesMixin\n * #category root\n */\nexport function TemporaryAssembliesMixin(\n pluginManager: PluginManager,\n assemblyConfigSchemasType = types.frozen(),\n) {\n return types\n .model({\n /**\n * #property\n */\n temporaryAssemblies: types.array(assemblyConfigSchemasType),\n })\n\n .actions(s => {\n const self = s as typeof s & BaseSession\n return {\n /**\n * #action\n * used for read vs ref type assemblies.\n */\n addTemporaryAssembly(conf: AnyConfiguration) {\n const asm = self.temporaryAssemblies.find(f => f.name === conf.name)\n if (asm) {\n console.warn(`Assembly ${conf.name} was already existing`)\n return asm\n }\n const length = self.temporaryAssemblies.push(conf)\n return self.temporaryAssemblies[length - 1]\n },\n\n /**\n * #action\n */\n removeTemporaryAssembly(name: string) {\n const elt = self.temporaryAssemblies.find(a => a.name === name)\n if (elt) {\n self.temporaryAssemblies.remove(elt)\n }\n },\n }\n })\n}\n","import { types } from 'mobx-state-tree'\n\nimport {\n ConnectionManagementSessionMixin,\n SessionWithSessionTracks,\n} from '@jbrowse/product-core'\nimport type { BaseSession } from '@jbrowse/product-core'\n\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig'\n\n/**\n * #stateModel WebSessionConnectionsMixin\n * #category session\n */\nexport function WebSessionConnectionsMixin(pluginManager: PluginManager) {\n return types\n .compose(\n 'SessionConnectionsManagement',\n ConnectionManagementSessionMixin(pluginManager),\n types.model({\n /**\n * #property\n */\n sessionConnections: types.array(\n pluginManager.pluggableConfigSchemaType('connection'),\n ),\n }),\n )\n .actions(s => {\n const self = s as typeof s & BaseSession & SessionWithSessionTracks\n const superDeleteConnection = self.deleteConnection\n const superAddConnectionConf = self.addConnectionConf\n return {\n addConnectionConf(connectionConf: BaseConnectionConfigModel) {\n if (self.adminMode) {\n return superAddConnectionConf(connectionConf)\n }\n const { connectionId, type } = connectionConf\n if (!type) {\n throw new Error(`unknown connection type ${type}`)\n }\n const connection = self.sessionTracks.find(\n c => c.connectionId === connectionId,\n )\n if (connection) {\n return connection\n }\n const length = self.sessionConnections.push(connectionConf)\n return self.sessionConnections[length - 1]\n },\n\n deleteConnection(configuration: AnyConfigurationModel) {\n let deletedConn: unknown\n if (self.adminMode) {\n deletedConn = superDeleteConnection(configuration)\n }\n if (!deletedConn) {\n const { connectionId } = configuration\n const idx = self.sessionConnections.findIndex(\n c => c.connectionId === connectionId,\n )\n if (idx === -1) {\n return undefined\n }\n return self.sessionConnections.splice(idx, 1)\n }\n return deletedConn\n },\n }\n })\n}\n","import { types } from 'mobx-state-tree'\n\n/**\n * #stateModel AppFocusMixin\n * #category session\n */\nexport function AppFocusMixin() {\n return types\n .model({\n /**\n * #property\n * used to keep track of which view is in focus\n */\n focusedViewId: types.maybe(types.string),\n })\n .actions(self => ({\n /**\n * #action\n */\n setFocusedViewId(viewId: string) {\n self.focusedViewId = viewId\n },\n }))\n}\n","import { AbstractSessionModel } from '@jbrowse/core/util/types'\nimport { Instance } from 'mobx-state-tree'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'\nimport { BaseWebSession } from '@jbrowse/web-core'\n\n/**\n * #stateModel JBrowseWebSessionModel\n * extends [BaseWebSession](../basewebsession)\n */\nexport default function sessionModelFactory({\n pluginManager,\n assemblyConfigSchema,\n}: {\n pluginManager: PluginManager\n assemblyConfigSchema: BaseAssemblyConfigSchema\n}) {\n return BaseWebSession({ pluginManager, assemblyConfigSchema })\n}\n\nexport type WebSessionModelType = ReturnType<typeof sessionModelFactory>\nexport type WebSessionModel = Instance<WebSessionModelType>\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction z(x: Instance<WebSessionModelType>): AbstractSessionModel {\n // this function's sole purpose is to get typescript to check\n // that the session model implements all of AbstractSessionModel\n return x\n}\n","import PluginManager from '@jbrowse/core/PluginManager'\nimport { doAnalytics } from '@jbrowse/core/util/analytics'\n\n// locals\nimport JBrowseRootModelFactory from './rootModel/rootModel'\nimport sessionModelFactory from './sessionModel'\nimport corePlugins from './corePlugins'\nimport { SessionLoaderModel, loadSessionSpec } from './SessionLoader'\n\nexport function createPluginManager(self: SessionLoaderModel) {\n // it is ready when a session has loaded and when there is no config\n // error Assuming that the query changes self.sessionError or\n // self.sessionSnapshot or self.blankSession\n const pluginManager = new PluginManager([\n ...corePlugins.map(P => ({\n plugin: new P(),\n metadata: { isCore: true },\n })),\n ...self.runtimePlugins.map(({ plugin: P, definition }) => ({\n plugin: new P(),\n definition,\n metadata: {\n // @ts-expect-error\n url: definition.url,\n },\n })),\n ...self.sessionPlugins.map(({ plugin: P, definition }) => ({\n plugin: new P(),\n definition,\n metadata: {\n // @ts-expect-error\n url: definition.url,\n },\n })),\n ])\n pluginManager.createPluggableElements()\n const RootModel = JBrowseRootModelFactory({\n pluginManager,\n sessionModelFactory,\n adminMode: !!self.adminKey,\n })\n\n if (!self.configSnapshot) {\n return undefined\n }\n const rootModel = RootModel.create(\n {\n jbrowse: self.configSnapshot,\n configPath: self.configPath,\n },\n { pluginManager },\n )\n\n // @ts-expect-error\n if (!self.configSnapshot.configuration?.rpc?.defaultDriver) {\n rootModel.jbrowse.configuration.rpc.defaultDriver.set('WebWorkerRpcDriver')\n }\n\n let afterInitializedCb = () => {}\n\n // in order: saves the previous autosave for recovery, tries to load the\n // local session if session in query, or loads the default session\n try {\n if (self.sessionError) {\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n throw self.sessionError\n } else if (self.sessionSnapshot) {\n rootModel.setSession(self.sessionSnapshot)\n } else if (self.sessionSpec) {\n // @ts-expect-error\n afterInitializedCb = loadSessionSpec(self.sessionSpec, pluginManager)\n } else if (rootModel.jbrowse.defaultSession?.views?.length) {\n rootModel.setDefaultSession()\n }\n } catch (e) {\n rootModel.setDefaultSession()\n const str = `${e}`\n const m = str.replace('[mobx-state-tree] ', '').replace(/\\(.+/, '')\n const r = m.length > 1000 ? `${m.slice(0, 1000)}...see more in console` : m\n const s = r.startsWith('Error:') ? r : `Error: ${r}`\n rootModel.session?.notifyError(\n `${s}. If you received this URL from another user, request that they send you a session generated with the \"Share\" button instead of copying and pasting their URL`,\n self.sessionError,\n self.sessionSnapshot,\n )\n console.error(e)\n }\n\n // send analytics\n doAnalytics(rootModel, self.initialTimestamp, self.sessionQuery)\n\n pluginManager.setRootModel(rootModel)\n pluginManager.configure()\n afterInitializedCb()\n return pluginManager\n}\n","import { readConfObject } from '../configuration'\nimport { isElectron } from '../util'\n\ntype AnalyticsObj = Record<string, any>\n\ninterface Track {\n type: string\n}\n\nexport async function writeAWSAnalytics(\n rootModel: any,\n initialTimeStamp: number,\n sessionQuery?: string | null,\n) {\n try {\n const url = 'https://analytics.jbrowse.org/api/v1'\n\n const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(\n (track: any) => (readConfObject(track, 'assemblyNames') || []).length > 1,\n ).length\n\n const savedSessionCount = Object.keys(localStorage).filter(name =>\n name.includes('localSaved-'),\n ).length\n\n const { jbrowse: config, session, version: ver } = rootModel\n const { tracks, assemblies, plugins } = config\n\n // stats to be recorded in db\n const stats: AnalyticsObj = {\n ver,\n 'plugins-count': plugins?.length || 0,\n 'plugin-names': plugins?.map((p: any) => p.name).join(','),\n 'assemblies-count': assemblies.length,\n 'tracks-count': tracks.length,\n 'session-tracks-count': session?.sessionTracks.length || 0,\n 'open-views': session?.views.length || 0,\n 'synteny-tracks-count': multiAssemblyTracks,\n 'saved-sessions-count': savedSessionCount,\n\n // field if existing session param in query before autogenerated param\n 'existing-session-param-type': sessionQuery?.split('-')[0] || 'none',\n\n // screen geometry\n 'scn-h': window.screen.height,\n 'scn-w': window.screen.width,\n\n // window geometry\n 'win-h': window.innerHeight,\n 'win-w': window.innerWidth,\n\n electron: isElectron,\n loadTime: (Date.now() - initialTimeStamp) / 1000,\n jb2: true,\n }\n\n // stringifies the track type counts, gets processed in lambda\n tracks.forEach((track: Track) => {\n const key = `track-types-${track.type}`\n stats[key] = stats[key] + 1 || 1\n })\n\n // stringifies the session track type counts, gets processed in lambda\n session?.sessionTracks.forEach((track: Track) => {\n const key = `sessionTrack-types-${track.type}`\n stats[key] = stats[key] + 1 || 1\n })\n\n // put stats into a query string for get request\n const qs = Object.keys(stats)\n .map(key => `${key}=${stats[key]}`)\n .join('&')\n\n await fetch(`${url}?${qs}`)\n } catch (e) {\n console.error('Failed to write analytics to AWS.', e)\n }\n}\n\nexport async function writeGAAnalytics(\n rootModel: any,\n initialTimestamp: number,\n) {\n const jbrowseUser = 'UA-7115575-5'\n const stats: AnalyticsObj = {\n 'tracks-count': rootModel.jbrowse.tracks.length, // this is all possible tracks\n ver: rootModel.version,\n electron: isElectron,\n loadTime: Date.now() - initialTimestamp,\n pluginNames:\n rootModel.jbrowse.plugins?.map((plugin: any) => plugin.name) || '',\n }\n\n // create script\n let analyticsScript =\n \"(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\"\n analyticsScript +=\n '(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),'\n analyticsScript +=\n 'm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)'\n analyticsScript +=\n \"})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');\"\n analyticsScript += `ga('create', '${jbrowseUser}', 'auto', 'jbrowseTracker');`\n\n const gaData: AnalyticsObj = {}\n const googleDimensions = 'tracks-count ver electron loadTime pluginNames'\n\n googleDimensions.split(/\\s+/).forEach((key, index) => {\n gaData[`dimension${index + 1}`] = stats[key]\n })\n\n gaData.metric1 = Math.round(stats.loadTime)\n\n analyticsScript += `ga('jbrowseTracker.send', 'pageview',${JSON.stringify(\n gaData,\n )});`\n\n const analyticsScriptNode = document.createElement('script')\n analyticsScriptNode.innerHTML = analyticsScript\n\n document.getElementsByTagName('head')[0]!.append(analyticsScriptNode)\n}\n\nexport function doAnalytics(\n rootModel: any,\n initialTimestamp: number,\n initialSessionQuery: string | null | undefined,\n) {\n if (\n rootModel &&\n !readConfObject(rootModel.jbrowse.configuration, 'disableAnalytics')\n ) {\n // ok if these are unhandled\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n writeAWSAnalytics(rootModel, initialTimestamp, initialSessionQuery)\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n writeGAAnalytics(rootModel, initialTimestamp)\n }\n}\n","import React, { lazy, useEffect, useState, Suspense } from 'react'\nimport { observer } from 'mobx-react'\nimport { ErrorBoundary } from 'react-error-boundary'\nimport {\n StringParam,\n QueryParamProvider,\n useQueryParam,\n} from 'use-query-params'\nimport { WindowHistoryAdapter } from 'use-query-params/adapters/window'\nimport { FatalErrorDialog, LoadingEllipses } from '@jbrowse/core/ui'\nimport PluginManager from '@jbrowse/core/PluginManager'\nimport '@fontsource/roboto'\n\n// locals\nimport Loading from './Loading'\nimport JBrowse from './JBrowse'\nimport factoryReset from '../factoryReset'\nimport SessionLoader, {\n SessionLoaderModel,\n SessionTriagedInfo,\n} from '../SessionLoader'\nimport StartScreenErrorMessage from './StartScreenErrorMessage'\nimport { createPluginManager } from '../createPluginManager'\nimport type { WebRootModel } from '../rootModel/rootModel'\n\nconst ConfigWarningDialog = lazy(() => import('./ConfigWarningDialog'))\nconst SessionWarningDialog = lazy(() => import('./SessionWarningDialog'))\nconst StartScreen = lazy(() => import('./StartScreen'))\n\nfunction normalize<T>(param: T | null | undefined) {\n return param === null ? undefined : param\n}\n\nexport function Loader({\n initialTimestamp = Date.now(),\n}: {\n initialTimestamp?: number\n}) {\n // return value if defined, else convert null to undefined for use with\n // types.maybe\n\n const Str = StringParam\n\n const [config] = useQueryParam('config', Str)\n const [session] = useQueryParam('session', Str)\n const [adminKey] = useQueryParam('adminKey', Str)\n const [password, setPassword] = useQueryParam('password', Str)\n const [loc, setLoc] = useQueryParam('loc', Str)\n const [sessionTracks, setSessionTracks] = useQueryParam('sessionTracks', Str)\n const [assembly, setAssembly] = useQueryParam('assembly', Str)\n const [tracks, setTracks] = useQueryParam('tracks', Str)\n const [highlight, setHighlight] = useQueryParam('highlight', Str)\n const [nav, setNav] = useQueryParam('nav', Str)\n const [tracklist, setTrackList] = useQueryParam('tracklist', Str)\n\n const loader = SessionLoader.create({\n configPath: normalize(config),\n sessionQuery: normalize(session),\n password: normalize(password),\n adminKey: normalize(adminKey),\n loc: normalize(loc),\n assembly: normalize(assembly),\n tracks: normalize(tracks),\n sessionTracks: normalize(sessionTracks),\n tracklist: JSON.parse(normalize(tracklist) || 'false'),\n highlight: normalize(highlight),\n nav: JSON.parse(normalize(nav) || 'true'),\n initialTimestamp,\n })\n\n useEffect(() => {\n setLoc(undefined, 'replaceIn')\n setTracks(undefined, 'replaceIn')\n setAssembly(undefined, 'replaceIn')\n setPassword(undefined, 'replaceIn')\n setSessionTracks(undefined, 'replaceIn')\n setTrackList(undefined, 'replaceIn')\n setNav(undefined, 'replaceIn')\n setHighlight(undefined, 'replaceIn')\n }, [\n setAssembly,\n setLoc,\n setNav,\n setTrackList,\n setTracks,\n setPassword,\n setSessionTracks,\n setHighlight,\n ])\n\n return <Renderer loader={loader} />\n}\n\nconst SessionTriaged = observer(function ({\n sessionTriaged,\n loader,\n}: {\n loader: SessionLoaderModel\n sessionTriaged: SessionTriagedInfo\n}) {\n return (\n <Suspense fallback={null}>\n {sessionTriaged.origin === 'session' ? (\n <SessionWarningDialog\n loader={loader}\n handleClose={() => {\n loader.setSessionTriaged(undefined)\n }}\n />\n ) : (\n <ConfigWarningDialog\n loader={loader}\n handleClose={() => {\n loader.setSessionTriaged(undefined)\n }}\n />\n )}\n </Suspense>\n )\n})\n\nconst PluginManagerLoaded = observer(function ({\n pluginManager,\n}: {\n pluginManager: PluginManager\n}) {\n const { rootModel } = pluginManager\n return !rootModel?.session ? (\n <Suspense fallback={<LoadingEllipses />}>\n <StartScreen\n rootModel={rootModel as WebRootModel}\n onFactoryReset={factoryReset}\n />\n </Suspense>\n ) : (\n <JBrowse pluginManager={pluginManager} />\n )\n})\n\nconst Renderer = observer(function ({\n loader,\n}: {\n loader: SessionLoaderModel\n}) {\n const { configError, ready, sessionTriaged } = loader\n const [pluginManager, setPluginManager] = useState<PluginManager>()\n const [error, setError] = useState<unknown>()\n\n useEffect(() => {\n let pm: PluginManager | undefined\n try {\n if (!ready) {\n return\n }\n pm = createPluginManager(loader)\n setPluginManager(pm)\n } catch (e) {\n console.error(e)\n setError(e)\n }\n }, [loader, ready])\n\n const err = configError || error\n if (err) {\n return <StartScreenErrorMessage error={err} />\n } else if (sessionTriaged) {\n return <SessionTriaged loader={loader} sessionTriaged={sessionTriaged} />\n } else if (pluginManager) {\n return <PluginManagerLoaded pluginManager={pluginManager} />\n } else {\n return <Loading />\n }\n})\n\nfunction LoaderWrapper({ initialTimestamp }: { initialTimestamp: number }) {\n return (\n <ErrorBoundary\n FallbackComponent={props => (\n <FatalErrorDialog\n {...props}\n resetButtonText=\"Reset Session\"\n onFactoryReset={factoryReset}\n />\n )}\n >\n <QueryParamProvider adapter={WindowHistoryAdapter}>\n <Loader initialTimestamp={initialTimestamp} />\n </QueryParamProvider>\n </ErrorBoundary>\n )\n}\n\nexport default LoaderWrapper\n","export default async function factoryReset() {\n // @ts-expect-error\n window.location = window.location.pathname\n}\n","import { toUrlSafeB64 } from './util'\n\n// from https://stackoverflow.com/questions/1349404/\nfunction generateUID(length: number) {\n return window\n .btoa(\n [...window.crypto.getRandomValues(new Uint8Array(length * 2))]\n .map(b => String.fromCharCode(b))\n .join(''),\n )\n .replaceAll(/[+/]/g, '')\n .slice(0, length)\n}\n\nconst encrypt = async (text: string, password: string) => {\n const AES = await import('crypto-js/aes')\n return AES.encrypt(text, password).toString()\n}\n\nconst decrypt = async (text: string, password: string) => {\n const AES = await import('crypto-js/aes')\n const Utf8 = await import('crypto-js/enc-utf8')\n const bytes = AES.decrypt(text, password)\n return bytes.toString(Utf8)\n}\n\nfunction getErrorMsg(err: string) {\n try {\n const obj = JSON.parse(err)\n return obj.message\n } catch (e) {\n return err\n }\n}\n// writes the encrypted session, current datetime, and referer to DynamoDB\nexport async function shareSessionToDynamo(\n session: unknown,\n url: string,\n referer: string,\n) {\n const sess = await toUrlSafeB64(JSON.stringify(session))\n const password = generateUID(5)\n const encryptedSession = await encrypt(sess, password)\n\n const data = new FormData()\n data.append('session', encryptedSession)\n data.append('dateShared', `${Date.now()}`)\n data.append('referer', referer)\n\n const response = await fetch(`${url}share`, {\n method: 'POST',\n mode: 'cors',\n body: data,\n })\n\n if (!response.ok) {\n const err = await response.text()\n throw new Error(getErrorMsg(err))\n }\n const json = await response.json()\n return {\n json,\n encryptedSession,\n password,\n }\n}\n\nexport async function readSessionFromDynamo(\n baseUrl: string,\n sessionQueryParam: string,\n password: string,\n signal?: AbortSignal,\n) {\n const sessionId = sessionQueryParam.split('share-')[1]!\n const url = `${baseUrl}?sessionId=${encodeURIComponent(sessionId)}`\n const response = await fetch(url, {\n signal,\n })\n\n if (!response.ok) {\n const err = await response.text()\n throw new Error(getErrorMsg(err))\n }\n\n const json = await response.json()\n return decrypt(json.session, password)\n}\n","import {\n PluginDefinition,\n isCJSPluginDefinition,\n isESMPluginDefinition,\n isUMDPluginDefinition,\n} from '@jbrowse/core/PluginLoader'\nimport {\n getPropertyMembers,\n getChildType,\n isArrayType,\n isModelType,\n isReferenceType,\n isValidReference,\n isMapType,\n IAnyType,\n IAnyStateTreeNode,\n Instance,\n} from 'mobx-state-tree'\nimport type { types } from 'mobx-state-tree'\n\n/**\n * Pad the end of a base64 string with \"=\" to make it valid\n * @param b64 - unpadded b64 string\n */\nexport function b64PadSuffix(b64: string): string {\n let num = 0\n const mo = b64.length % 4\n switch (mo) {\n case 3:\n num = 1\n break\n case 2:\n num = 2\n break\n case 0:\n num = 0\n break\n default:\n throw new Error('base64 not a valid length')\n }\n return b64 + '='.repeat(num)\n}\n\n/**\n * Decode and inflate a url-safe base64 to a string\n * See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}\n * @param b64 - a base64 string to decode and inflate\n */\nexport async function fromUrlSafeB64(b64: string) {\n const originalB64 = b64PadSuffix(\n b64.replaceAll('-', '+').replaceAll('_', '/'),\n )\n const { toByteArray } = await import('base64-js')\n const { inflate } = await import('pako')\n const bytes = toByteArray(originalB64)\n const inflated = inflate(bytes)\n return new TextDecoder().decode(inflated)\n}\n\n/**\n * Compress and encode a string as url-safe base64\n * See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}\n * @param str- a string to compress and encode\n */\nexport async function toUrlSafeB64(str: string) {\n const bytes = new TextEncoder().encode(str)\n const { deflate } = await import('pako')\n const { fromByteArray } = await import('base64-js')\n const deflated = deflate(bytes)\n const encoded = fromByteArray(deflated)\n const pos = encoded.indexOf('=')\n return pos > 0\n ? encoded.slice(0, pos).replaceAll('+', '-').replaceAll('/', '_')\n : encoded.replaceAll('+', '-').replaceAll('/', '_')\n}\n\ntype MSTArray = Instance<ReturnType<typeof types.array>>\ntype MSTMap = Instance<ReturnType<typeof types.map>>\n\n// attempts to remove undefined references from the given MST model. can only actually\n// remove them from arrays and maps. throws MST undefined ref error if it encounters\n// undefined refs in model properties\nexport function filterSessionInPlace(\n node: IAnyStateTreeNode | undefined,\n type: IAnyType,\n) {\n // makes it work with session sharing\n if (node === undefined) {\n return\n }\n if (isArrayType(type)) {\n const array = node as MSTArray\n const childType = getChildType(node)\n if (isReferenceType(childType)) {\n // filter array elements\n for (let i = 0; i < array.length; ) {\n if (!isValidReference(() => array[i])) {\n array.splice(i, 1)\n } else {\n i += 1\n }\n }\n }\n array.forEach(el => {\n filterSessionInPlace(el, childType)\n })\n } else if (isMapType(type)) {\n const map = node as MSTMap\n const childType = getChildType(map)\n if (isReferenceType(childType)) {\n // filter the map members\n for (const key in map.keys()) {\n if (!isValidReference(() => map.get(key))) {\n map.delete(key)\n }\n }\n }\n map.forEach(child => {\n filterSessionInPlace(child, childType)\n })\n } else if (isModelType(type)) {\n // iterate over children\n const { properties } = getPropertyMembers(node)\n\n Object.entries(properties).forEach(([pname, ptype]) => {\n // @ts-ignore\n filterSessionInPlace(node[pname], ptype)\n })\n }\n}\n\nexport function addRelativeUris(\n config: Record<string, unknown> | null,\n base: URL,\n) {\n if (typeof config === 'object' && config !== null) {\n for (const key of Object.keys(config)) {\n if (typeof config[key] === 'object' && config[key] !== null) {\n addRelativeUris(config[key] as Record<string, unknown>, base)\n } else if (key === 'uri') {\n config.baseUri = base.href\n }\n }\n }\n}\n\nexport interface Root {\n configuration?: Record<string, unknown>\n}\n\n// raw readConf alternative for before conf is initialized\nexport function readConf({ configuration }: Root, attr: string, def: string) {\n return configuration?.[attr] || def\n}\n\nexport async function fetchPlugins() {\n const response = await fetch('https://jbrowse.org/plugin-store/plugins.json')\n if (!response.ok) {\n throw new Error(\n `HTTP ${response.status} ${response.statusText} fetching plugins`,\n )\n }\n return response.json() as Promise<{ plugins: PluginDefinition[] }>\n}\n\nexport async function checkPlugins(pluginsToCheck: PluginDefinition[]) {\n if (pluginsToCheck.length === 0) {\n return true\n }\n const storePlugins = await fetchPlugins()\n return pluginsToCheck.every(p => {\n if (isUMDPluginDefinition(p)) {\n return storePlugins.plugins.some(\n pp =>\n isUMDPluginDefinition(p) &&\n (('url' in pp && 'url' in p && p.url === pp.url) ||\n ('umdUrl' in pp && 'umdUrl' in p && p.umdUrl === pp.umdUrl)),\n )\n }\n if (isESMPluginDefinition(p)) {\n return storePlugins.plugins.some(\n pp =>\n // @ts-expect-error\n isESMPluginDefinition(p) && 'esmUrl' in p && p.esmUrl === pp.esmUrl,\n )\n }\n if (isCJSPluginDefinition(p)) {\n return storePlugins.plugins.some(\n // @ts-expect-error\n pp => isCJSPluginDefinition(p) && p.cjsUrl === pp.cjsUrl,\n )\n }\n return false\n })\n}\n\nexport function removeAttr(obj: Record<string, unknown>, attr: string) {\n for (const prop in obj) {\n if (prop === attr) {\n delete obj[prop]\n } else if (typeof obj[prop] === 'object') {\n removeAttr(obj[prop] as Record<string, unknown>, attr)\n }\n }\n return obj\n}\n"],"names":["isUMDPluginDefinition","def","undefined","umdUrl","url","umdLoc","name","isESMPluginDefinition","esmUrl","esmLoc","isCJSPluginDefinition","cjsUrl","pluginDescriptionString","pluginDefinition","uri","PluginLoader","definitions","constructor","defs","args","this","fetchESM","fetchCJS","JSON","parse","stringify","loadCJSPlugin","baseUri","parsedUrl","URL","protocol","Error","href","loadESMPlugin","plugin","loadUMDPlugin","moduleName","umdName","jest","async","scriptUrl","Boolean","globalThis","src","Promise","resolve","reject","domLoadScript","err","script","importScripts","loadScript","default","Plugin","loadPlugin","isElectron","installGlobalReExports","target","JBrowseExports","Object","fromEntries","entries","ReExports","map","module","load","all","definition","adapterConfigCacheKey","conf","idMaker","adapterCache","getAdapter","pluginManager","sessionId","adapterConfigSnapshot","cacheKey","adapterType","type","dataAdapterType","getAdapterType","adapterConfig","configSchema","create","getSubAdapter","bind","dataAdapter","getAdapterClass","sessionIds","Set","cacheEntry","add","freeAdapterResources","specification","deleteCount","specKeys","keys","length","forEach","delete","size","values","regions","region","refName","freeResources","abortSignalCounter","abortSignalIds","WeakMap","serializeAbortSignal","signal","callfunc","abortSignalId","get","set","addEventListener","signalId","isRemoteAbortSignal","thing","surrogateAbortControllers","Map","deserializeAbortSignal","surrogateAbortController","AbortController","CascadingContext","React","parentPopupState","rootPopupState","CascadingMenuItem","onClick","closeAfterItemClick","props","useContext","MenuItem","_extends","event","close","CascadingSubmenu","title","Icon","inset","popupId","popupState","usePopupState","variant","bindHover","bindFocus","ListItemIcon","ListItemText","primary","ChevronRight","CascadingSubmenuHover","anchorOrigin","vertical","horizontal","transformOrigin","onMenuItemClick","menuItems","classes","context","useMemo","Provider","value","HoverMenu","bindMenu","CascadingMenu","Menu","EndDecoration","item","MenuItemEndDecoration","checked","disabled","CascadingMenuList","hasIcon","some","m","icon","sort","a","b","priority","idx","key","label","subMenu","Divider","component","ListSubheader","callback","secondary","subLabel","style","flexGrow","minWidth","rest","useStyles","makeStyles","theme","closeButton","position","right","spacing","top","color","palette","grey","DialogError","error","width","margin","ErrorMessage","observer","header","children","onClose","useTheme","MUIDialog","ScopedCssBaseline","DialogTitle","SanitizedHTML","html","IconButton","className","CloseIcon","ErrorBoundary","FallbackComponent","ThemeProvider","createTheme","components","MuiInputBase","styleOverrides","input","boxSizing","inputBase","typography","left","whiteSpace","visibility","inputRoot","padding","inputFocused","borderStyle","borderWidth","ref","setValue","other","ref2","useMeasure","editedValue","setEditedValue","useState","inputNode","setInputNode","blur","setBlur","useEffect","val","Typography","InputBase","inputRef","node","inputProps","root","focused","onChange","onKeyDown","onBlur","ErrorMessageStackTraceDialog","lazy","bg","background","divider","border","iconFloat","float","marginLeft","ErrorButtons","onReset","showStack","setShowStack","Tooltip","ReportIcon","RefreshIcon","Suspense","fallback","str","str2","indexOf","str3","slice","snapshotError","trim","findStr","match","exec","match2","parseError","RedErrorMessageBox","FactoryResetDialog","open","onFactoryReset","handleDialogClose","action","Dialog","DialogContent","DialogContentText","DialogActions","Button","ContentCopy","SvgIcon","d","Indexing","TrackSelector","Cable","getColors","midnight","forrest","grape","mandarin","gray","Logomark","viewBox","LogoFull","Text","colors","fill","transform","paper","overflowY","overflowX","minHeight","maxWidth","maxHeight","outline","menuItemEndDecoration","height","ArrowRightIcon","CheckBoxIcon","CheckBoxOutlineBlankIcon","RadioButtonCheckedIcon","RadioButtonUncheckedIcon","checkIfValid","MenuPage","subMenuAnchorEl","setSubMenuAnchorEl","openSubMenuIdx","setOpenSubMenuIdx","isSubMenuOpen","setIsSubMenuOpen","selectedMenuItemIdx","setSelectedMenuItemIdx","setPosition","paperRef","useRef","anchorEl","shouldSubMenuBeOpen","timer","setTimeout","clearTimeout","rect","getBoundingClientRect","menuItem","menuItemStyle","ListContents","MenuList","autoFocusItem","dense","endDecoration","MUIMenuItem","id","String","selected","onMouseMove","e","currentTarget","document","activeElement","focus","currentIdx","findLastIndex","findPreviousValidIdx","findIndex","findNextValidIdx","Grow","in","Paper","elevation","Popover","horizontalHandle","cursor","verticalHandle","flexbox_verticalHandle","alignSelf","flexbox_horizontalHandle","onDrag","flexbox","originalClassName","onMouseDown","mouseDragging","setMouseDragging","initialPosition","prevPos","cx","mouseMove","preventDefault","pos","clientX","clientY","totalDistance","current","lastFrameDistance","mouseUp","window","removeEventListener","model","handleClose","clearView","autoFocus","added","full","RegExp","tag","join","pre","linkify","test","escapeHTML","dompurify","tagName","setAttribute","dangerouslySetInnerHTML","__html","refTheme","forest","augmentColor","main","bases","A","green","C","blue","G","orange","T","red","framesCDS","frames","stopCodon","startCodon","stockTheme","mode","tertiary","quaternary","highlight","MuiLink","defaultThemes","lightStock","lightMinimal","darkMinimal","darkStock","MuiAppBar","defaultProps","enableColorOnDark","overwriteArrayMerge","_","sourceArray","createJBrowseBaseTheme","themeP","fontSize","MuiButton","text","MuiAccordion","disableGutters","slotProps","transition","timeout","unmountOnExit","MuiFilledInput","MuiFormControl","MuiFormHelperText","MuiIconButton","MuiAutocomplete","MuiInputLabel","MuiToolbar","MuiListItem","MuiOutlinedInput","MuiFab","backgroundColor","MuiTable","MuiPopover","transitionDuration","MuiMenu","MuiMenuItem","MuiTextField","MuiCheckbox","MuiRadio","MuiFormLabel","MuiAccordionSummary","content","contrastText","MuiToggleButtonGroup","deepmerge","arrayMerge","createJBrowseTheme","configTheme","themes","themeName","augmentTheme","augmentThemePlus","importFormEntry","session","InputProps","TextFieldProps","localStorageKey","helperText","assemblyNames","assemblyManager","config","URLSearchParams","location","search","lastSelected","setLastSelected","useLocalStorage","host","pathname","selection","includes","TextField","select","assembly","displayName","getConf","ToggleButtonWithTooltip","ToggleButton","shorten","len","Math","max","description","rootModel","setLocation","fileOrUrl","isUriLocation","toggleButtonValue","setToggleButtonValue","internetAccountId","accounts","isAppRootModel","internetAccounts","filter","f","recentlyUsedInternetAccounts","setRecentlyUsedInternetAccounts","arr","s","shownAccounts","hiddenAccounts","setAnchorEl","selectedAccount","setLocationWithAccount","useCallback","locationInput","UrlChooser","selectorLabel","LocalFileChooser","SelectorComponent","Box","display","InputLabel","shrink","flexDirection","ToggleButtonGroup","exclusive","_event","newState","notEmpty","toggleContents","ArrowDropDownIcon","FormHelperText","highResolutionScaling","imageData","blockKey","showSoftClip","done","setDone","featureCanvas","canvas","getContext","drawImageOntoCanvasContext","QuickLRU","options","super","maxSize","TypeError","maxAge","Number","POSITIVE_INFINITY","onEviction","cache","oldCache","_size","_emitEvictions","_deleteIfExpired","expiry","Date","now","_getOrDeleteIfExpired","_getItemValue","_peek","_set","_moveToRecent","_entriesAscending","has","peek","deleted","clear","resize","newSize","items","removeCount","Symbol","iterator","entriesDescending","i","entriesAscending","oldCacheSize","min","callbackFunction","thisArgument","call","toStringTag","useDebounce","delay","debouncedValue","setDebouncedValue","handle","useWidthSetter","view","isAlive","requestAnimationFrame","setWidth","parseInt","useDebouncedCallback","wait","argsRef","findParentThat","predicate","hasParent","currentNode","getParent","springAnimate","fromValue","toValue","onFinish","precision","tension","friction","clamp","animationFrameId","update","animation","time","lastPosition","lastTime","velocity","lastVelocity","numSteps","floor","isVelocity","abs","isDisplacement","cancelAnimationFrame","findParentThatIs","getSession","isSessionModel","getContainingView","isViewModel","getContainingTrack","isTrackModel","getContainingDisplay","isDisplayModel","assembleLocString","assembleLocStringFast","toLocale","cb","n","assemblyName","start","end","reversed","assemblyNameString","startString","endString","rev","parseLocStringOneBased","locString","isValidRefName","endsWith","replace","assemblyMatch","assemblyName2","location2","startsWith","lastColonIdx","lastIndexOf","prefix","suffix","rangeMatch","singleMatch","replaceAll","separator","parseLocString","parsed","compareLocs","locA","locB","assemblyComp","localeCompare","refComp","startComp","endComp","compareLocStrings","num","bpToPx","bp","bpPerPx","round","oneEightyOverPi","PI","piOverOneEighty","radToDeg","radians","degToRad","degrees","polarToCartesian","rho","theta","cos","sin","cartesianToPolar","x","y","sqrt","atan","featureSpanPx","feature","bpSpanPx","leftBp","rightBp","iterMap","iter","func","sizeHint","results","Array","from","counter","array","l","findLast","makeAbortableReaction","self","dataFunction","asyncReactionFunction","reactionOptions","startedFunction","successFunction","errorFunction","inProgress","handleError","isAbortException","console","addDisposer","reaction","data","mobxReactionHandle","aborted","abort","thisInProgress","result","checkAbortSignal","renameRegionIfNeeded","refNameMap","isStateTreeNode","newRef","getSnapshot","originalRefName","renameRegionsIfNeeded","assemblyMaps","getRefNameMapForAdapter","minmax","short","coord","oob","useAssemblyName","navigator","userAgent","revcom","seqString","reverse","complement","split","complementRegex","complementTable","S","w","r","N","K","Y","V","M","h","k","g","t","W","X","v","B","H","c","D","R","rIC","requestIdleCallback","widths","measureText","total","code","charCodeAt","getFrame","strand","phase","defaultStarts","defaultStops","defaultCodonTable","TCA","TCC","TCG","TCT","TTC","TTT","TTA","TTG","TAC","TAT","TAA","TAG","TGC","TGT","TGA","TGG","CTA","CTC","CTG","CTT","CCA","CCC","CCG","CCT","CAC","CAT","CAA","CAG","CGA","CGC","CGG","CGT","ATA","ATC","ATT","ATG","ACA","ACC","ACG","ACT","AAC","AAT","AAA","AAG","AGC","AGT","AGA","AGG","GTA","GTC","GTG","GTT","GCA","GCC","GCG","GCT","GAC","GAT","GAA","GAG","GGA","GGC","GGG","GGT","generateCodonTable","table","tempCodonTable","codon","aa","nucs","nuc","charAt","toUpperCase","toLowerCase","n0","j","n1","n2","updateStatus","msg","fn","res","hashCode","hash","objectHash","obj","bytesForRegions","index","blocksForRange","flat","block","minv","blockPosition","maxv","reduce","isSupportedIndexingAdapter","getBpDisplayStr","totalBp","parseFloat","toPrecision","toLocaleString","getTickDisplayStr","toFixed","getViewParams","exportSVG","dynamicBlocks","staticBlocks","offsetPx","contentBlocks","staticblock","staticblock1","offsetPx1","getLayoutId","layoutId","initialValue","storedValue","setStoredValue","localStorage","getItem","valueToStore","Function","setItem","getUriLink","getStr","isObject","coarseStripHTML","measureGridWidth","elements","stripHTML","element","getEnv","getEnvMST","localStorageGetItem","localStorageSetItem","init","NEGATIVE_INFINITY","entry","sum","avg","groupBy","push","mergeIntervals","intervals","stack","at","pop","gatherOverlaps","memo","flatMap","group","stripAlpha","colord","alpha","toHex","getStrokeProps","strokeOpacity","stroke","getFillProps","fillOpacity","renderToStaticMarkup","createRootFn","div","createElement","flushSync","render","innerHTML","isGzip","buf","getTrackAssemblyNames","track","getConfAssemblyNames","configuration","trackAssemblyNames","readConfObject","parent","getRpcSessionId","thisNode","highestRpcSessionId","isRoot","rpcSessionId","getParentRenderProps","renderProps","UNKNOWN","UNSUPPORTED","blobMap","getBlob","getBlobMap","setBlobMap","storeBlobLocation","blobId","blob","locationType","makeIndex","localPath","makeIndexType","typeA","typeB","getFileName","guessAdapter","file","adapterHint","adapter","evaluateExtensionPoint","_file","_index","_adapterHint","adapterGuesser","guessTrackType","trackType","_adapterName","trackTypeGuesser","generateUnsupportedTrackConf","trackName","trackUrl","categories","category","trackId","generateUnknownTrackConf","getTrackName","asm","assemblies","find","sequence","ElementId","types","optional","identifier","nanoid","NoAssemblyRegion","string","number","boolean","actions","setRefName","newRefName","Region","compose","LocalPathLocation","literal","BlobLocation","UriLocationRaw","maybe","internetAccountPreAuthorization","internetAccountType","authInfo","frozen","UriLocation","snapshotProcessor","postProcessor","snap","FileLocation","union","preProcessor","BaseSessionModel","_pluginManager","volatile","hovered","views","jbrowse","rpcManager","adminMode","textSearchManager","setSelection","clearSelection","setHovered","isBaseSession","ConnectionManagementSessionMixin","connectionInstances","pluggableMstType","connections","makeConnection","initialSnapshot","getConnectionType","prepareToBreakConnection","callbacksToDeref","derefTypeCount","connection","tracks","getReferring","removeReferring","breakConnection","remove","deleteConnection","deleteConnectionConf","addConnectionConf","connectionConf","clearConnections","isSessionWithConnections","AssemblyManager","DataManagementPlugin","exports","install","UCSCTrackHubConnectionF","AddTrackWidgetF","HierarchicalTrackSelectorWidgetF","AddConnectionWidgetF","PluginStoreWidgetF","configure","snackbarMessages","latestMessage","reason","popSnackbarMessage","MUISnackbar","Alert","severity","level","message","buttonRoot","hoverOpacity","menuTitle","setOpen","ArrowDropDown","logoPath","alt","grow","light","borderColor","HeaderButtons","savedSessionNames","menus","Toolbar","menu","DropDownMenu","arrow","EditableTypography","newName","notify","renameCurrentSession","AppLogo","DialogComponent","DialogProps","zIndex","bottom","minimized","activeWidgets","drawerPosition","Fab","showWidgetDrawer","LaunchIcon","selectPaper","m2","viewTypes","getElementTypeRecord","FormControl","Select","addView","IconButtonProps","IconProps","bindTrigger","MenuIcon","bindPopover","KeyboardDoubleArrowUpIcon","moveViewToTop","KeyboardArrowUpIcon","moveViewUp","KeyboardArrowDownIcon","moveViewDown","KeyboardDoubleArrowDownIcon","moveViewToBottom","paddingBottom","paddingTop","setDisplayName","viewHeader","viewTitle","alignItems","ViewButtons","onMinimize","AddIcon","MinimizeIcon","scrollRef","scrollIntoView","ViewMenu","focusedViewId","KeyboardArrowRightIcon","ViewContainerTitle","viewContainer","overflow","focusedView","unfocusedView","dark","handleSelectView","Element","contains","setFocusedViewId","ViewHeader","viewType","getViewType","ReactComponent","ViewContainer","removeView","setMinimized","LoadingEllipses","viewsContainer","gridRow","ViewPanel","ViewLauncher","DrawerWidget","colorScheme","appContainer","gridColumn","gridTemplateRows","appBar","LazyDrawerWidget","App","visibleWidget","drawerWidth","drawerVisible","grid","gridTemplateColumns","DialogQueue","AppBar","AppToolbar","ViewsContainer","AppFab","Snackbar","undoIdx","targetPath","history","notTrackingUndo","canUndo","canRedo","targetStore","snapshotDisposer","skipNextUndoState","stopTrackingUndo","resumeTrackingUndo","addUndoState","todos","splice","shift","beforeDestroy","initialize","resolvePath","onSnapshot","debounce","snapshot","undo","applySnapshot","redo","ConfigurationSchema","workerCount","defaultValue","explicitlyTyped","baseConfiguration","BaseRpcDriverConfigSchema","defaultDriver","drivers","MainThreadRpcDriverConfigSchema","WebWorkerRpcDriverConfigSchema","MainThreadRpcDriver","WebWorkerRpcDriver","addDriverConfig","configName","configSnapshot","isClonable","LazyWorker","driver","getWorker","workerP","makeWorker","then","worker","pingTime","rpcDriverClassName","watchWorker","maxPingTime","catch","destroy","status","BaseRpcDriver","lastWorkerAssignment","workerAssignments","workerCheckFrequency","filterArgs","isArray","AbortSignal","remoteAbort","File","functionName","createWorkerPool","hardwareConcurrency","mainThread","canDetect","detectHardwareConcurrency","workers","getWorkerPool","workerPool","workerNumber","workerAssignment","unextendedWorker","rpcMethod","getRpcMethodType","serializedArgs","serializeArguments","filteredAndSerializedArgs","callP","statusCallback","finally","killedCheckInterval","killedP","setInterval","clearInterval","resultP","race","deserializeReturn","WebWorkerHandle","Rpc","Client","terminate","funcName","opts","channel","listener","on","off","workerBootConfiguration","makeWorkerInstance","instance","log","postMessage","deserializeError","DummyHandle","_functionName","_filteredArgs","_options","pm","execute","RpcManager","static","rpcConfigSchema","mainConfiguration","backendConfigurations","driverObjects","getDriver","backendName","backendConfiguration","newDriver","plugins","runtimePluginDefinitions","windowHref","getDriverForCall","_sessionId","rpcDriverName","shareDiv","textAlign","paddingLeft","shareButton","ShareDialog","startIcon","ShareIcon","adminKey","useQueryParam","StringParam","adminServer","configPath","setSessionId","currentSessionId","JBrowseRootModel","JBrowseSession","response","fetch","method","headers","body","ok","CssBaseline","ShareButton","sessionQuery","password","loc","sessionTracks","tracklist","nav","initialTimestamp","sessionTriaged","sessionSnapshot","sessionSpec","blankSession","runtimePlugins","sessionPlugins","sessionError","configError","bc1","BroadcastChannel","bc2","isSharedSession","isSpecSession","isJb1StyleSession","isEncodedSession","isJsonSession","isLocalSession","ready","isSessionLoaded","isConfigLoaded","sessionTracksParsed","setSessionQuery","setConfigError","setSessionError","setRuntimePlugins","setSessionPlugins","setConfigSnapshot","setBlankSession","flag","setSessionTriaged","setSessionSnapshotSuccess","fetchPlugins","pluginLoader","import","fetchSessionPlugins","setSessionSnapshot","userAcceptedConfirmation","checkPlugins","origin","fetchConfig","__jbrowseConfigPath","__jbrowseCacheBuster","random","openLocation","readFile","configUri","addRelativeUris","hostname","configPlugins","fetchSessionStorageSession","sessionStr","sessionStorage","query","sessionSnap","onmessage","fetchSharedSession","decryptedSession","readSessionFromDynamo","readConf","fromUrlSafeB64","decodeEncodedUrlSession","decodeSessionSpec","decodeJb1StyleSession","decodeJsonUrlSession","afterCreate","lastAutosave","autorun","StartScreenErrorMessage","Worker","resolveIdentifier","refNameRegex","refNameColors","checkRefName","assemblyFactory","assemblyConfigType","adapterLoads","AbortablePromiseCache","adapterConf","when","refNameAliases","refNames","getCanonicalRefName","forwardMap","reverseMap","canonicalName","adapterName","loadRefNameMap","safeReference","loadingP","volatileRegions","lowerCaseRefNameAliases","cytobands","arg","initialized","aliases","hasName","allAliases","allRefNames","lowerCaseRefNames","allRefNamesWithLowerCase","getRefNameColor","setLoaded","setRegions","setRefNameAliases","setCytobands","setError","lowerCaseAliases","setLoadingP","p","loadPre","refNameAliasesAdapterConf","cytobandAdapterConf","sequenceAdapterConf","getRegions","getAssemblyRegions","adapterRegionsWithAssembly","refNameAliasCollection","getRefNameAliases","override","alias","getCytobands","getAdapterMapEntry","getReverseRefNameMapForAdapter","getData","SetDefaultSession","PreferencesDialog","RootModel","sessionModelFactory","assemblyConfigSchema","getTrackType","pluggableConfigSchemaType","preProcessSnapshot","explicitIdentifier","assemblyConfigSchemaFactory","jbrowseModelType","rpc","formatDetails","contextVariable","subfeatures","depth","maxDepth","formatAbout","hideUris","shareURL","disableAnalytics","hierarchical","trackNames","defaultCollapsed","categoryNames","topLevelCategories","subCategories","extraThemes","pluginConfigurationSchemas","aggregateTextSearchAdapters","defaultSession","JBrowseConfigF","addAssemblyConf","removeAssemblyConf","toRemove","addTrackConf","trackConf","elt","conn","deleteTrackConf","addPlugin","setPluginsUpdated","removePlugin","cast","setDefaultSessionConf","sessionConf","newDefault","toJS","addInternetAccountConf","internetAccountConf","deleteInternetAccountConf","JBrowseModelF","removeAttr","clone","jbrowseWebFactory","sessionModelType","sessionPath","assemblyNameMap","asmName","assemblyNamesList","assemblyList","sessionAssemblies","temporaryAssemblies","waitForAssembly","afterAttach","assemblyConfs","removeAssembly","addAssembly","fireImmediately","replaceAssembly","TextSearchManager","setSession","setDefaultSession","setSessionPath","path","BaseRootModelFactory","initializeInternetAccount","internetAccountConfig","getInternetAccountType","createEphemeralInternetAccount","hostUri","internetAccountSplit","domains","internetAccount","stateModel","findAppropriateInternetAccount","selectedId","account","handlesLocation","InternetAccountsRootModelMixin","TimeTraveller","ctrlKey","metaKey","shiftKey","setMenus","newMenus","appendMenu","menuName","insertMenu","appendToMenu","insertInMenu","insertPosition","appendToSubMenu","menuPath","topMenu","pathSoFar","sm","mi","insertInSubMenu","version","hydrateFn","hydrateRoot","createRoot","pluginsUpdated","savedSessionsVolatile","observable","savedSessions","localStorageId","autosaveId","previousAutosaveId","locationUrl","params","_val","alert","reload","oldSession","filterSessionInPlace","getType","newSession","sessionName","addSavedSession","removeSavedSession","removeItem","duplicateCurrentSession","newSnapshotName","newSnapshotCopyNumber","activateSession","localId","newSessionSnapshot","saveSessionToLocalStorage","loadAutosaveSession","previousAutosave","autosavedSession","PublishIcon","widget","addWidget","showWidget","GetAppIcon","sessionBlob","Blob","saveAs","FolderOpenIcon","SaveIcon","FileCopyIcon","StorageIcon","AppsIcon","queueDialog","UndoIcon","RedoIcon","ExtensionIcon","SettingsIcon","ReferenceManagementSessionMixin","object","refs","walk","isModelType","members","getMembers","properties","isReferenceType","referring","callbacks","dereferenceTypeCount","dereferenced","hideTrack","err1","isSessionModelWithWidgets","widgets","hideWidget","DrawerWidgetSessionMixin","widgetStateModelType","refinement","integer","setDrawerPosition","updateDrawerWidth","newDrawerWidth","resizeDrawer","distance","oldDrawerWidth","typeName","initialState","getElementType","hasWidget","minimizeWidgetDrawer","hideAllWidgets","editConfiguration","isConfigurationModel","editor","AboutDialog","BaseWebSession","sessionModel","queueOfDialogs","removeActiveDialog","sessionThemeName","allThemes","setThemeName","addLinearGenomeViewOfAssembly","addViewOfAssembly","displayRegionsFromAssemblyName","addViewFromAnotherView","otherView","state","displayedRegions","MultipleViewsSessionMixin","callbacksToDereferenceTrack","TracksManagerSessionMixin","named","superAddTrackConf","superDeleteTrackConf","found","SessionTracksManagerSessionMixin","assemblyConfigSchemasType","addSessionAssembly","warn","removeSessionAssembly","addTemporaryAssembly","removeTemporaryAssembly","TemporaryAssembliesMixin","sessionConnections","superDeleteConnection","superAddConnectionConf","connectionId","deletedConn","WebSessionConnectionsMixin","viewId","snackbarMessageSet","pushSnackbarMessage","removeSnackbarMessage","notifyError","errorMessage","extra","Report","task","setName","addSessionPlugin","removeSessionPlugin","editTrackConfiguration","getTrackActionMenuItems","canEdit","isRefSeq","InfoIcon","DeleteIcon","displays","displayId","CopyIcon","extendedSessionModel","createPluginManager","PluginManager","corePlugins","P","metadata","isCore","createPluggableElements","JBrowseRootModelFactory","afterInitializedCb","evaluateAsyncExtensionPoint","loadSessionSpec","initialSessionQuery","initialTimeStamp","multiAssemblyTracks","savedSessionCount","ver","stats","screen","innerHeight","innerWidth","electron","loadTime","jb2","qs","writeAWSAnalytics","pluginNames","analyticsScript","gaData","metric1","analyticsScriptNode","getElementsByTagName","append","writeGAAnalytics","doAnalytics","setRootModel","ConfigWarningDialog","SessionWarningDialog","StartScreen","normalize","param","Loader","Str","setPassword","setLoc","setSessionTracks","setAssembly","setTracks","setHighlight","setNav","setTrackList","loader","SessionLoader","Renderer","SessionTriaged","PluginManagerLoaded","JBrowse","factoryReset","setPluginManager","Loading","FatalErrorDialog","resetButtonText","QueryParamProvider","WindowHistoryAdapter","encrypt","toString","decrypt","AES","Utf8","getErrorMsg","shareSessionToDynamo","referer","sess","toUrlSafeB64","btoa","crypto","getRandomValues","Uint8Array","fromCharCode","encryptedSession","FormData","json","baseUrl","sessionQueryParam","encodeURIComponent","b64","originalB64","repeat","b64PadSuffix","toByteArray","inflate","inflated","TextDecoder","decode","bytes","TextEncoder","encode","deflate","fromByteArray","encoded","isArrayType","childType","getChildType","isValidReference","el","isMapType","child","getPropertyMembers","pname","ptype","base","attr","pluginsToCheck","storePlugins","statusText","every","pp","prop"],"sourceRoot":""} \ No newline at end of file