BiNgoViewer 2.3.4__tar.gz → 2.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/PKG-INFO +2 -1
  2. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/SOURCES.txt +1 -1
  3. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/PKG-INFO +2 -1
  4. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/README.md +1 -0
  5. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/__init__.py +1 -1
  6. bingoviewer-2.3.4/bingoviewer/frontend_dist/assets/index-Dbtbm6Rs.js → bingoviewer-2.3.5/bingoviewer/frontend_dist/assets/index-auU-stei.js +1 -1
  7. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/frontend_dist/index.html +1 -1
  8. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/main.py +1 -1
  9. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/pyproject.toml +1 -1
  10. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/dependency_links.txt +0 -0
  11. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/entry_points.txt +0 -0
  12. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/requires.txt +0 -0
  13. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/BiNgoViewer.egg-info/top_level.txt +0 -0
  14. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/__main__.py +0 -0
  15. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/cli.py +0 -0
  16. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/icon.py +0 -0
  17. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/install_shortcut.py +0 -0
  18. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/__init__.py +0 -0
  19. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/api/__init__.py +0 -0
  20. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/api/data.py +0 -0
  21. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/api/genome.py +0 -0
  22. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/api/tracks.py +0 -0
  23. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/__init__.py +0 -0
  24. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/annotation_reader.py +0 -0
  25. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/bam_reader.py +0 -0
  26. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/bigwig_reader.py +0 -0
  27. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/genbank_reader.py +0 -0
  28. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/genome_reader.py +0 -0
  29. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/readers/vcf_reader.py +0 -0
  30. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/bingoviewer/server/state.py +0 -0
  31. {bingoviewer-2.3.4 → bingoviewer-2.3.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BiNgoViewer
3
- Version: 2.3.4
3
+ Version: 2.3.5
4
4
  Summary: BiNgo Genome Viewer — a lightweight browser-based genomics viewer
5
5
  Author-email: Billy M Ngo <billy.ngo0108@gmail.com>
6
6
  License: Proprietary
@@ -101,6 +101,7 @@ Then open [http://localhost:8000](http://localhost:8000).
101
101
  | Problem | Solution |
102
102
  |---------|----------|
103
103
  | `python` not found | Install Python 3.10+ and check **Add to PATH** during setup |
104
+ | "No matching distribution" | Your Python is too old — BiNgo requires **Python 3.10+**. Check with `python --version` |
104
105
  | pip install fails | Try `pip install --user BiNgoViewer` or use a virtual environment |
105
106
  | Port 8000 in use | Run `bingo --port 9000` (or any free port) |
106
107
  | Browser doesn't open | Visit `http://localhost:8000` manually |
@@ -12,7 +12,7 @@ bingoviewer/cli.py
12
12
  bingoviewer/icon.py
13
13
  bingoviewer/install_shortcut.py
14
14
  bingoviewer/frontend_dist/index.html
15
- bingoviewer/frontend_dist/assets/index-Dbtbm6Rs.js
15
+ bingoviewer/frontend_dist/assets/index-auU-stei.js
16
16
  bingoviewer/server/__init__.py
17
17
  bingoviewer/server/main.py
18
18
  bingoviewer/server/state.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BiNgoViewer
3
- Version: 2.3.4
3
+ Version: 2.3.5
4
4
  Summary: BiNgo Genome Viewer — a lightweight browser-based genomics viewer
5
5
  Author-email: Billy M Ngo <billy.ngo0108@gmail.com>
6
6
  License: Proprietary
@@ -101,6 +101,7 @@ Then open [http://localhost:8000](http://localhost:8000).
101
101
  | Problem | Solution |
102
102
  |---------|----------|
103
103
  | `python` not found | Install Python 3.10+ and check **Add to PATH** during setup |
104
+ | "No matching distribution" | Your Python is too old — BiNgo requires **Python 3.10+**. Check with `python --version` |
104
105
  | pip install fails | Try `pip install --user BiNgoViewer` or use a virtual environment |
105
106
  | Port 8000 in use | Run `bingo --port 9000` (or any free port) |
106
107
  | Browser doesn't open | Visit `http://localhost:8000` manually |
@@ -73,6 +73,7 @@ Then open [http://localhost:8000](http://localhost:8000).
73
73
  | Problem | Solution |
74
74
  |---------|----------|
75
75
  | `python` not found | Install Python 3.10+ and check **Add to PATH** during setup |
76
+ | "No matching distribution" | Your Python is too old — BiNgo requires **Python 3.10+**. Check with `python --version` |
76
77
  | pip install fails | Try `pip install --user BiNgoViewer` or use a virtual environment |
77
78
  | Port 8000 in use | Run `bingo --port 9000` (or any free port) |
78
79
  | Browser doesn't open | Visit `http://localhost:8000` manually |
@@ -1,3 +1,3 @@
1
1
  """BiNgo Genome Viewer — a lightweight browser-based genomics viewer."""
2
2
 
3
- __version__ = "2.3.4"
3
+ __version__ = "2.3.5"
@@ -94,4 +94,4 @@ ${z.join(`
94
94
  `)}
95
95
 
96
96
  Tip: If files were moved, re-add them using the 📂 Path button.`):(x("Session restored"),setTimeout(()=>{x(null),e()},1200))}catch(Y){f(Y.message)}finally{m(!1)}}const A=jc(),R=ky(c);return s.jsx("div",{style:R.overlay,onClick:U=>{U.target===U.currentTarget&&e()},children:s.jsxs("div",{style:R.panel,children:[s.jsxs("div",{style:R.header,children:[s.jsx("span",{style:R.title,children:"Session"}),s.jsx("button",{style:R.closeBtn,onClick:e,children:"✕"})]}),s.jsxs("div",{style:R.body,children:[s.jsxs("div",{style:R.section,children:[s.jsx("div",{style:R.sectionTitle,children:"Save"}),s.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:s.jsx("button",{style:R.btn,onClick:b,disabled:!r||p,children:"Save to file"})}),s.jsx("div",{style:{fontSize:10,color:c.textTertiary,marginTop:4},children:"Session is also auto-saved to browser storage."})]}),s.jsxs("div",{style:R.section,children:[s.jsx("div",{style:R.sectionTitle,children:"Restore"}),s.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[s.jsx("button",{style:R.btn,onClick:j,disabled:p,children:"Load from file"}),A&&s.jsx("button",{style:R.btn,onClick:E,disabled:p,children:"Restore last session"})]}),s.jsx("input",{ref:w,type:"file",accept:".json",style:{display:"none"},onChange:S}),A&&s.jsxs("div",{style:{fontSize:10,color:c.textTertiary,marginTop:4},children:["Last auto-save: ",new Date(A.savedAt).toLocaleString(),A.genome&&` — ${A.genome.name}`,A.tracks&&` — ${A.tracks.length} tracks`]})]}),v&&s.jsx("div",{style:{padding:"4px 16px",fontSize:11,color:"#81c784"},children:v}),y&&s.jsx("div",{style:{padding:"4px 16px",fontSize:11,color:"#ef9a9a",whiteSpace:"pre-wrap"},children:y})]}),s.jsx("div",{style:R.footer,children:s.jsx("button",{style:R.btn,onClick:e,children:"Close"})})]})})}function ky(e){return{overlay:{position:"fixed",inset:0,background:e.overlayBg,display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3},panel:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:0,minWidth:380,maxWidth:480,maxHeight:"80vh",display:"flex",flexDirection:"column",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},header:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"10px 16px",borderBottom:`1px solid ${e.border}`},title:{fontSize:14,fontWeight:700,color:e.textPrimary},closeBtn:{background:"none",border:"none",color:e.textSecondary,cursor:"pointer",fontSize:18,lineHeight:1,padding:"0 4px"},body:{padding:"8px 0",overflowY:"auto",flex:1},section:{padding:"8px 16px"},sectionTitle:{fontSize:11,color:e.textSecondary,textTransform:"uppercase",letterSpacing:1,marginBottom:6},btn:{background:e.btnBg,border:"none",borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600},footer:{display:"flex",justifyContent:"flex-end",padding:"10px 16px",borderTop:`1px solid ${e.border}`}}}const ye=e=>s.jsx("strong",{children:e}),ue=({children:e})=>s.jsxs("div",{style:{display:"flex",gap:6,marginTop:4},children:[s.jsx("span",{style:{opacity:.5},children:"•"}),s.jsx("span",{children:e})]}),Rc=({children:e})=>s.jsx("span",{style:{background:"rgba(255,255,255,0.1)",borderRadius:3,padding:"0 4px",fontSize:11,fontFamily:"monospace"},children:e}),Cn=[{target:"file-loader",title:"Load Files",description:s.jsxs(s.Fragment,{children:["Upload genome and track files via:",s.jsxs(ue,{children:[ye("File picker"),' — click "Choose Files"']}),s.jsxs(ue,{children:[ye("Drag & drop")," — drop files anywhere on the app"]}),s.jsxs(ue,{children:[ye("Local path")," — paste a file path (best for large files)"]}),s.jsx("div",{style:{marginTop:8,opacity:.7},children:"Supported: FASTA, GenBank, BAM, BigWig, WIG, BedGraph, VCF, BED, GTF, GFF"})]}),position:"bottom"},{target:"nav-bar",title:"Navigation",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("Chromosome selector")," — switch between chromosomes"]}),s.jsxs(ue,{children:[ye("Coordinate input")," — type ",s.jsx(Rc,{children:"chr1:1000-5000"})," and press Go"]}),s.jsxs(ue,{children:[ye("- +")," — zoom out / zoom in"]}),s.jsxs(ue,{children:[ye("◀ ▶")," — pan left / pan right"]}),s.jsxs(ue,{children:[ye("Blue scrubber bar")," — click or drag to jump across the chromosome"]})]}),position:"bottom"},{target:"track-area",title:"Track Interaction",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("Left-click drag")," — pan the viewport"]}),s.jsxs(ue,{children:[ye("Scroll wheel")," — zoom in/out at cursor position"]}),s.jsxs(ue,{children:[ye("Right-click drag")," — select a region (hover for stats)"]}),s.jsxs(ue,{children:[ye("Double-click gene")," — zoom to fit that gene with context"]}),s.jsxs(ue,{children:[ye("Hover features")," — view detailed tooltips"]})]}),position:"inside"},{target:"skeleton-track-label",title:"Track Labels",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("≡ Drag handle")," — reorder tracks by dragging"]}),s.jsxs(ue,{children:[ye("Color swatch")," — click to pick a color"]}),s.jsxs(ue,{children:[ye("× Button")," — remove the track"]}),s.jsxs(ue,{children:[ye("Bottom edge")," — drag to resize track height"]})]}),position:"right"},{target:"btn-settings",title:"Track Settings",description:s.jsxs(s.Fragment,{children:["Select one or more tracks to adjust:",s.jsx(ue,{children:"Height, visibility, and fill color"}),s.jsx(ue,{children:"Bar width, peak outline trace + smoothness"}),s.jsxs(ue,{children:["Y-axis scale (auto / manual / log","₂",")"]}),s.jsx(ue,{children:"Annotation colors per feature type"}),s.jsx(ue,{children:"Read appearance — strand colors, arrow style & size"}),s.jsx(ue,{children:"Nucleotide display with mismatch highlighting"}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"The panel is draggable — adjust settings while viewing your data."})]}),position:"bottom",action:"open-settings"},{target:"header-btns",title:"Themes",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("5 built-in themes")," — Dark, Light, Colorblind, Soft, High Contrast"]}),s.jsxs(ue,{children:[ye("Custom themes")," — clone any preset and edit every color"]}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"Theme preferences persist across sessions."})]}),position:"bottom",action:"open-theme"},{target:"btn-export",title:"Export Image",description:s.jsxs(s.Fragment,{children:["Export the current view as ",ye("SVG")," or ",ye("PNG"),".",s.jsx(ue,{children:"Background, bars, outlines, and labels are separate SVG groups"}),s.jsx(ue,{children:"All track settings (colors, outlines, visibility) are respected"}),s.jsx(ue,{children:"Edit exported SVGs in Illustrator, Inkscape, or Figma"})]}),position:"bottom"},{target:"header-btns",title:"Sessions",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("Save to file")," — exports genome, tracks, region, zoom, colors, and all settings as JSON"]}),s.jsxs(ue,{children:[ye("Restore")," — reload a saved session or the last auto-save"]}),s.jsxs(ue,{children:[ye("Auto-save")," — your session saves to the browser automatically"]}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"An exit guard warns you before closing with unsaved work."})]}),position:"bottom"},{target:"file-loader",title:"Tips",description:s.jsxs(s.Fragment,{children:[s.jsxs(ue,{children:[ye("Large BAM files")," — use the ",s.jsxs(Rc,{children:["📂"," Path"]})," button to load by file path (no upload needed)"]}),s.jsxs(ue,{children:[ye("Large WIG files")," — convert to BigWig for instant loading"]}),s.jsxs(ue,{children:[ye("BAM + BAI")," — select both together, or load by path (index auto-discovered)"]}),s.jsxs(ue,{children:[ye("Updates")," — the app checks for updates automatically on launch"]})]}),position:"bottom"}],Tn=8,jn=14,Et=340,Cy=230,zr="rgba(0,0,0,0.55)";function Ty({onClose:e,theme:t,onAction:n}){const[r,o]=C.useState(0),[l,i]=C.useState(null),[a,u]=C.useState(Cy),c=C.useRef(null),h=Cn[r],d=r===0,g=r===Cn.length-1;C.useEffect(()=>{var S;const j=(S=Cn[r])==null?void 0:S.action;j&&n&&n(j)},[r,n]);const T=C.useCallback(j=>{var E;((E=Cn[j])==null?void 0:E.action)&&n&&n(null)},[n]),v=C.useCallback(()=>{T(r),r<Cn.length-1?o(j=>j+1):e()},[r,e,T]),x=C.useCallback(()=>{T(r),r>0&&o(j=>j-1)},[r,T]);C.useEffect(()=>{function j(S){S.key==="Escape"?e():S.key==="ArrowRight"||S.key==="Enter"?v():S.key==="ArrowLeft"&&x()}return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[e,v,x]),C.useEffect(()=>{function j(){const S=document.querySelector(`[data-tour="${h.target}"]`);if(S){const E=S.getBoundingClientRect();i({top:E.top,left:E.left,width:E.width,height:E.height})}else i(null)}return j(),window.addEventListener("resize",j),window.addEventListener("scroll",j,!0),()=>{window.removeEventListener("resize",j),window.removeEventListener("scroll",j,!0)}},[h.target]),C.useEffect(()=>{c.current&&u(c.current.getBoundingClientRect().height)});const y=l?{top:l.top-Tn,left:l.left-Tn,width:l.width+Tn*2,height:l.height+Tn*2}:null;let f,p,m=null,w=Et/2;if(!l)f=(window.innerHeight-a)/2,p=(window.innerWidth-Et)/2;else{const j=h.position||"bottom",S=l.top+l.height+Tn,E=l.top-Tn,$=l.left+l.width+Tn,A=l.left+l.width/2;j==="inside"?(f=l.top+Math.max(20,(l.height-a)/2),p=l.left+Math.max(16,(l.width-Et)/2)):j==="right"?(f=l.top+l.height/2-a/2,p=$+jn,m="left",w=a/2,p+Et>window.innerWidth-12&&(f=S+jn,p=A-Et/2,m="up",w=Math.max(20,Math.min(Et-20,A-p)))):(S+jn+a<=window.innerHeight?(f=S+jn,m="up"):E-jn-a>=0?(f=E-jn-a,m="down"):(f=S+jn,m="up"),l.width<200?(p=Math.max(12,l.left+l.width-Et),p<12&&(p=12)):p=A-Et/2,w=Math.max(20,Math.min(Et-20,A-p))),p=Math.max(12,Math.min(window.innerWidth-Et-12,p)),f=Math.max(12,Math.min(window.innerHeight-a-12,f))}const b={card:{position:"fixed",top:f,left:p,width:Et,zIndex:10002,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:10,padding:"20px 24px 16px",color:t.textPrimary,boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},stepCounter:{fontSize:11,fontWeight:600,color:t.textTertiary,textTransform:"uppercase",letterSpacing:1.2,marginBottom:10},title:{fontSize:16,fontWeight:700,marginBottom:6,color:t.textPrimary},description:{fontSize:13,lineHeight:1.6,color:t.textSecondary,marginBottom:20},dots:{display:"flex",justifyContent:"center",gap:8,marginBottom:14},dot:j=>({width:7,height:7,borderRadius:"50%",background:j?"#42a5f5":t.borderStrong,cursor:"pointer"}),nav:{display:"flex",alignItems:"center",justifyContent:"space-between"},btnPrimary:{background:"#1976d2",border:"none",borderRadius:5,color:"#fff",padding:"6px 18px",cursor:"pointer",fontSize:12,fontWeight:600},btnSecondary:{background:t.btnBg,border:`1px solid ${t.borderStrong}`,borderRadius:5,color:t.btnText,padding:"6px 14px",cursor:"pointer",fontSize:12,fontWeight:600},btnDisabled:{background:t.btnBg,border:`1px solid ${t.border}`,borderRadius:5,color:t.textMuted,padding:"6px 14px",fontSize:12,fontWeight:600,cursor:"default",opacity:.5},skip:{background:"none",border:"none",color:t.textTertiary,fontSize:11,cursor:"pointer",textDecoration:"underline",padding:0},arrowUp:{position:"absolute",top:-7,left:w-7,width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent",borderBottom:`7px solid ${t.panelBg}`},arrowDown:{position:"absolute",bottom:-7,left:w-7,width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent",borderTop:`7px solid ${t.panelBg}`},arrowLeft:{position:"absolute",left:-7,top:w-7,width:0,height:0,borderTop:"7px solid transparent",borderBottom:"7px solid transparent",borderRight:`7px solid ${t.panelBg}`}};return s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4},onClick:e}),y?s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{position:"fixed",top:0,left:0,right:0,height:Math.max(0,y.top),background:zr,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:y.top+y.height,left:0,right:0,bottom:0,background:zr,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:y.top,left:0,width:Math.max(0,y.left),height:y.height,background:zr,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:y.top,left:y.left+y.width,right:0,height:y.height,background:zr,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:y.top,left:y.left,width:y.width,height:y.height,borderRadius:6,border:"2px solid rgba(255,255,255,0.22)",zIndex:10001,pointerEvents:"none",boxSizing:"border-box"}})]}):s.jsx("div",{style:{position:"fixed",inset:0,background:zr,zIndex:10001,pointerEvents:"none"}}),s.jsxs("div",{ref:c,style:b.card,onClick:j=>j.stopPropagation(),children:[m==="up"&&s.jsx("div",{style:b.arrowUp}),m==="down"&&s.jsx("div",{style:b.arrowDown}),m==="left"&&s.jsx("div",{style:b.arrowLeft}),s.jsxs("div",{style:b.stepCounter,children:["Step ",r+1," of ",Cn.length]}),s.jsx("div",{style:b.title,children:h.title}),s.jsx("div",{style:b.description,children:h.description}),s.jsx("div",{style:b.dots,children:Cn.map((j,S)=>s.jsx("div",{style:b.dot(S===r),onClick:()=>o(S)},S))}),s.jsxs("div",{style:b.nav,children:[s.jsx("button",{style:b.skip,onClick:e,children:"Skip Tour"}),s.jsxs("div",{style:{display:"flex",gap:8},children:[s.jsx("button",{style:d?b.btnDisabled:b.btnSecondary,onClick:x,disabled:d,children:"Previous"}),s.jsx("button",{style:b.btnPrimary,onClick:v,children:g?"Finish":"Next"})]})]})]})]})}function jy(){const{theme:e}=Xe(),{genome:t,region:n,navigateTo:r,zoom:o,pan:l}=at(),[i,a]=C.useState(""),u=C.useRef(null),c=C.useRef(!1),h=C.useMemo(()=>{if(!t)return{toShort:{},toLong:{}};const w={},b={};return t.chromosomes.forEach((j,S)=>{const E=`chr${S+1}`;w[j.name]=E,b[E.toLowerCase()]=j.name,b[j.name.toLowerCase()]=j.name}),{toShort:w,toLong:b}},[t]);C.useEffect(()=>{if(n){const w=h.toShort[n.chrom]||n.chrom;a(`${w}:${n.start.toLocaleString()}-${n.end.toLocaleString()}`)}},[n,h]);const d=C.useMemo(()=>{if(!t||!n)return 0;const w=t.chromosomes.find(b=>b.name===n.chrom);return w?w.length:0},[t,n==null?void 0:n.chrom]),g=C.useCallback(w=>{if(!u.current||!n||!d)return;const b=u.current.getBoundingClientRect(),j=Math.max(0,Math.min(1,(w-b.left)/b.width)),S=n.end-n.start,E=j*d;r(n.chrom,E-S/2,E+S/2)},[n,d,r]),T=C.useCallback(w=>{w.preventDefault(),c.current=!0,g(w.clientX);function b(S){c.current&&g(S.clientX)}function j(){c.current=!1,window.removeEventListener("mousemove",b),window.removeEventListener("mouseup",j),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="grabbing",document.body.style.userSelect="none",window.addEventListener("mousemove",b),window.addEventListener("mouseup",j)},[g]),v={bar:{background:e.headerBg,borderBottom:`1px solid ${e.border}`,padding:"6px 12px",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},select:{background:e.inputBg,border:`1px solid ${e.borderAccent}`,borderRadius:4,color:e.textPrimary,padding:"4px 6px",fontSize:12},coordInput:{background:e.inputBg,border:`1px solid ${e.borderAccent}`,borderRadius:4,color:e.textPrimary,padding:"4px 8px",fontSize:12,width:220,fontFamily:"monospace"},btn:{background:e.btnBg,border:"none",borderRadius:4,color:e.btnText,padding:"4px 10px",cursor:"pointer",fontSize:13},info:{color:e.textSecondary,fontSize:11,marginLeft:8},scrubberWrap:{flex:1,minWidth:120,height:14,position:"relative",background:e.inputBg,borderRadius:7,border:`1px solid ${e.borderAccent}`,cursor:"pointer",overflow:"hidden"}};function x(w){if(!t)return;const b=t.chromosomes.find(j=>j.name===w.target.value);b&&r(b.name,0,Math.min(b.length,5e4))}function y(w){w.preventDefault();const j=i.replace(/,/g,"").trim().match(/^(\S+):(\d+)-(\d+)$/);if(j){const S=h.toLong[j[1].toLowerCase()]||j[1];r(S,parseInt(j[2]),parseInt(j[3]))}}if(!t)return s.jsx("div",{style:{...v.bar,opacity:.4},"data-tour":"nav-bar",children:s.jsx("span",{style:{fontSize:12,color:e.textMuted,fontStyle:"italic"},children:"Load a genome to enable navigation"})});const f=n?n.end-n.start:0;let p=0,m=100;return n&&d>0&&(p=n.start/d*100,m=Math.max(1,f/d*100)),s.jsxs("div",{style:v.bar,"data-tour":"nav-bar",children:[s.jsx("select",{style:v.select,value:(n==null?void 0:n.chrom)||"",onChange:x,children:t.chromosomes.map((w,b)=>s.jsxs("option",{value:w.name,children:["chr",b+1," ","—"," ",w.name," (",(w.length/1e3).toFixed(0)," kbp)"]},w.name))}),s.jsxs("form",{onSubmit:y,style:{display:"flex",gap:4},children:[s.jsx("input",{style:v.coordInput,value:i,onChange:w=>a(w.target.value),placeholder:"chr1:start-end"}),s.jsx("button",{style:v.btn,type:"submit",children:"Go"})]}),s.jsx("button",{style:v.btn,onClick:()=>o(2),title:"Zoom out",children:"-"}),s.jsx("button",{style:v.btn,onClick:()=>o(.5),title:"Zoom in",children:"+"}),s.jsx("button",{style:v.btn,onClick:()=>l(-f*.5),title:"Pan left",children:"◀"}),s.jsx("button",{style:v.btn,onClick:()=>l(f*.5),title:"Pan right",children:"▶"}),n&&d>0&&s.jsx("div",{ref:u,style:v.scrubberWrap,onMouseDown:T,title:"Drag to scroll across the chromosome",children:s.jsx("div",{style:{position:"absolute",left:`${p}%`,width:`${m}%`,top:1,bottom:1,background:"#42a5f5",borderRadius:6,minWidth:8,opacity:.7,transition:c.current?"none":"left 0.1s ease"}})}),n&&s.jsxs("span",{style:v.info,children:[f.toLocaleString()," bp"]})]})}function Pp(e){const{region:t,zoom:n,navigateTo:r,setSelection:o,clearSelection:l}=at(),i=C.useRef(null),a=C.useRef(null),u=C.useRef(t);u.current=t,C.useEffect(()=>{const c=e.current;if(!c)return;function h(x){const y=u.current;if(y){if(x.button===2){x.preventDefault();const f=c.getBoundingClientRect(),p=(x.clientX-f.left)/f.width,m=y.start+p*(y.end-y.start);a.current={startX:x.clientX,startBp:m,region:{...y},containerWidth:f.width};return}x.button===0&&(l(),i.current={x:x.clientX,startRegion:{...y},containerWidth:c.offsetWidth||c.clientWidth||1})}}function d(x){if(a.current){const j=a.current,S=c.getBoundingClientRect(),E=Math.max(0,Math.min(1,(x.clientX-S.left)/S.width)),$=j.region.start+E*(j.region.end-j.region.start),A=Math.min(j.startBp,$),R=Math.max(j.startBp,$);Math.abs(R-A)>=1&&o({chrom:j.region.chrom,start:Math.floor(A),end:Math.ceil(R)});return}if(!i.current)return;const y=x.clientX-i.current.x,{chrom:f,start:p,end:m}=i.current.startRegion,w=(m-p)/i.current.containerWidth,b=-y*w;r(f,p+b,m+b)}function g(x){if(a.current){a.current=null;return}i.current=null}function T(x){x.preventDefault()}function v(x){x.preventDefault();const y=c.getBoundingClientRect(),f=(x.clientX-y.left)/y.width,p=x.deltaY>0?1.4:.7;n(p,f)}return c.addEventListener("mousedown",h),c.addEventListener("contextmenu",T),window.addEventListener("mousemove",d),window.addEventListener("mouseup",g),c.addEventListener("wheel",v,{passive:!1}),()=>{c.removeEventListener("mousedown",h),c.removeEventListener("contextmenu",T),window.removeEventListener("mousemove",d),window.removeEventListener("mouseup",g),c.removeEventListener("wheel",v)}},[n,r,o,l,e])}const En=30;function Ey({width:e}){const t=C.useRef(null),n=C.useRef(null),{region:r,selection:o}=at(),{theme:l}=Xe();return Pp(t),C.useEffect(()=>{const i=n.current;if(!i||!r)return;const a=window.devicePixelRatio||1;i.width=e*a,i.height=En*a;const u=i.getContext("2d");u.scale(a,a);const{start:c,end:h}=r,d=h-c;if(u.clearRect(0,0,e,En),u.fillStyle=l.canvasBg,u.fillRect(0,0,e,En),o&&o.chrom===r.chrom){const p=(o.start-c)/d,m=(o.end-c)/d,w=Math.max(0,p*e),b=Math.min(e,m*e);b-w>=1&&(u.fillStyle="rgba(100, 181, 246, 0.25)",u.fillRect(w,0,b-w,En),u.strokeStyle="rgba(100, 181, 246, 0.6)",u.lineWidth=1,u.beginPath(),u.moveTo(w,0),u.lineTo(w,En),u.moveTo(b,0),u.lineTo(b,En),u.stroke())}const g=Math.min(10,Math.floor(e/80)),T=d/g,v=Math.pow(10,Math.floor(Math.log10(T))),x=[1,2,5,10].map(p=>p*v),y=x.find(p=>p>=T)||x[x.length-1],f=Math.ceil(c/y)*y;u.strokeStyle=l.rulerTick,u.fillStyle=l.rulerLabel,u.font="10px Arial, Helvetica, sans-serif",u.textAlign="center",u.beginPath(),u.moveTo(0,20),u.lineTo(e,20),u.lineWidth=1,u.stroke();for(let p=f;p<=h;p+=y){const m=(p-c)/d*e;u.beginPath(),u.moveTo(m,14),u.lineTo(m,20),u.stroke(),u.fillText(Ry(p),m,11)}},[r,o,e,l]),s.jsx("div",{ref:t,style:{position:"relative"},children:s.jsx("canvas",{ref:n,style:{display:"block",width:"100%",height:En}})})}function Ry(e){return e>=1e6?`${(e/1e6).toFixed(2)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function $i(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function Xn(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function Py({track:e,width:t,height:n,onWarning:r}){const o=C.useRef(null),{region:l}=at(),{theme:i}=Xe(),{data:a,loading:u,error:c}=ei(e,l,t);return C.useEffect(()=>{var Y,I;const h=o.current;if(!h)return;const d=window.devicePixelRatio||1;h.width=t*d,h.height=n*d;const g=h.getContext("2d");if(g.scale(d,d),g.clearRect(0,0,t,n),g.fillStyle=i.canvasBg,g.fillRect(0,0,t,n),u&&!((Y=a==null?void 0:a.bins)!=null&&Y.length)){g.fillStyle=i.textTertiary,g.font="11px Arial, Helvetica, sans-serif",g.fillText("Loading…",8,n/2+4),r&&r(null);return}if(c){g.fillStyle="#ef9a9a",g.font="11px Arial, Helvetica, sans-serif",g.fillText(typeof c=="string"?c:JSON.stringify(c),8,n/2+4),r&&r(null);return}if(!((I=a==null?void 0:a.bins)!=null&&I.length)){r&&r(null);return}const T=a.max_value||0,v=a.min_value||0,x=v<0,y=l.start,f=l.end-l.start,p=e.color||"#78909c",m=e.scaleMax!=null?e.scaleMax:null,w=e.scaleMin!=null?e.scaleMin:null,b=e.logScale===!0,j=e.barAutoWidth!==!1,S=e.barWidth||2,E=e.showOutline===!0,$=e.outlineColor||null,A=e.outlineSmooth||0,R=e.showBars!==!1,U=p,P=_y(p,-40),W=t/f;function O(L){return j?W>=1?Math.max(1,Math.min(W,L)):Math.max(1,L):Math.min(S,L)}if(x){const N=Math.round(n/2),D=N-12/2,z=n-N-12/2,F=m??(T||1),V=w??(Math.abs(v)||1);if(g.strokeStyle=i.centerLine,g.lineWidth=1,g.beginPath(),g.moveTo(0,N),g.lineTo(t,N),g.stroke(),R)for(const k of a.bins){const Q=(k.end-k.start)/f*t,ee=O(Q),ce=(k.start-y)/f*t,he=k.forward!=null?k.forward:Math.max(0,k.value),pe=k.reverse!=null?k.reverse:Math.min(0,k.value);if(he>0){const ae=b?Xn(he,F):he/F;g.fillStyle=U,g.fillRect(ce,N-ae*D,ee,ae*D)}if(pe<0){const ae=b?Xn(Math.abs(pe),V):Math.abs(pe)/V;g.fillStyle=P,g.fillRect(ce,N,ee,ae*z)}}if(E&&a.bins.length>0){const k=$||i.textPrimary||"#fff",Q=$||i.textPrimary||"#fff",ee=a.bins.map(ie=>{const ne=ie.forward!=null?ie.forward:Math.max(0,ie.value);return ne>0?b?Xn(ne,F):ne/F:0}),ce=a.bins.map(ie=>{const ne=ie.reverse!=null?ie.reverse:Math.min(0,ie.value);return ne<0?b?Xn(Math.abs(ne),V):Math.abs(ne)/V:0}),he=$i(ee,A),pe=$i(ce,A),ae=a.bins.map(ie=>((ie.start+ie.end)/2-y)/f*t);Ni(g,ae,he.map(ie=>N-ie*D),k,A>0),Ni(g,ae,pe.map(ie=>N+ie*z),Q,A>0)}const M=b?" log₂":"";$r(g,`+${F.toFixed(1)}${M}`,2,2,i),$r(g,`−${V.toFixed(1)}${M}`,2,n-12,i),$r(g,"0",2,N-6,i,!0)}else{const L=m??(T||1);if(R){g.fillStyle=U;for(const D of a.bins){const z=(D.end-D.start)/f*t,F=O(z),V=(D.start-y)/f*t,k=(b?Xn(D.value,L):D.value/L)*(n-14);g.fillRect(V,n-k-2,F,k)}}if(E&&a.bins.length>0){const D=a.bins.map(M=>b?Xn(M.value,L):M.value/L),z=$i(D,A),F=a.bins.map(M=>((M.start+M.end)/2-y)/f*t),V=z.map(M=>n-M*(n-14)-2);Ni(g,F,V,$||i.textPrimary||"#fff",A>0)}const N=b?" log₂":"";$r(g,`${L.toFixed(1)}${N}`,2,2,i),$r(g,"0",2,n-12,i,!0)}if(r){const L=[];m!=null&&T>m&&L.push(`Bars clipped: max value ${T.toFixed(1)} exceeds scale ${m.toFixed(1)}`),x&&w!=null&&Math.abs(v)>w&&L.push(`Negative bars clipped: min value ${Math.abs(v).toFixed(1)} exceeds scale ${w.toFixed(1)}`),r(L.length>0?L.join(`
97
- `):null)}},[a,u,c,t,n,l,e.color,e.scaleMax,e.scaleMin,e.logScale,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Ni(e,t,n,r,o){if(!(t.length<2)){if(e.beginPath(),e.moveTo(t[0],n[0]),o){for(let l=0;l<t.length-1;l++){const i=(t[l]+t[l+1])/2,a=(n[l]+n[l+1])/2;e.quadraticCurveTo(t[l],n[l],i,a)}e.lineTo(t[t.length-1],n[n.length-1])}else for(let l=0;l<t.length;l++)e.lineTo(t[l],n[l]);e.strokeStyle=r,e.lineWidth=1.5,e.stroke()}}function $r(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=e.measureText(t),a=2,u=i.width+a*2,c=12;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,u,c),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+a,r+1),e.textBaseline="alphabetic"}function _y(e,t){const n=e.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;const r=o=>Math.max(0,Math.min(255,o+t));return`rgb(${r(parseInt(n[1],16))},${r(parseInt(n[2],16))},${r(parseInt(n[3],16))})`}const Pc=6,Oi=8,Fi=14,Ii=2,Ly="#9c27b0",Vo=10,My={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"},By="#ffeb3b";function _c(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function Ay({track:e,width:t,height:n,onWarning:r}){const o=C.useRef(null),{region:l}=at(),{theme:i}=Xe(),{data:a,loading:u}=ei(e,l,t),[c,h]=C.useState(null),d=C.useRef(null),[g,T]=C.useState(0),v=C.useRef(null),x=e.showNucleotides!==!1,y=e.useArrows!==!1,f=e.logScale===!0,p=e.fwdColor||"#90a4ae",m=e.revColor||"#f06292",w=e.arrowStyle||"pointed",b=e.arrowSize||4,j=C.useRef(null);C.useEffect(()=>{if(l&&j.current){const $=j.current;($.chrom!==l.chrom||Math.abs($.start-l.start)>$.end-$.start)&&T(0)}j.current=l},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end]),C.useEffect(()=>{if(!l||!x){h(null);return}const $=l.end-l.start;if(t/$<Pc||$>2e3){h(null);return}if(c&&c.chrom===l.chrom&&c.start<=l.start&&c.end>=l.end)return;const R=Math.max(0,l.start-500),U=l.end+500,P=`${l.chrom}:${R}-${U}`;d.current!==P&&(d.current=P,yn.sequence(l.chrom,R,U).then(W=>h({chrom:l.chrom,start:R,end:U,sequence:W.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,x]);const S=C.useCallback($=>{var W;if(!((W=a==null?void 0:a.reads)!=null&&W.length)||!$.shiftKey&&Math.abs($.deltaX)>Math.abs($.deltaY))return;const A=x&&c?Fi:Oi,R=Math.max(0,...a.reads.map(O=>O.row)),U=Math.floor(n/(A+Ii)),P=Math.max(0,R-U+2);P<=0||($.preventDefault(),$.stopPropagation(),T(O=>Math.max(0,Math.min(P,O+Math.sign($.deltaY)*3))))},[a,n,x,c]);C.useEffect(()=>{var k;const $=o.current;if(!$)return;const A=window.devicePixelRatio||1;$.width=t*A,$.height=n*A;const R=$.getContext("2d");if(R.scale(A,A),R.clearRect(0,0,t,n),R.fillStyle=i.canvasBg,R.fillRect(0,0,t,n),u&&!a){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!a){r&&r(null);return}const U=l.start,P=l.end-l.start;if(a.bins){const Q=a.max_value||1,ee=e.scaleMax!=null?e.scaleMax:Q,ce=e.color||"#78909c",he=e.barAutoWidth!==!1,pe=e.barWidth||2,ae=t/P;if(e.showBars!==!1){R.fillStyle=ce;for(const ne of a.bins){const xe=(ne.end-ne.start)/P*t,Me=he?ae>=1?Math.max(1,Math.min(ae,xe)):Math.max(1,xe):Math.min(pe,xe),ve=(ne.start-U)/P*t,et=(f?_c(ne.value,ee):Math.min(1,ne.value/ee))*(n-14);R.fillRect(ve,n-et-2,Me,et)}}if(e.showOutline&&a.bins.length>0){const ne=e.outlineSmooth||0,xe=a.bins.map(me=>f?_c(me.value,ee):Math.min(1,me.value/ee)),Me=$y(xe,ne),ve=a.bins.map(me=>((me.start+me.end)/2-U)/P*t),Fe=Me.map(me=>n-me*(n-14)-2),et=e.outlineColor||i.textPrimary||"#fff";if(R.beginPath(),R.moveTo(ve[0],Fe[0]),ne>0){for(let me=0;me<ve.length-1;me++)R.quadraticCurveTo(ve[me],Fe[me],(ve[me]+ve[me+1])/2,(Fe[me]+Fe[me+1])/2);R.lineTo(ve[ve.length-1],Fe[Fe.length-1])}else for(let me=0;me<ve.length;me++)R.lineTo(ve[me],Fe[me]);R.strokeStyle=et,R.lineWidth=1.5,R.stroke()}const ie=f?" log₂":"";Lc(R,`${ee.toFixed(1)}${ie}`,2,2,i),Lc(R,"0",2,n-12,i,!0),R.fillStyle="#ffb74d",R.font="10px Arial, Helvetica, sans-serif",R.textAlign="right",R.fillText("zoom in for reads",t-4,10),r&&r(e.scaleMax!=null&&Q>e.scaleMax?`Bars clipped: max value ${Q.toFixed(1)} exceeds scale ${e.scaleMax.toFixed(1)}`:null);return}if(!((k=a.reads)!=null&&k.length)){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("No reads in region",8,n/2+4),r&&r(null);return}const W=Q=>(Q-U)/P*t,O=t/P,Y=x&&O>=Pc&&c!=null,I=Y?Fi:Oi,L=Ii,D=Math.max(0,...a.reads.map(Q=>Q.row))+1,z=Math.floor(n/(I+L)),F=D>z,V=Math.min(g,Math.max(0,D-z+1));let M=0;for(const Q of a.reads){const ee=(Q.row-V)*(I+L)+2;if(ee+I<0||ee>n){M++;continue}const ce=Q.strand==="+"?p:m,he=Q.segments;if(he&&he.length>0){const pe=W(Q.start),ae=W(Q.end);R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(pe,ee+I/2),R.lineTo(ae,ee+I/2),R.stroke();let ie=0;for(const ne of he)if(ne.type==="M"){const xe=W(ne.start),Me=Math.max(1,W(ne.end)-xe);if(R.fillStyle=ce,R.fillRect(xe,ee,Me,I),Y&&Q.sequence){const ve=ne.end-ne.start;for(let Fe=0;Fe<ve;Fe++){const et=ne.start+Fe,me=W(et),gt=W(et+1)-me,G=(Q.sequence[ie+Fe]||"").toUpperCase();let J="";c&&et>=c.start&&et<c.end&&(J=(c.sequence[et-c.start]||"").toUpperCase());const te=J&&G&&G!==J&&G!=="N";te&&(R.fillStyle=By,R.fillRect(me,ee,gt,I)),gt>=6&&(R.fillStyle=te?"#000":My[G]||"#999",R.font=`bold ${Math.min(11,gt-1)}px monospace`,R.textAlign="center",R.textBaseline="middle",R.fillText(G,me+gt/2,ee+I/2))}ie+=ve}}else if(ne.type==="D"){const xe=W(ne.start),Me=W(ne.end)-xe;Me>=1&&(R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(xe,ee+I/2),R.lineTo(xe+Me,ee+I/2),R.stroke())}else if(ne.type==="N"){const xe=W(ne.start),Me=W(ne.end)-xe;Me>=2&&(R.setLineDash([2,2]),R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(xe,ee+I/2),R.lineTo(xe+Me,ee+I/2),R.stroke(),R.setLineDash([]))}else ne.type==="I"?(R.fillStyle=Ly,R.fillRect(W(ne.pos)-1,ee-1,2,I+2),Y&&(ie+=ne.length)):ne.type==="S"&&Y&&(ie+=ne.length)}else{const pe=W(Q.start),ae=Math.max(2,W(Q.end)-pe);R.fillStyle=Q.strand==="+"?p:m,R.fillRect(pe,ee,ae,I)}if(y&&w!=="flat"){const pe=W(Q.start),ae=Math.max(2,W(Q.end)-pe),ie=Math.min(b,ae/2);ie>=2&&zy(R,w,Q.strand,pe,ee,ae,I,ie,ce,i.canvasBg)}if(!Y&&!x){const pe=W(Q.start);Math.max(2,W(Q.end)-pe)>60&&(R.fillStyle=i.canvasBg,R.font="8px Arial, Helvetica, sans-serif",R.textAlign="left",R.fillText(Q.name.slice(0,20),pe+2,ee+I-1))}}if(F){const Q=t-Vo;R.fillStyle=i.inputBg||"#2a2a2a",R.fillRect(Q,0,Vo,n);const ee=z/D,ce=Math.max(20,ee*n),pe=(D>z?V/(D-z):0)*(n-ce);R.fillStyle="#555",R.fillRect(Q+1,pe,Vo-2,ce)}r&&(M>0&&!F?r(`${M} read${M>1?"s":""} hidden — increase track height to show all`):r(F?`${D} rows · Shift+scroll or drag scrollbar to navigate`:null))},[a,u,t,n,l,c,g,e.color,e.scaleMax,e.scaleMin,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.showNucleotides,e.useArrows,e.logScale,e.fwdColor,e.revColor,e.arrowStyle,e.arrowSize,i]);const E=C.useCallback($=>{var D;if(!((D=a==null?void 0:a.reads)!=null&&D.length))return;const A=o.current;if(!A)return;const R=A.getBoundingClientRect();if(($.clientX-R.left)*(t/R.width)<t-Vo)return;const P=x&&c?Fi:Oi,O=Math.max(0,...a.reads.map(z=>z.row))+1,Y=Math.floor(n/(P+Ii)),I=Math.max(0,O-Y+1);if(I<=0)return;$.preventDefault(),v.current={maxScroll:I,startY:$.clientY,startRow:g};function L(z){if(!v.current)return;const F=z.clientY-v.current.startY,V=Math.round(F/n*v.current.maxScroll);T(Math.max(0,Math.min(v.current.maxScroll,v.current.startRow+V)))}function N(){v.current=null,window.removeEventListener("mousemove",L),window.removeEventListener("mouseup",N)}window.addEventListener("mousemove",L),window.addEventListener("mouseup",N)},[a,t,n,g,x,c]);return s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onWheel:S,onMouseDown:E})}function zy(e,t,n,r,o,l,i,a,u,c){const h=n==="+";if(t==="pointed")e.fillStyle=c,h?(e.beginPath(),e.moveTo(r+l,o+i/2),e.lineTo(r+l-a,o),e.lineTo(r+l-a,o+i),e.fill()):(e.beginPath(),e.moveTo(r,o+i/2),e.lineTo(r+a,o),e.lineTo(r+a,o+i),e.fill());else if(t==="chevron")e.strokeStyle=c,e.lineWidth=1.5,h?(e.beginPath(),e.moveTo(r+l-a,o),e.lineTo(r+l,o+i/2),e.lineTo(r+l-a,o+i),e.stroke()):(e.beginPath(),e.moveTo(r+a,o),e.lineTo(r,o+i/2),e.lineTo(r+a,o+i),e.stroke());else if(t==="fade")if(h){const d=e.createLinearGradient(r+l-a*2,0,r+l,0);d.addColorStop(0,"rgba(0,0,0,0)"),d.addColorStop(1,c),e.fillStyle=d,e.fillRect(r+l-a*2,o,a*2,i)}else{const d=e.createLinearGradient(r,0,r+a*2,0);d.addColorStop(0,c),d.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=d,e.fillRect(r,o,a*2,i)}}function $y(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function Lc(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=2,a=e.measureText(t).width+i*2;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,a,12),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+i,r+1),e.textBaseline="alphabetic"}const Ny=16,Oy=22,Fy=4,_p=8,Mc=6,Bc={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"};function Iy({track:e,width:t,height:n,onWarning:r}){var $,A,R,U;const o=C.useRef(null),{region:l,navigateTo:i}=at(),{tracks:a}=Jt(),{theme:u}=Xe(),{data:c,loading:h,error:d}=ei(e,l,t),g=e.useArrows!==!1,T=e.showNucleotides!==!1,v=C.useRef([]),[x,y]=C.useState(null),[f,p]=C.useState(null),m=C.useRef(null);C.useEffect(()=>{if(!l||!T){p(null);return}const P=l.end-l.start;if(t/P<Mc||P>2e3){p(null);return}if(f&&f.chrom===l.chrom&&f.start<=l.start&&f.end>=l.end)return;const O=Math.max(0,l.start-500),Y=l.end+500,I=`${l.chrom}:${O}-${Y}`;m.current!==I&&(m.current=I,yn.sequence(l.chrom,O,Y).then(L=>p({chrom:l.chrom,start:O,end:Y,sequence:L.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,T]),C.useEffect(()=>{var V,M;const P=o.current;if(!P)return;const W=window.devicePixelRatio||1;P.width=t*W,P.height=n*W;const O=P.getContext("2d");if(O.scale(W,W),O.clearRect(0,0,t,n),O.fillStyle=u.canvasBg,O.fillRect(0,0,t,n),v.current=[],h&&!((V=c==null?void 0:c.features)!=null&&V.length)){O.fillStyle=u.textTertiary,O.font="11px Arial, Helvetica, sans-serif",O.fillText("Loading…",8,n/2+4),r&&r(null);return}if(d){O.fillStyle="#ef9a9a",O.font="11px Arial, Helvetica, sans-serif",O.fillText(typeof d=="string"?d:JSON.stringify(d),8,n/2+4),r&&r(null);return}if(!((M=c==null?void 0:c.features)!=null&&M.length)){c&&(O.fillStyle=u.textTertiary,O.font="11px Arial, Helvetica, sans-serif",O.fillText("No features in region",8,n/2+4)),r&&r(null);return}const Y=l.end-l.start,I=t/Y,L=T&&I>=Mc&&f!=null,N=L?Oy:Ny,D=[],z=[];let F=0;if(L){const Q=n-14;O.fillStyle=u.canvasBg,O.fillRect(0,Q,t,14),O.strokeStyle=u.border||"#333",O.lineWidth=.5,O.beginPath(),O.moveTo(0,Q),O.lineTo(t,Q),O.stroke();const ee=Math.min(10,I-1);if(ee>=5){O.font=`bold ${ee}px monospace`,O.textAlign="center",O.textBaseline="middle";for(let ce=Math.floor(l.start);ce<Math.ceil(l.end);ce++)if(f&&ce>=f.start&&ce<f.end){const he=(f.sequence[ce-f.start]||"").toUpperCase(),pe=(ce-l.start)/Y*t;O.fillStyle=Bc[he]||"#999",O.fillText(he,pe+I/2,Q+14/2)}}}for(const k of c.features){let Q=D.findIndex(ae=>k.start>=ae);Q===-1&&(Q=D.length),D[Q]=k.end;const ee=(k.start-l.start)/Y*t,ce=Math.max(2,(k.end-k.start)/Y*t),he=Q*(N+Fy)+2;if(he+N>n){F++;continue}const pe=zc(k.feature_type,e,u);if(k.sub_features&&k.sub_features.length>0){O.fillStyle=pe+"66",O.fillRect(ee,he+N/2-1,ce,2);for(const ae of k.sub_features){const ie=(ae.start-l.start)/Y*t,ne=Math.max(1,(ae.end-ae.start)/Y*t),xe=zc(ae.feature_type,e,u),Me=ae.feature_type==="CDS"?N:N-6,ve=ae.feature_type==="CDS"?he:he+3;g?Ac(O,xe,ie,ve,ne,Me,ae.strand||k.strand):(O.fillStyle=xe,O.fillRect(ie,ve,ne,Me))}}else g?Ac(O,pe,ee,he,ce,N,k.strand):(O.fillStyle=pe,O.fillRect(ee,he,ce,N));if(L){const ae=Math.max(k.start,l.start),ie=Math.min(k.end,l.end);for(let ne=ae;ne<ie;ne++)if(f&&ne>=f.start&&ne<f.end){const xe=(f.sequence[ne-f.start]||"").toUpperCase(),Me=(ne-l.start)/Y*t,ve=I;ve>=6&&(O.fillStyle=Bc[xe]||"#999",O.font=`bold ${Math.min(10,ve-1)}px monospace`,O.textAlign="center",O.textBaseline="middle",O.fillText(xe,Me+ve/2,he+N/2))}}else if(ce>20){O.fillStyle="#fff",O.font="10px Arial, Helvetica, sans-serif",O.textAlign="left",O.textBaseline="alphabetic";const ae=k.name||k.feature_type,ie=Math.floor((ce-(g?_p:0)-4)/6);ie>0&&O.fillText(ae.slice(0,ie),ee+3,he+N-4)}z.push({feat:k,x:ee,y:he,w:ce,h:N})}v.current=z,r&&r(F>0?`${F} feature${F>1?"s":""} hidden — increase track height to show all`:null)},[c,h,d,t,n,l,f,e.color,e.annotationColors,g,e.showNucleotides,u]);const w=C.useCallback(P=>{const W=o.current;if(!W)return;const O=W.getBoundingClientRect(),Y=(P.clientX-O.left)*(t/O.width),I=(P.clientY-O.top)*(n/O.height);for(const L of v.current)if(Y>=L.x&&Y<=L.x+L.w&&I>=L.y&&I<=L.y+L.h){const N=Math.min(P.clientX+14,window.innerWidth-300),D=Math.min(P.clientY+14,window.innerHeight-260);y({feat:L.feat,x:Math.max(4,N),y:Math.max(4,D)});return}y(null)},[t,n]),b=C.useCallback(()=>y(null),[]),j=C.useCallback(P=>{const W=o.current;if(!W||!l)return;const O=W.getBoundingClientRect(),Y=(P.clientX-O.left)*(t/O.width),I=(P.clientY-O.top)*(n/O.height);for(const L of v.current)if(Y>=L.x&&Y<=L.x+L.w&&I>=L.y&&I<=L.y+L.h){const N=L.feat,z=(N.end-N.start)*.15/(1-.3),F=N.start-z,V=N.end+z;i(l.chrom,F,V),y(null);return}},[t,n,l,i]),S=x?Dy(x.feat,a,l==null?void 0:l.chrom):[],E=x?Wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:x.x,top:x.y,background:u.tooltipBg,border:`1px solid ${u.tooltipBorder}`,borderRadius:4,padding:"6px 10px",color:u.textPrimary,fontSize:11,lineHeight:1.5,maxWidth:280,zIndex:1e4,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:[s.jsx("div",{style:{fontWeight:700,fontSize:12,marginBottom:2},children:x.feat.name||x.feat.feature_type}),s.jsx(en,{label:"Type",value:x.feat.feature_type}),s.jsx(en,{label:"Strand",value:x.feat.strand||"."}),s.jsx(en,{label:"Location",value:`${x.feat.start.toLocaleString()}–${x.feat.end.toLocaleString()}`}),s.jsx(en,{label:"Length",value:`${(x.feat.end-x.feat.start).toLocaleString()} bp`}),(($=x.feat.attributes)==null?void 0:$.gene)&&x.feat.attributes.gene!==x.feat.name&&s.jsx(en,{label:"Gene",value:x.feat.attributes.gene}),((A=x.feat.attributes)==null?void 0:A.locus_tag)&&s.jsx(en,{label:"Locus",value:x.feat.attributes.locus_tag}),((R=x.feat.attributes)==null?void 0:R.product)&&s.jsx(en,{label:"Product",value:x.feat.attributes.product}),((U=x.feat.attributes)==null?void 0:U.note)&&s.jsx(en,{label:"Note",value:String(x.feat.attributes.note).slice(0,120)}),S.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{borderTop:`1px solid ${u.tooltipBorder}`,margin:"4px 0",paddingTop:4},children:s.jsx("span",{style:{color:u.textSecondary,fontWeight:600,fontSize:10,textTransform:"uppercase"},children:"Track totals in gene"})}),S.map(P=>s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:8},children:[s.jsx("span",{style:{color:u.textSecondary,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1},children:P.name}),s.jsx("span",{style:{color:u.textPrimary,fontWeight:600,flexShrink:0},children:P.total.toFixed(1)})]},P.trackId))]})]}),document.body):null;return s.jsxs("div",{style:{position:"relative",width:"100%",height:n},children:[s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onMouseMove:w,onMouseLeave:b,onDoubleClick:j}),E]})}function en({label:e,value:t}){return t?s.jsxs("div",{style:{display:"flex",gap:6},children:[s.jsxs("span",{style:{opacity:.6,flexShrink:0},children:[e,":"]}),s.jsx("span",{children:t})]}):null}function Dy(e,t,n){var o;if(!e||!n)return[];const r=[];for(const l of t){if(l.track_type!=="coverage"&&l.track_type!=="reads")continue;const i=ly(l.id,n);if(!((o=i==null?void 0:i.bins)!=null&&o.length))continue;let a=0;for(const u of i.bins){if(u.end<=e.start||u.start>=e.end)continue;const c=u.forward!=null?u.forward:Math.max(0,u.value||0),h=u.reverse!=null?Math.abs(u.reverse):Math.abs(Math.min(0,u.value||0));a+=c+h}a>0&&r.push({trackId:l.id,name:l.name,total:a})}return r}function Ac(e,t,n,r,o,l,i){e.fillStyle=t;const a=Math.min(_p,o*.4);e.beginPath(),i==="+"?(e.moveTo(n,r),e.lineTo(n+o-a,r),e.lineTo(n+o,r+l/2),e.lineTo(n+o-a,r+l),e.lineTo(n,r+l),e.closePath()):i==="-"?(e.moveTo(n+a,r),e.lineTo(n+o,r),e.lineTo(n+o,r+l),e.lineTo(n+a,r+l),e.lineTo(n,r+l/2),e.closePath()):e.rect(n,r,o,l),e.fill(),e.strokeStyle="rgba(0,0,0,0.25)",e.lineWidth=.5,e.stroke()}function zc(e,t,n){const r=t.annotationColors;switch(e==null?void 0:e.toLowerCase()){case"cds":return(r==null?void 0:r.cds)||(n==null?void 0:n.geneCds)||"#66bb6a";case"exon":return(r==null?void 0:r.exon)||(n==null?void 0:n.geneExon)||"#42a5f5";case"gene":return(r==null?void 0:r.gene)||(n==null?void 0:n.geneGene)||"#7e57c2";case"mrna":case"transcript":return(r==null?void 0:r.transcript)||(n==null?void 0:n.geneTranscript)||"#ab47bc";case"utr":case"3utr":case"5utr":return(r==null?void 0:r.utr)||(n==null?void 0:n.geneUtr)||"#26c6da";case"rrna":return(r==null?void 0:r.rrna)||(n==null?void 0:n.geneRrna)||"#ffa726";case"trna":return(r==null?void 0:r.trna)||(n==null?void 0:n.geneTrna)||"#ef5350";case"repeat_region":return(r==null?void 0:r.repeat)||(n==null?void 0:n.geneRepeat)||"#8d6e63";default:return(r==null?void 0:r.default)||t.color||(n==null?void 0:n.geneDefault)||"#80cbc4"}}function Uy({track:e,width:t,height:n,onWarning:r}){const o=C.useRef(null),{region:l}=at(),{theme:i}=Xe(),{data:a,loading:u}=ei(e,l,t);return C.useEffect(()=>{var f,p;const c=o.current;if(!c)return;const h=window.devicePixelRatio||1;c.width=t*h,c.height=n*h;const d=c.getContext("2d");if(d.scale(h,h),d.clearRect(0,0,t,n),d.fillStyle=i.canvasBg,d.fillRect(0,0,t,n),u&&!((f=a==null?void 0:a.variants)!=null&&f.length)){d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!((p=a==null?void 0:a.variants)!=null&&p.length)){a&&(d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("No variants in region",8,n/2+4)),r&&r(null);return}const g=l.end-l.start,T=e.barAutoWidth!==!1,v=e.barWidth||2,x=T?1:Math.max(.5,v),y=T?5:Math.max(2,v*2);for(const m of a.variants){const w=(m.pos-l.start)/g*t,b=Wy(m.ref,m.alt);d.strokeStyle=b,d.lineWidth=x,d.beginPath(),d.moveTo(w,n-4),d.lineTo(w,14),d.stroke(),d.fillStyle=b,d.beginPath(),d.arc(w,10,y,0,Math.PI*2),d.fill(),g<5e3&&(d.fillStyle=i.textPrimary,d.font="9px Arial, Helvetica, sans-serif",d.textAlign="center",d.fillText(`${m.ref}>${m.alt[0]||"?"}`,w,n-6))}if(r){const m=a.variants.filter(w=>w.pos>=l.start&&w.pos<=l.end).length;r(m>50?`${m} variants overlapping — zoom in for detail`:null)}},[a,u,t,n,l,e.color,e.barAutoWidth,e.barWidth,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Wy(e,t){const n=t[0]||"";return e.length===1&&n.length===1?"#ffb74d":n.length>e.length?"#81c784":n.length<e.length?"#e57373":"#b0bec5"}function Hy({message:e,theme:t}){const[n,r]=C.useState(!1),o=C.useRef(null),l=o.current?o.current.getBoundingClientRect():null;return s.jsxs(s.Fragment,{children:[s.jsx("span",{ref:o,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:12,height:12,borderRadius:"50%",background:"rgba(229, 57, 53, 0.85)",color:"#fff",fontSize:9,fontWeight:800,lineHeight:1,cursor:"default",flexShrink:0,fontFamily:"Arial, Helvetica, sans-serif"},children:"!"}),n&&l&&Wn.createPortal(s.jsx("div",{style:{position:"fixed",left:Math.min(l.right+6,window.innerWidth-220),top:l.top-4,background:t.tooltipBg||"#333",border:`1px solid ${t.tooltipBorder||"#555"}`,borderRadius:4,padding:"4px 8px",color:t.textPrimary||"#e0e0e0",fontSize:11,lineHeight:1.4,maxWidth:200,zIndex:10001,pointerEvents:"none",boxShadow:"0 3px 10px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",fontFamily:"Arial, Helvetica, sans-serif"},children:e}),document.body)]})}function Vy({width:e,height:t,trackData:n,trackType:r}){const{region:o,selection:l,clearSelection:i}=at(),{theme:a}=Xe(),[u,c]=C.useState(!1),[h,d]=C.useState({x:0,y:0}),g=C.useRef(null),T=C.useCallback(A=>{d({x:A.clientX,y:A.clientY}),c(!0)},[]),v=C.useCallback(()=>c(!1),[]);if(!l||!o||l.chrom!==o.chrom)return null;const x=o.end-o.start;if(x<=0)return null;const y=(l.start-o.start)/x,f=(l.end-o.start)/x,p=Math.max(0,y*e),w=Math.min(e,f*e)-p;if(w<1)return null;const b=Gy(l,n,r),j=l.end-l.start,S=260,E=Math.min(h.x+14,window.innerWidth-S-10),$=Math.min(h.y+14,window.innerHeight-200);return s.jsxs("div",{ref:g,style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none"},children:[s.jsx("div",{style:{position:"absolute",left:p,top:0,width:w,height:"100%",background:"rgba(100, 181, 246, 0.2)",borderLeft:"1px solid rgba(100, 181, 246, 0.6)",borderRight:"1px solid rgba(100, 181, 246, 0.6)",pointerEvents:"auto",cursor:"crosshair"},onMouseMove:T,onMouseLeave:v,onClick:A=>{A.stopPropagation(),i()}}),u&&Wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:E,top:$,background:a.panelBg,border:`1px solid ${a.borderAccent}`,borderRadius:6,padding:"8px 12px",fontSize:11,color:a.textPrimary,lineHeight:1.6,pointerEvents:"none",zIndex:1e4,boxShadow:"0 4px 16px rgba(0,0,0,0.4)",minWidth:180,maxWidth:S},children:[s.jsx("div",{style:{fontWeight:700,marginBottom:4,fontSize:12},children:"Selected Region"}),s.jsxs("div",{children:[s.jsx("span",{style:{color:a.textSecondary},children:"Region:"})," ",l.chrom,":",l.start.toLocaleString(),"-",l.end.toLocaleString()]}),s.jsxs("div",{children:[s.jsx("span",{style:{color:a.textSecondary},children:"Length:"})," ",j.toLocaleString()," bp"]}),b.map((A,R)=>s.jsxs("div",{children:[s.jsxs("span",{style:{color:a.textSecondary},children:[A.label,":"]})," ",A.value]},R)),s.jsx("div",{style:{fontSize:9,color:a.textTertiary,marginTop:4},children:"Click to dismiss"})]}),document.body)]})}function Gy(e,t,n){const r=[];if(!t)return r;if(n==="reads"&&t.reads){const o=t.reads.filter(i=>i.end>e.start&&i.start<e.end);r.push({label:"Reads in region",value:o.length.toLocaleString()});let l=0;for(const i of o)if(i.cigar){const a=i.cigar.match(/(\d+)I/g);if(a)for(const u of a)l+=parseInt(u)}if(l>0&&r.push({label:"Insertion bases",value:l.toLocaleString()}),o.length>0){const i=o.reduce((a,u)=>a+(u.mapq||0),0)/o.length;r.push({label:"Avg MAPQ",value:i.toFixed(1)})}}if((n==="coverage"||n==="reads")&&t.bins){const o=t.bins.filter(l=>l.end>e.start&&l.start<e.end);if(o.length>0){const l=o.map(c=>c.value),i=l.reduce((c,h)=>c+h,0)/l.length,a=Math.max(...l),u=Math.min(...l);r.push({label:"Avg coverage",value:i.toFixed(1)}),r.push({label:"Max coverage",value:a.toFixed(1)}),u!==a&&r.push({label:"Min coverage",value:u.toFixed(1)})}}if(n==="variants"&&t.variants){const o=t.variants.filter(l=>l.pos>=e.start&&l.pos<e.end);r.push({label:"Variants in region",value:o.length.toLocaleString()})}if((n==="annotations"||n==="genome_annotations")&&t.features){const o=t.features.filter(l=>l.end>e.start&&l.start<e.end);r.push({label:"Features in region",value:o.length.toLocaleString()})}return r}class Yy extends C.Component{constructor(t){super(t),this.state={hasError:!1,error:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}render(){var t;return this.state.hasError?s.jsxs("div",{style:{padding:8,color:"#ef9a9a",fontSize:11},children:["Track error: ",((t=this.state.error)==null?void 0:t.message)||"Unknown error"]}):this.props.children}}function Qy({track:e,containerWidth:t,labelWidth:n=140,onLabelResizeStart:r,isDragging:o,isDropTarget:l,onDragStart:i,onDragOver:a,onDrop:u,onDragEnd:c}){const{theme:h}=Xe(),{updateTrack:d,removeTrack:g}=Jt(),T=C.useRef(null),v=C.useRef(null),[x,y]=C.useState(!1),[f,p]=C.useState(!1),[m,w]=C.useState(null),b=C.useRef(null),j=C.useRef(null),S=e.track_type==="annotations"||e.track_type==="genome_annotations";Pp(T);const E=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],$=t-n,A={row:{display:"flex",borderBottom:`1px solid ${h.border}`,minHeight:40},label:{width:n,minWidth:n,background:h.panelBg,borderRight:`1px solid ${h.border}`,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 8px",overflow:"hidden",position:"relative"},trackName:{fontSize:11,color:h.trackName,fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},trackType:{fontSize:10,color:h.textTertiary,marginTop:2},trackArea:{flex:1,overflow:"hidden",position:"relative"}},R=C.useCallback(P=>{P.preventDefault(),P.stopPropagation();const W=P.clientY,O=e.height;function Y(L){const N=Math.max(30,Math.min(500,O+(L.clientY-W)));d(e.id,{height:N})}function I(){window.removeEventListener("mousemove",Y),window.removeEventListener("mouseup",I),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ns-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",Y),window.addEventListener("mouseup",I)},[e.id,e.height,d]);function U(){const P={track:e,width:$,height:e.height,onWarning:w};switch(e.track_type){case"reads":return s.jsx(Ay,{...P});case"coverage":return s.jsx(Py,{...P});case"variants":return s.jsx(Uy,{...P});case"annotations":case"genome_annotations":return s.jsx(Iy,{...P});default:return s.jsx("div",{style:{padding:8,color:h.textTertiary,fontSize:11},children:"Unknown track type"})}}return s.jsxs("div",{style:{...A.row,height:e.height,position:"relative",opacity:o?.4:1,borderTop:l?"2px solid #888":void 0},onDragOver:P=>{P.preventDefault(),P.dataTransfer.dropEffect="move",a==null||a()},onDrop:P=>{P.preventDefault(),u==null||u()},onDragEnd:c,children:[s.jsxs("div",{style:A.label,children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("div",{draggable:!0,onDragStart:P=>{P.dataTransfer.effectAllowed="move",P.dataTransfer.setData("text/plain",e.id),i==null||i()},style:{cursor:"grab",color:h.textMuted,fontSize:14,lineHeight:1,userSelect:"none",flexShrink:0,padding:"0 2px"},title:"Drag to reorder tracks",children:"≡"}),s.jsx("div",{ref:b,children:S?s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:"#888",cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)",backgroundImage:"linear-gradient(135deg, #ef5350 25%, #66bb6a 25%, #66bb6a 50%, #42a5f5 50%, #42a5f5 75%, #ffa726 75%)"},title:"Click to customize annotation colors",onMouseDown:P=>{P.stopPropagation(),p(W=>!W)}}),f&&Wn.createPortal(s.jsx(Jy,{track:e,theme:h,anchorRef:b,onClose:()=>p(!1),onChange:(P,W)=>{const O={...e.annotationColors||{},[P]:W};d(e.id,{annotationColors:O})},onReset:()=>d(e.id,{annotationColors:null})}),document.body)]}):s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:e.color,cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)"},title:"Click to pick color, double-click for full palette",onMouseDown:P=>{P.stopPropagation(),y(!0)},onDoubleClick:P=>{var W;P.stopPropagation(),y(!1),(W=j.current)==null||W.click()}}),s.jsx("input",{ref:j,type:"color",value:e.color||"#78909c",onChange:P=>d(e.id,{color:P.target.value}),style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0}}),x&&Wn.createPortal(s.jsx("div",{style:{position:"fixed",left:b.current?b.current.getBoundingClientRect().left:0,top:b.current?b.current.getBoundingClientRect().bottom+4:0,zIndex:10001,background:h.panelBg,border:`1px solid ${h.borderAccent}`,borderRadius:4,padding:6,boxShadow:"0 4px 12px rgba(0,0,0,0.5)",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},onMouseLeave:()=>y(!1),children:E.map(P=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:P,cursor:"pointer",border:P===e.color?`2px solid ${h.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onMouseUp:()=>{d(e.id,{color:P}),y(!1)}},P))}),document.body)]})}),s.jsx("div",{style:{...A.trackName,flex:1},title:e.name,children:e.name}),s.jsx("span",{title:"Remove track",onClick:P=>{P.stopPropagation(),g(e.id)},style:{color:"#e53935",fontSize:13,fontWeight:700,cursor:"pointer",lineHeight:1,flexShrink:0,padding:"0 2px",opacity:.7,transition:"opacity 0.15s"},onMouseEnter:P=>P.currentTarget.style.opacity="1",onMouseLeave:P=>P.currentTarget.style.opacity="0.7",children:"×"})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsxs("div",{style:A.trackType,children:[e.file_format," · ",e.track_type]}),m&&s.jsx(Hy,{message:m,theme:h})]}),r&&s.jsx("div",{onMouseDown:r,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:P=>P.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:P=>P.currentTarget.style.background="transparent"})]}),s.jsxs("div",{style:A.trackArea,ref:T,children:[s.jsx(Yy,{children:U()}),s.jsx(Vy,{width:$,height:e.height,trackData:jp(e.id),trackType:e.track_type})]}),s.jsx("div",{ref:v,onMouseDown:R,title:"Drag to resize track height",style:{position:"absolute",left:0,right:0,bottom:-2,height:5,cursor:"ns-resize",zIndex:10,background:"transparent"},onMouseEnter:P=>P.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:P=>P.currentTarget.style.background="transparent"})]})}const Xy=[{key:"cds",label:"CDS"},{key:"exon",label:"Exon"},{key:"gene",label:"Gene"},{key:"transcript",label:"Transcript"},{key:"utr",label:"UTR"},{key:"rrna",label:"rRNA"},{key:"trna",label:"tRNA"},{key:"repeat",label:"Repeat"},{key:"default",label:"Other"}],Ky=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],qy={cds:"geneCds",exon:"geneExon",gene:"geneGene",transcript:"geneTranscript",utr:"geneUtr",rrna:"geneRrna",trna:"geneTrna",repeat:"geneRepeat",default:"geneDefault"};function Jy({track:e,theme:t,anchorRef:n,onClose:r,onChange:o,onReset:l}){var x;const[i,a]=C.useState(null),u=C.useRef(null),[c,h]=C.useState(null),d=e.annotationColors||{},g=(x=n.current)==null?void 0:x.getBoundingClientRect();function T(y){return d[y]||t[qy[y]]||Sp[y]}function v(y){h(y),u.current&&(u.current.value=T(y),u.current.click())}return s.jsxs("div",{style:{position:"fixed",left:g?Math.min(g.left,window.innerWidth-220):0,top:g?g.bottom+4:0,zIndex:10001,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:6,padding:"8px 0",boxShadow:"0 6px 20px rgba(0,0,0,0.5)",width:210,maxHeight:340,overflowY:"auto"},onMouseLeave:r,children:[s.jsx("div",{style:{fontSize:10,fontWeight:700,color:t.textSecondary,textTransform:"uppercase",letterSpacing:1,padding:"0 10px 6px",borderBottom:`1px solid ${t.border}`,marginBottom:4},children:"Annotation Colors"}),Xy.map(({key:y,label:f})=>{const p=T(y);return s.jsxs("div",{children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 10px",cursor:"pointer",fontSize:11,color:t.textPrimary},onMouseEnter:m=>m.currentTarget.style.background=t.selectedRow,onMouseLeave:m=>m.currentTarget.style.background="transparent",onClick:()=>a(i===y?null:y),children:[s.jsx("span",{style:{display:"inline-block",width:14,height:14,borderRadius:3,background:p,border:"1px solid rgba(255,255,255,0.15)",flexShrink:0,cursor:"pointer"},onDoubleClick:m=>{m.stopPropagation(),v(y)},title:"Click to expand, double-click for full picker"}),s.jsx("span",{style:{flex:1},children:f}),s.jsx("span",{style:{fontSize:9,color:t.textTertiary},children:i===y?"▲":"▼"})]}),i===y&&s.jsx("div",{style:{padding:"4px 10px 6px 32px",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},children:Ky.map(m=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:m,cursor:"pointer",border:m===p?`2px solid ${t.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onClick:()=>{o(y,m),a(null)}},m))})]},y)}),s.jsx("div",{style:{borderTop:`1px solid ${t.border}`,marginTop:4,paddingTop:4},children:s.jsx("div",{style:{padding:"4px 10px",fontSize:10,color:t.textTertiary,cursor:"pointer",textAlign:"center"},onMouseEnter:y=>{y.currentTarget.style.color=t.textPrimary},onMouseLeave:y=>{y.currentTarget.style.color=t.textTertiary},onClick:l,children:"Reset to defaults"})}),s.jsx("input",{ref:u,type:"color",style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0},onChange:y=>{c&&o(c,y.target.value)}})]})}function Zy({labelWidth:e}){const{genome:t,region:n}=at(),{tracks:r}=Jt(),{theme:o,themeName:l,customTheme:i}=Xe(),[a,u]=C.useState(!1),[c,h]=C.useState(!1),d=!!t;C.useEffect(()=>{if(!d)return;function x(y){y.preventDefault(),y.returnValue=""}return window.addEventListener("beforeunload",x),()=>window.removeEventListener("beforeunload",x)},[d]),C.useEffect(()=>{if(!d)return;function x(y){(y.ctrlKey||y.metaKey)&&y.key==="w"&&(y.preventDefault(),u(!0))}return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[d]);const g=C.useCallback(()=>u(!1),[]),T=C.useCallback(()=>{window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[]),v=C.useCallback(()=>{h(!0);try{const x=Da(t,n,r,l,i,e);Ua(x),Rp(x)}catch{}h(!1),window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[t,n,r,l,i,e]);return a?s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center"},onClick:g,children:s.jsxs("div",{style:{background:o.panelBg,border:`1px solid ${o.borderAccent}`,borderRadius:8,padding:"24px 28px",maxWidth:400,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.6)"},onClick:x=>x.stopPropagation(),children:[s.jsx("div",{style:{fontSize:16,fontWeight:700,color:o.textPrimary,marginBottom:8},children:"Leave BiNgo Genome Viewer?"}),s.jsxs("div",{style:{fontSize:12,color:o.textSecondary,lineHeight:1.7,marginBottom:20},children:["You have an active session with"," ",s.jsxs("strong",{style:{color:o.textPrimary},children:[r.length," track",r.length!==1?"s":""]})," loaded. Unsaved changes will be lost."]}),s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[s.jsx("button",{onClick:g,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Return to App"}),s.jsx("button",{onClick:v,disabled:c,style:{background:o.btnBg,border:`1px solid ${o.borderStrong}`,borderRadius:4,color:o.btnText,padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:c?"Saving...":"Save Session & Exit"}),s.jsx("button",{onClick:T,style:{background:"transparent",border:`1px solid ${o.border}`,borderRadius:4,color:"#e57373",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Exit Without Saving"})]})]})}):null}const $c="2.3.4";let ex=0;function Nc({size:e=32}){const[t]=Hs.useState(()=>`blogo${++ex}`);return s.jsxs("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{flexShrink:0},xmlns:"http://www.w3.org/2000/svg",children:[s.jsxs("defs",{children:[s.jsxs("radialGradient",{id:`${t}_bg`,cx:"35%",cy:"30%",r:"65%",children:[s.jsx("stop",{offset:"0%",stopColor:"#5eb8ff"}),s.jsx("stop",{offset:"50%",stopColor:"#1976d2"}),s.jsx("stop",{offset:"100%",stopColor:"#0d47a1"})]}),s.jsxs("radialGradient",{id:`${t}_sh`,cx:"30%",cy:"25%",r:"30%",children:[s.jsx("stop",{offset:"0%",stopColor:"#ffffff",stopOpacity:"0.7"}),s.jsx("stop",{offset:"100%",stopColor:"#ffffff",stopOpacity:"0"})]})]}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_bg)`}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"white"}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"none",stroke:"#1565c0",strokeWidth:"2.5"}),s.jsx("text",{x:"50",y:"39",textAnchor:"middle",fontSize:"13",fontWeight:"800",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"BN"}),s.jsx("text",{x:"50",y:"64",textAnchor:"middle",fontSize:"30",fontWeight:"900",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"1"}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_sh)`})]})}function tx({theme:e,labelWidth:t}){return s.jsxs("div",{style:{display:"flex",borderBottom:`1px solid ${e.border}`,height:60,opacity:.45},children:[s.jsx("div",{"data-tour":"skeleton-track-label",style:{width:t,minWidth:t,background:e.panelBg,borderRight:`1px solid ${e.border}`,padding:"6px 8px",display:"flex",flexDirection:"column",justifyContent:"center",gap:4},children:s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[s.jsx("span",{style:{fontSize:14,color:e.textTertiary,userSelect:"none",lineHeight:1},children:"≡"}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:"#78909c",flexShrink:0}}),s.jsx("span",{style:{fontSize:11,fontWeight:600,color:e.textSecondary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:"Track Name"}),s.jsx("span",{style:{fontSize:13,color:e.textTertiary,lineHeight:1,padding:"0 2px"},children:"×"})]})}),s.jsx("div",{style:{flex:1,background:e.canvasBg}})]})}function nx(){const{theme:e}=Xe(),{genome:t,region:n,setGenome:r,navigateTo:o}=at(),{tracks:l,reorderTracks:i,addTrack:a,uploadTrack:u,commitTrack:c,discardTrack:h,addGenomeAnnotationTrack:d,restoreAnnotationTracks:g}=Jt(),T=C.useRef(null),[v,x]=C.useState(800),[y,f]=C.useState(!1),[p,m]=C.useState(!1),[w,b]=C.useState(!1),[j,S]=C.useState(!1),[E,$]=C.useState(!1),[A,R]=C.useState(!1),[U,P]=C.useState(140),[W,O]=C.useState(null),[Y,I]=C.useState(null),[L,N]=C.useState(!1),[D,z]=C.useState(null),[F,V]=C.useState(null),[M,k]=C.useState(null),Q=C.useRef(0);Sy(U),C.useEffect(()=>{const B=()=>fetch("/api/heartbeat").catch(()=>{});B();const q=setInterval(B,1e4);return()=>clearInterval(q)},[]);const ee=C.useRef(n==null?void 0:n.chrom);C.useEffect(()=>{n!=null&&n.chrom&&n.chrom!==ee.current&&(ee.current=n.chrom,g())},[n==null?void 0:n.chrom,g]);const ce=new Set([".gb",".gbk",".genbank",".fasta",".fa"]),he=new Set([".bam",".bw",".bigwig",".wig",".bedgraph",".bdg",".vcf",".bed",".gtf",".gff",".gff2",".gff3"]),pe=new Set([".bai"]);function ae(B){if(!B)return"";if(B.toLowerCase().endsWith(".vcf.gz"))return".vcf.gz";const q=B.lastIndexOf(".");return q>=0?B.slice(q).toLowerCase():""}const ie=C.useCallback(B=>{var q,X;B.preventDefault(),B.stopPropagation(),(X=(q=B.dataTransfer)==null?void 0:q.types)!=null&&X.includes("Files")&&(Q.current++,Q.current===1&&N(!0))},[]),ne=C.useCallback(B=>{var q,X;B.preventDefault(),B.stopPropagation(),(X=(q=B.dataTransfer)==null?void 0:q.types)!=null&&X.includes("Files")&&(Q.current--,Q.current<=0&&(Q.current=0,N(!1)))},[]),xe=C.useCallback(B=>{B.preventDefault(),B.stopPropagation()},[]);function Me(B){const q=B==null?void 0:B.compatibility;return q&&q.status!=="ok"&&q.status!=="no_genome"}const ve=C.useCallback(async B=>{var Ie,ut,Wa,Ha,Va;if(B.preventDefault(),B.stopPropagation(),Q.current=0,N(!1),!((ut=(Ie=B.dataTransfer)==null?void 0:Ie.types)!=null&&ut.includes("Files")))return;const q=Array.from(B.dataTransfer.files);if(!q.length)return;const X=[],Z=[],le=[],oe=[];for(const Re of q){const Be=ae(Re.name),yt=Re.name.toLowerCase();ce.has(Be)?X.push(Re):he.has(Be)||Be===".vcf.gz"?Z.push(Re):pe.has(Be)||yt.endsWith(".bam.bai")?le.push(Re):oe.push(Re)}const fe=Z.filter(Re=>Re.name.toLowerCase().endsWith(".bam")&&Re.size>50*1024*1024),we=le.filter(Re=>Re.size>10*1024*1024);if(fe.length||we.length){const Re=[...fe,...we].map(yt=>yt.name).join(", "),Be=[...fe,...we].reduce((yt,jo)=>yt+jo.size,0)/(1024*1024);z({error:`${Re} (${Be.toFixed(0)} MB) — large files load faster via the Path button. Click 📂 Path in the toolbar and paste the file path instead of uploading.`}),setTimeout(()=>z(null),1e4);return}if(oe.length&&!X.length&&!Z.length&&!le.length){z({error:`Unsupported file${oe.length>1?"s":""}: ${oe.map(Re=>Re.name).join(", ")}`}),setTimeout(()=>z(null),4e3);return}try{if(X.length>0&&!t){z({msg:`Loading genome: ${X[0].name}...`});const Be=(await yn.load(X[0])).data;if(Be.name&&(Be.name=Ft(Be.name)),r(Be),((Wa=Be.chromosomes)==null?void 0:Wa.length)>0){const yt=Be.chromosomes[0];o(yt.name,0,Math.min(yt.length,5e4))}Be.is_annotated&&d({id:"genome_annotations",name:`${Be.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:Be.annotated_chromosomes||null})}else X.length>0&&t&&V({files:X});if(Z.length>0){if(!t&&X.length===0){z({error:"Load a genome file first (.fasta, .gb, .genbank)"}),setTimeout(()=>z(null),4e3);return}z({msg:`Loading ${Z.length} track${Z.length>1?"s":""}...`});const Re=[],Be=[],yt=[];for(const jo of Z)try{const kn=await u(jo,void 0);Me(kn)?Be.push(kn):(c(kn),Re.push(kn))}catch(kn){yt.push(`${jo.name}: ${((Va=(Ha=kn.response)==null?void 0:Ha.data)==null?void 0:Va.detail)||kn.message}`)}if(yt.length){z({error:yt.join("; ")}),setTimeout(()=>z(null),5e3);return}Be.length>0&&k({tracks:Be})}oe.length?(z({error:`Skipped unsupported: ${oe.map(Re=>Re.name).join(", ")}`}),setTimeout(()=>z(null),4e3)):(z({msg:"Files loaded"}),setTimeout(()=>z(null),2e3))}catch(Re){z({error:Re.message||"Drop failed"}),setTimeout(()=>z(null),5e3)}},[t,r,o,a,d]),Fe=C.useCallback(async()=>{var q,X;if(!F)return;const B=F.files;V(null);try{const Z=[];for(const le of B){z({msg:`Adding chromosomes from ${le.name}...`});try{const fe=(await yn.addChromosomes(le)).data;fe.name&&(fe.name=Ft(fe.name)),r(fe),fe.is_annotated&&d({id:"genome_annotations",name:`${fe.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:fe.annotated_chromosomes||null})}catch(oe){Z.push(`${le.name}: ${((X=(q=oe.response)==null?void 0:q.data)==null?void 0:X.detail)||oe.message}`)}}Z.length?(z({error:Z.join("; ")}),setTimeout(()=>z(null),5e3)):(z({msg:`Added chromosomes from ${B.length} file${B.length>1?"s":""}`}),setTimeout(()=>z(null),3e3))}catch(Z){z({error:Z.message||"Failed to add chromosomes"}),setTimeout(()=>z(null),5e3)}},[F,r,d]),et=C.useCallback(async()=>{var q,X;if(!F)return;const B=F.files;V(null);try{z({msg:`Loading ${B.length} track${B.length>1?"s":""}...`});const Z=[];for(const le of B)try{await a(le,void 0)}catch(oe){Z.push(`${le.name}: ${((X=(q=oe.response)==null?void 0:q.data)==null?void 0:X.detail)||oe.message}`)}Z.length?(z({error:Z.join("; ")}),setTimeout(()=>z(null),5e3)):(z({msg:`Added ${B.length} track${B.length>1?"s":""}`}),setTimeout(()=>z(null),3e3))}catch(Z){z({error:Z.message||"Failed to load tracks"}),setTimeout(()=>z(null),5e3)}},[F,a]),me=C.useCallback(async()=>{if(M){for(const B of M.tracks)await h(B.id);k(null)}},[M,h]),gt=C.useCallback(()=>{if(M){for(const B of M.tracks)c(B);k(null),z({msg:`Added ${M.tracks.length} track${M.tracks.length>1?"s":""}`}),setTimeout(()=>z(null),3e3)}},[M,c]),G=C.useCallback(B=>{B.preventDefault();const q=B.clientX,X=U;function Z(oe){P(Math.max(60,Math.min(400,X+(oe.clientX-q))))}function le(){window.removeEventListener("mousemove",Z),window.removeEventListener("mouseup",le),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ew-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",Z),window.addEventListener("mouseup",le)},[U]);C.useEffect(()=>{if(!T.current)return;const B=new ResizeObserver(q=>{for(const X of q)x(X.contentRect.width)});return B.observe(T.current),()=>B.disconnect()},[]);const J=C.useCallback(B=>B.visible?!B.targetChromosomes||!(n!=null&&n.chrom)?!0:B.targetChromosomes.includes(n.chrom):!1,[n==null?void 0:n.chrom]),te={app:{display:"flex",flexDirection:"column",height:"100vh",background:e.appBg,color:e.textPrimary},header:{background:e.headerBg,borderBottom:`2px solid ${e.borderAccent}`,padding:"8px 16px",display:"flex",alignItems:"center",justifyContent:"space-between"},headerLeft:{display:"flex",alignItems:"center",gap:12},title:{fontSize:18,fontWeight:700,color:e.textPrimary,letterSpacing:1},subtitle:{fontSize:11,color:e.textTertiary},headerBtns:{display:"flex",gap:8},btn:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600,display:"flex",alignItems:"center",gap:6},trackArea:{flex:1,overflowY:"auto",overflowX:"hidden",display:"flex",flexDirection:"column"},emptyState:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",flex:1,color:e.textMuted,gap:12},emptyTitle:{fontSize:22,fontWeight:300},emptyHint:{fontSize:13}};return s.jsxs("div",{style:te.app,onDragEnter:ie,onDragLeave:ne,onDragOver:xe,onDrop:ve,children:[s.jsxs("div",{style:te.header,children:[s.jsxs("div",{style:te.headerLeft,children:[s.jsx(Nc,{size:34}),s.jsxs("div",{children:[s.jsx("div",{style:te.title,children:"BiNgo Genome Viewer"}),t&&s.jsxs("div",{style:te.subtitle,children:[t.name," · ",t.chromosomes.length," chr"]})]}),s.jsxs("button",{onClick:()=>$(!0),title:"About / References",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:B=>{B.currentTarget.style.color=e.textPrimary,B.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:B=>{B.currentTarget.style.color=e.textSecondary,B.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("circle",{cx:"8",cy:"4.5",r:"1.2"}),s.jsx("rect",{x:"7",y:"6.5",width:"2",height:"5.5",rx:"0.8"})]}),"Info"]}),s.jsxs("button",{onClick:()=>R(!0),title:"Guided Tour",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:B=>{B.currentTarget.style.color=e.textPrimary,B.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:B=>{B.currentTarget.style.color=e.textSecondary,B.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("path",{d:"M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zM8 13.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"})]}),"Help"]})]}),s.jsxs("div",{style:te.headerBtns,"data-tour":"header-btns",children:[s.jsxs("button",{style:te.btn,onClick:()=>S(!0),title:"Save or restore a session",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:[s.jsx("path",{d:"M2 2h8v8H2z"}),s.jsx("path",{d:"M4 2v4h4V2"}),s.jsx("path",{d:"M5 3h2"})]}),"Save Session"]}),s.jsxs("button",{style:te.btn,onClick:()=>m(!0),title:"Customize color theme",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",style:{flexShrink:0},children:[s.jsx("rect",{x:"0",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#66bb6a"}),s.jsx("rect",{x:"6.5",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#42a5f5"}),s.jsx("rect",{x:"0",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ffa726"}),s.jsx("rect",{x:"6.5",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ab47bc"})]}),"Theme"]}),s.jsxs("button",{"data-tour":"btn-export",style:{...te.btn,...n&&l.length>0?{}:{opacity:.35,cursor:"default"}},onClick:()=>{n&&l.length>0&&b(!0)},title:"Export current view as SVG or PNG",children:[s.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:s.jsx("path",{d:"M6 1v7M3 5.5L6 8.5 9 5.5M2 11h8"})}),"Export Image"]}),s.jsxs("button",{"data-tour":"btn-settings",style:{...te.btn,...l.length===0?{opacity:.35,cursor:"default"}:{}},onClick:()=>{l.length>0&&f(!0)},title:"Adjust height, scale, color, and bar width for tracks",children:["⚙"," Track Settings"]})]})]}),s.jsx(W0,{}),s.jsx(jy,{}),s.jsxs("div",{style:te.trackArea,ref:T,"data-tour":"track-area",children:[l.filter(J).length===0&&s.jsx(tx,{theme:e,labelWidth:U}),t?n?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{display:"flex"},children:[s.jsx("div",{style:{width:U,minWidth:U,background:e.panelBg,borderRight:`1px solid ${e.border}`,position:"relative"},children:s.jsx("div",{onMouseDown:G,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:B=>B.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:B=>B.currentTarget.style.background="transparent"})}),s.jsx(Ey,{width:v-U})]}),l.filter(J).map(B=>s.jsx(Qy,{track:B,containerWidth:v,labelWidth:U,onLabelResizeStart:G,isDragging:W===B.id,isDropTarget:Y===B.id,onDragStart:()=>O(B.id),onDragOver:()=>I(B.id),onDrop:()=>{W&&W!==B.id&&i(W,B.id),O(null),I(null)},onDragEnd:()=>{O(null),I(null)}},B.id)),l.length===0&&s.jsx("div",{style:{padding:24,color:e.textMuted,fontSize:13},children:"Add tracks above — BAM, VCF, BigWig, BED, GTF, GFF, WIG..."})]}):s.jsx("div",{style:te.emptyState,children:s.jsx("div",{style:te.emptyHint,children:"Select a chromosome to begin"})}):s.jsxs("div",{style:te.emptyState,children:[s.jsx("div",{style:te.emptyTitle,children:"No genome loaded"}),s.jsx("div",{style:te.emptyHint,children:"Load a FASTA or GenBank file above to get started"})]})]}),y&&s.jsx(Q0,{onClose:()=>f(!1)}),p&&s.jsx(Z0,{onClose:()=>m(!1)}),w&&s.jsx(ay,{onClose:()=>b(!1)}),j&&s.jsx(by,{onClose:()=>S(!1),labelWidth:U,setLabelWidth:P}),A&&s.jsx(Ty,{onClose:()=>{R(!1),f(!1),m(!1)},theme:e,onAction:B=>{B==="open-settings"?(f(!0),m(!1)):B==="open-theme"?(m(!0),f(!1)):(f(!1),m(!1))}}),E&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},onClick:()=>$(!1),children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.border}`,borderRadius:8,padding:"28px 36px",maxWidth:520,maxHeight:"85vh",overflowY:"auto",color:e.textPrimary,lineHeight:1.7},onClick:B=>B.stopPropagation(),children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:16},children:[s.jsx(Nc,{size:44}),s.jsx("div",{style:{fontSize:20,fontWeight:700},children:"BiNgo Genome Viewer"})]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Version:"})," ",$c]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Publisher:"})," Billy M Ngo"]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:20},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Published:"})," April 2026"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,background:e.canvasBg,border:`1px solid ${e.border}`,borderRadius:4,padding:"10px 14px",fontFamily:"monospace",lineHeight:1.6,marginBottom:20,userSelect:"all"},children:["Ngo, B.M. (2026). BiNgo Genome Viewer (v",$c,") [Software]."]}),s.jsxs("details",{style:{marginBottom:20},children:[s.jsx("summary",{style:{cursor:"pointer",fontSize:13,fontWeight:600,color:e.textPrimary,marginBottom:8},children:"References & Acknowledgments"}),s.jsxs("div",{style:{fontSize:11,color:e.textSecondary,lineHeight:1.8,paddingTop:8},children:[s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginBottom:4},children:"Software Dependencies"}),s.jsxs("div",{children:[s.jsx("strong",{children:"FastAPI"})," ","—"," Ram","í","rez, S. (2018). A modern web framework for building APIs with Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Uvicorn"})," ","—"," Encode OSS. ASGI server implementation for Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BioPython"})," ","—"," Cock, P.J.A. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(11), 1422","–","1423."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"pyfaidx"})," ","—"," Shirley, M.D. et al. (2015). ",s.jsx("em",{children:"PeerJ PrePrints"}),", 3:e1196."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"bamnostic"})," ","—"," Sherman, M.A. & Mills, R.E. (2019). Pure Python BAM parser."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"React"})," ","—"," Meta Platforms, Inc. JavaScript UI library."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Vite"})," ","—"," You, E. (2020). Next generation frontend tooling."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"File Format Specifications"}),s.jsxs("div",{children:[s.jsx("strong",{children:"SAM/BAM"})," ","—"," Li, H. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(16), 2078","–","2079."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"VCF"})," ","—"," Danecek, P. et al. (2011). ",s.jsx("em",{children:"Bioinformatics"}),", 27(15), 2156","–","2158."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BigWig/WIG"})," ","—"," Kent, W.J. et al. (2010). ",s.jsx("em",{children:"Bioinformatics"}),", 26(17), 2204","–","2207."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BED"})," ","—"," UCSC Genome Browser, UC Santa Cruz."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GFF3"})," ","—"," Sequence Ontology Project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GTF"})," ","—"," Ensembl genome database project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GenBank"})," ","—"," Benson, D.A. et al. (2013). ",s.jsx("em",{children:"Nucleic Acids Res."}),", 41(D1), D36","–","D42."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Inspiration"}),s.jsxs("div",{children:[s.jsx("strong",{children:"IGV"})," ","—"," Robinson, J.T. et al. (2011). ",s.jsx("em",{children:"Nature Biotechnology"}),", 29(1), 24","–","26."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Acknowledgments"}),s.jsx("div",{children:"Early version testing and feedback:"}),s.jsx("div",{children:"Amanda Antoch, Isaac Poarch, Otto Chipashvili, Jake Colautti"})]})]}),s.jsx("div",{style:{textAlign:"right"},children:s.jsx("button",{onClick:()=>$(!1),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 18px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Close"})})]})}),F&&(()=>{const B=F.files.length>1,q=F.files.map(X=>X.name).join(", ");return s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:440,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:X=>X.stopPropagation(),children:[s.jsxs("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:["Genome file",B?"s":""," detected"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[s.jsx("strong",{style:{color:e.textPrimary},children:q}),B?" appear to be genome files. A genome is already loaded.":" appears to be a genome file. A genome is already loaded.",s.jsx("br",{}),"How would you like to handle ",B?"them":"it","?"]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:()=>V(null),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsxs("button",{onClick:et,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Track",B?"s":""]}),s.jsxs("button",{onClick:Fe,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Chromosome",B?"s":""]})]})]})})})(),M&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:480,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:B=>B.stopPropagation(),children:[s.jsx("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:"Track compatibility warning"}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[M.tracks.map(B=>{var q;return s.jsxs("div",{style:{marginBottom:6},children:[s.jsx("strong",{style:{color:e.textPrimary},children:B.name})," — ",((q=B.compatibility)==null?void 0:q.message)||"Possible mismatch with loaded genome"]},B.id)}),s.jsx("div",{style:{marginTop:8},children:M.tracks.length>1?"These tracks may not match the loaded genome.":"This track may not match the loaded genome."})]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:me,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsx("button",{onClick:gt,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Load Anyway"})]})]})}),L&&s.jsx("div",{style:{position:"fixed",inset:0,zIndex:9998,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:s.jsxs("div",{style:{border:`3px dashed ${e.textSecondary}`,borderRadius:16,padding:"40px 60px",textAlign:"center"},children:[s.jsx("div",{style:{fontSize:28,fontWeight:300,color:e.textPrimary,marginBottom:8},children:"Drop files here"}),s.jsx("div",{style:{fontSize:13,color:e.textSecondary},children:"Genome (.gb, .fasta) or track files (.bam, .bw, .wig, .vcf, .bed, .gff, .gtf)"})]})}),D&&s.jsx("div",{style:{position:"fixed",bottom:20,left:"50%",transform:"translateX(-50%)",zIndex:10001,padding:"8px 20px",borderRadius:6,background:D.error?"#c62828":e.panelBg,border:`1px solid ${D.error?"#e53935":e.borderAccent}`,color:D.error?"#fff":"#81c784",fontSize:12,fontWeight:600,boxShadow:"0 4px 16px rgba(0,0,0,0.5)"},children:D.error||D.msg}),t&&s.jsx(Zy,{labelWidth:U})]})}function rx(){return s.jsx(F0,{children:s.jsx(rg,{children:s.jsx($0,{children:s.jsx(nx,{})})})})}Di.createRoot(document.getElementById("root")).render(s.jsx(Hs.StrictMode,{children:s.jsx(rx,{})}));
97
+ `):null)}},[a,u,c,t,n,l,e.color,e.scaleMax,e.scaleMin,e.logScale,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Ni(e,t,n,r,o){if(!(t.length<2)){if(e.beginPath(),e.moveTo(t[0],n[0]),o){for(let l=0;l<t.length-1;l++){const i=(t[l]+t[l+1])/2,a=(n[l]+n[l+1])/2;e.quadraticCurveTo(t[l],n[l],i,a)}e.lineTo(t[t.length-1],n[n.length-1])}else for(let l=0;l<t.length;l++)e.lineTo(t[l],n[l]);e.strokeStyle=r,e.lineWidth=1.5,e.stroke()}}function $r(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=e.measureText(t),a=2,u=i.width+a*2,c=12;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,u,c),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+a,r+1),e.textBaseline="alphabetic"}function _y(e,t){const n=e.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;const r=o=>Math.max(0,Math.min(255,o+t));return`rgb(${r(parseInt(n[1],16))},${r(parseInt(n[2],16))},${r(parseInt(n[3],16))})`}const Pc=6,Oi=8,Fi=14,Ii=2,Ly="#9c27b0",Vo=10,My={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"},By="#ffeb3b";function _c(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function Ay({track:e,width:t,height:n,onWarning:r}){const o=C.useRef(null),{region:l}=at(),{theme:i}=Xe(),{data:a,loading:u}=ei(e,l,t),[c,h]=C.useState(null),d=C.useRef(null),[g,T]=C.useState(0),v=C.useRef(null),x=e.showNucleotides!==!1,y=e.useArrows!==!1,f=e.logScale===!0,p=e.fwdColor||"#90a4ae",m=e.revColor||"#f06292",w=e.arrowStyle||"pointed",b=e.arrowSize||4,j=C.useRef(null);C.useEffect(()=>{if(l&&j.current){const $=j.current;($.chrom!==l.chrom||Math.abs($.start-l.start)>$.end-$.start)&&T(0)}j.current=l},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end]),C.useEffect(()=>{if(!l||!x){h(null);return}const $=l.end-l.start;if(t/$<Pc||$>2e3){h(null);return}if(c&&c.chrom===l.chrom&&c.start<=l.start&&c.end>=l.end)return;const R=Math.max(0,l.start-500),U=l.end+500,P=`${l.chrom}:${R}-${U}`;d.current!==P&&(d.current=P,yn.sequence(l.chrom,R,U).then(W=>h({chrom:l.chrom,start:R,end:U,sequence:W.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,x]);const S=C.useCallback($=>{var W;if(!((W=a==null?void 0:a.reads)!=null&&W.length)||!$.shiftKey&&Math.abs($.deltaX)>Math.abs($.deltaY))return;const A=x&&c?Fi:Oi,R=Math.max(0,...a.reads.map(O=>O.row)),U=Math.floor(n/(A+Ii)),P=Math.max(0,R-U+2);P<=0||($.preventDefault(),$.stopPropagation(),T(O=>Math.max(0,Math.min(P,O+Math.sign($.deltaY)*3))))},[a,n,x,c]);C.useEffect(()=>{var k;const $=o.current;if(!$)return;const A=window.devicePixelRatio||1;$.width=t*A,$.height=n*A;const R=$.getContext("2d");if(R.scale(A,A),R.clearRect(0,0,t,n),R.fillStyle=i.canvasBg,R.fillRect(0,0,t,n),u&&!a){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!a){r&&r(null);return}const U=l.start,P=l.end-l.start;if(a.bins){const Q=a.max_value||1,ee=e.scaleMax!=null?e.scaleMax:Q,ce=e.color||"#78909c",he=e.barAutoWidth!==!1,pe=e.barWidth||2,ae=t/P;if(e.showBars!==!1){R.fillStyle=ce;for(const ne of a.bins){const xe=(ne.end-ne.start)/P*t,Me=he?ae>=1?Math.max(1,Math.min(ae,xe)):Math.max(1,xe):Math.min(pe,xe),ve=(ne.start-U)/P*t,et=(f?_c(ne.value,ee):Math.min(1,ne.value/ee))*(n-14);R.fillRect(ve,n-et-2,Me,et)}}if(e.showOutline&&a.bins.length>0){const ne=e.outlineSmooth||0,xe=a.bins.map(me=>f?_c(me.value,ee):Math.min(1,me.value/ee)),Me=$y(xe,ne),ve=a.bins.map(me=>((me.start+me.end)/2-U)/P*t),Fe=Me.map(me=>n-me*(n-14)-2),et=e.outlineColor||i.textPrimary||"#fff";if(R.beginPath(),R.moveTo(ve[0],Fe[0]),ne>0){for(let me=0;me<ve.length-1;me++)R.quadraticCurveTo(ve[me],Fe[me],(ve[me]+ve[me+1])/2,(Fe[me]+Fe[me+1])/2);R.lineTo(ve[ve.length-1],Fe[Fe.length-1])}else for(let me=0;me<ve.length;me++)R.lineTo(ve[me],Fe[me]);R.strokeStyle=et,R.lineWidth=1.5,R.stroke()}const ie=f?" log₂":"";Lc(R,`${ee.toFixed(1)}${ie}`,2,2,i),Lc(R,"0",2,n-12,i,!0),R.fillStyle="#ffb74d",R.font="10px Arial, Helvetica, sans-serif",R.textAlign="right",R.fillText("zoom in for reads",t-4,10),r&&r(e.scaleMax!=null&&Q>e.scaleMax?`Bars clipped: max value ${Q.toFixed(1)} exceeds scale ${e.scaleMax.toFixed(1)}`:null);return}if(!((k=a.reads)!=null&&k.length)){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("No reads in region",8,n/2+4),r&&r(null);return}const W=Q=>(Q-U)/P*t,O=t/P,Y=x&&O>=Pc&&c!=null,I=Y?Fi:Oi,L=Ii,D=Math.max(0,...a.reads.map(Q=>Q.row))+1,z=Math.floor(n/(I+L)),F=D>z,V=Math.min(g,Math.max(0,D-z+1));let M=0;for(const Q of a.reads){const ee=(Q.row-V)*(I+L)+2;if(ee+I<0||ee>n){M++;continue}const ce=Q.strand==="+"?p:m,he=Q.segments;if(he&&he.length>0){const pe=W(Q.start),ae=W(Q.end);R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(pe,ee+I/2),R.lineTo(ae,ee+I/2),R.stroke();let ie=0;for(const ne of he)if(ne.type==="M"){const xe=W(ne.start),Me=Math.max(1,W(ne.end)-xe);if(R.fillStyle=ce,R.fillRect(xe,ee,Me,I),Y&&Q.sequence){const ve=ne.end-ne.start;for(let Fe=0;Fe<ve;Fe++){const et=ne.start+Fe,me=W(et),gt=W(et+1)-me,G=(Q.sequence[ie+Fe]||"").toUpperCase();let J="";c&&et>=c.start&&et<c.end&&(J=(c.sequence[et-c.start]||"").toUpperCase());const te=J&&G&&G!==J&&G!=="N";te&&(R.fillStyle=By,R.fillRect(me,ee,gt,I)),gt>=6&&(R.fillStyle=te?"#000":My[G]||"#999",R.font=`bold ${Math.min(11,gt-1)}px monospace`,R.textAlign="center",R.textBaseline="middle",R.fillText(G,me+gt/2,ee+I/2))}ie+=ve}}else if(ne.type==="D"){const xe=W(ne.start),Me=W(ne.end)-xe;Me>=1&&(R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(xe,ee+I/2),R.lineTo(xe+Me,ee+I/2),R.stroke())}else if(ne.type==="N"){const xe=W(ne.start),Me=W(ne.end)-xe;Me>=2&&(R.setLineDash([2,2]),R.strokeStyle=ce,R.lineWidth=1,R.beginPath(),R.moveTo(xe,ee+I/2),R.lineTo(xe+Me,ee+I/2),R.stroke(),R.setLineDash([]))}else ne.type==="I"?(R.fillStyle=Ly,R.fillRect(W(ne.pos)-1,ee-1,2,I+2),Y&&(ie+=ne.length)):ne.type==="S"&&Y&&(ie+=ne.length)}else{const pe=W(Q.start),ae=Math.max(2,W(Q.end)-pe);R.fillStyle=Q.strand==="+"?p:m,R.fillRect(pe,ee,ae,I)}if(y&&w!=="flat"){const pe=W(Q.start),ae=Math.max(2,W(Q.end)-pe),ie=Math.min(b,ae/2);ie>=2&&zy(R,w,Q.strand,pe,ee,ae,I,ie,ce,i.canvasBg)}if(!Y&&!x){const pe=W(Q.start);Math.max(2,W(Q.end)-pe)>60&&(R.fillStyle=i.canvasBg,R.font="8px Arial, Helvetica, sans-serif",R.textAlign="left",R.fillText(Q.name.slice(0,20),pe+2,ee+I-1))}}if(F){const Q=t-Vo;R.fillStyle=i.inputBg||"#2a2a2a",R.fillRect(Q,0,Vo,n);const ee=z/D,ce=Math.max(20,ee*n),pe=(D>z?V/(D-z):0)*(n-ce);R.fillStyle="#555",R.fillRect(Q+1,pe,Vo-2,ce)}r&&(M>0&&!F?r(`${M} read${M>1?"s":""} hidden — increase track height to show all`):r(F?`${D} rows · Shift+scroll or drag scrollbar to navigate`:null))},[a,u,t,n,l,c,g,e.color,e.scaleMax,e.scaleMin,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.showNucleotides,e.useArrows,e.logScale,e.fwdColor,e.revColor,e.arrowStyle,e.arrowSize,i]);const E=C.useCallback($=>{var D;if(!((D=a==null?void 0:a.reads)!=null&&D.length))return;const A=o.current;if(!A)return;const R=A.getBoundingClientRect();if(($.clientX-R.left)*(t/R.width)<t-Vo)return;const P=x&&c?Fi:Oi,O=Math.max(0,...a.reads.map(z=>z.row))+1,Y=Math.floor(n/(P+Ii)),I=Math.max(0,O-Y+1);if(I<=0)return;$.preventDefault(),v.current={maxScroll:I,startY:$.clientY,startRow:g};function L(z){if(!v.current)return;const F=z.clientY-v.current.startY,V=Math.round(F/n*v.current.maxScroll);T(Math.max(0,Math.min(v.current.maxScroll,v.current.startRow+V)))}function N(){v.current=null,window.removeEventListener("mousemove",L),window.removeEventListener("mouseup",N)}window.addEventListener("mousemove",L),window.addEventListener("mouseup",N)},[a,t,n,g,x,c]);return s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onWheel:S,onMouseDown:E})}function zy(e,t,n,r,o,l,i,a,u,c){const h=n==="+";if(t==="pointed")e.fillStyle=c,h?(e.beginPath(),e.moveTo(r+l,o+i/2),e.lineTo(r+l-a,o),e.lineTo(r+l-a,o+i),e.fill()):(e.beginPath(),e.moveTo(r,o+i/2),e.lineTo(r+a,o),e.lineTo(r+a,o+i),e.fill());else if(t==="chevron")e.strokeStyle=c,e.lineWidth=1.5,h?(e.beginPath(),e.moveTo(r+l-a,o),e.lineTo(r+l,o+i/2),e.lineTo(r+l-a,o+i),e.stroke()):(e.beginPath(),e.moveTo(r+a,o),e.lineTo(r,o+i/2),e.lineTo(r+a,o+i),e.stroke());else if(t==="fade")if(h){const d=e.createLinearGradient(r+l-a*2,0,r+l,0);d.addColorStop(0,"rgba(0,0,0,0)"),d.addColorStop(1,c),e.fillStyle=d,e.fillRect(r+l-a*2,o,a*2,i)}else{const d=e.createLinearGradient(r,0,r+a*2,0);d.addColorStop(0,c),d.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=d,e.fillRect(r,o,a*2,i)}}function $y(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function Lc(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=2,a=e.measureText(t).width+i*2;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,a,12),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+i,r+1),e.textBaseline="alphabetic"}const Ny=16,Oy=22,Fy=4,_p=8,Mc=6,Bc={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"};function Iy({track:e,width:t,height:n,onWarning:r}){var $,A,R,U;const o=C.useRef(null),{region:l,navigateTo:i}=at(),{tracks:a}=Jt(),{theme:u}=Xe(),{data:c,loading:h,error:d}=ei(e,l,t),g=e.useArrows!==!1,T=e.showNucleotides!==!1,v=C.useRef([]),[x,y]=C.useState(null),[f,p]=C.useState(null),m=C.useRef(null);C.useEffect(()=>{if(!l||!T){p(null);return}const P=l.end-l.start;if(t/P<Mc||P>2e3){p(null);return}if(f&&f.chrom===l.chrom&&f.start<=l.start&&f.end>=l.end)return;const O=Math.max(0,l.start-500),Y=l.end+500,I=`${l.chrom}:${O}-${Y}`;m.current!==I&&(m.current=I,yn.sequence(l.chrom,O,Y).then(L=>p({chrom:l.chrom,start:O,end:Y,sequence:L.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,T]),C.useEffect(()=>{var V,M;const P=o.current;if(!P)return;const W=window.devicePixelRatio||1;P.width=t*W,P.height=n*W;const O=P.getContext("2d");if(O.scale(W,W),O.clearRect(0,0,t,n),O.fillStyle=u.canvasBg,O.fillRect(0,0,t,n),v.current=[],h&&!((V=c==null?void 0:c.features)!=null&&V.length)){O.fillStyle=u.textTertiary,O.font="11px Arial, Helvetica, sans-serif",O.fillText("Loading…",8,n/2+4),r&&r(null);return}if(d){O.fillStyle="#ef9a9a",O.font="11px Arial, Helvetica, sans-serif",O.fillText(typeof d=="string"?d:JSON.stringify(d),8,n/2+4),r&&r(null);return}if(!((M=c==null?void 0:c.features)!=null&&M.length)){c&&(O.fillStyle=u.textTertiary,O.font="11px Arial, Helvetica, sans-serif",O.fillText("No features in region",8,n/2+4)),r&&r(null);return}const Y=l.end-l.start,I=t/Y,L=T&&I>=Mc&&f!=null,N=L?Oy:Ny,D=[],z=[];let F=0;if(L){const Q=n-14;O.fillStyle=u.canvasBg,O.fillRect(0,Q,t,14),O.strokeStyle=u.border||"#333",O.lineWidth=.5,O.beginPath(),O.moveTo(0,Q),O.lineTo(t,Q),O.stroke();const ee=Math.min(10,I-1);if(ee>=5){O.font=`bold ${ee}px monospace`,O.textAlign="center",O.textBaseline="middle";for(let ce=Math.floor(l.start);ce<Math.ceil(l.end);ce++)if(f&&ce>=f.start&&ce<f.end){const he=(f.sequence[ce-f.start]||"").toUpperCase(),pe=(ce-l.start)/Y*t;O.fillStyle=Bc[he]||"#999",O.fillText(he,pe+I/2,Q+14/2)}}}for(const k of c.features){let Q=D.findIndex(ae=>k.start>=ae);Q===-1&&(Q=D.length),D[Q]=k.end;const ee=(k.start-l.start)/Y*t,ce=Math.max(2,(k.end-k.start)/Y*t),he=Q*(N+Fy)+2;if(he+N>n){F++;continue}const pe=zc(k.feature_type,e,u);if(k.sub_features&&k.sub_features.length>0){O.fillStyle=pe+"66",O.fillRect(ee,he+N/2-1,ce,2);for(const ae of k.sub_features){const ie=(ae.start-l.start)/Y*t,ne=Math.max(1,(ae.end-ae.start)/Y*t),xe=zc(ae.feature_type,e,u),Me=ae.feature_type==="CDS"?N:N-6,ve=ae.feature_type==="CDS"?he:he+3;g?Ac(O,xe,ie,ve,ne,Me,ae.strand||k.strand):(O.fillStyle=xe,O.fillRect(ie,ve,ne,Me))}}else g?Ac(O,pe,ee,he,ce,N,k.strand):(O.fillStyle=pe,O.fillRect(ee,he,ce,N));if(L){const ae=Math.max(k.start,l.start),ie=Math.min(k.end,l.end);for(let ne=ae;ne<ie;ne++)if(f&&ne>=f.start&&ne<f.end){const xe=(f.sequence[ne-f.start]||"").toUpperCase(),Me=(ne-l.start)/Y*t,ve=I;ve>=6&&(O.fillStyle=Bc[xe]||"#999",O.font=`bold ${Math.min(10,ve-1)}px monospace`,O.textAlign="center",O.textBaseline="middle",O.fillText(xe,Me+ve/2,he+N/2))}}else if(ce>20){O.fillStyle="#fff",O.font="10px Arial, Helvetica, sans-serif",O.textAlign="left",O.textBaseline="alphabetic";const ae=k.name||k.feature_type,ie=Math.floor((ce-(g?_p:0)-4)/6);ie>0&&O.fillText(ae.slice(0,ie),ee+3,he+N-4)}z.push({feat:k,x:ee,y:he,w:ce,h:N})}v.current=z,r&&r(F>0?`${F} feature${F>1?"s":""} hidden — increase track height to show all`:null)},[c,h,d,t,n,l,f,e.color,e.annotationColors,g,e.showNucleotides,u]);const w=C.useCallback(P=>{const W=o.current;if(!W)return;const O=W.getBoundingClientRect(),Y=(P.clientX-O.left)*(t/O.width),I=(P.clientY-O.top)*(n/O.height);for(const L of v.current)if(Y>=L.x&&Y<=L.x+L.w&&I>=L.y&&I<=L.y+L.h){const N=Math.min(P.clientX+14,window.innerWidth-300),D=Math.min(P.clientY+14,window.innerHeight-260);y({feat:L.feat,x:Math.max(4,N),y:Math.max(4,D)});return}y(null)},[t,n]),b=C.useCallback(()=>y(null),[]),j=C.useCallback(P=>{const W=o.current;if(!W||!l)return;const O=W.getBoundingClientRect(),Y=(P.clientX-O.left)*(t/O.width),I=(P.clientY-O.top)*(n/O.height);for(const L of v.current)if(Y>=L.x&&Y<=L.x+L.w&&I>=L.y&&I<=L.y+L.h){const N=L.feat,z=(N.end-N.start)*.15/(1-.3),F=N.start-z,V=N.end+z;i(l.chrom,F,V),y(null);return}},[t,n,l,i]),S=x?Dy(x.feat,a,l==null?void 0:l.chrom):[],E=x?Wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:x.x,top:x.y,background:u.tooltipBg,border:`1px solid ${u.tooltipBorder}`,borderRadius:4,padding:"6px 10px",color:u.textPrimary,fontSize:11,lineHeight:1.5,maxWidth:280,zIndex:1e4,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:[s.jsx("div",{style:{fontWeight:700,fontSize:12,marginBottom:2},children:x.feat.name||x.feat.feature_type}),s.jsx(en,{label:"Type",value:x.feat.feature_type}),s.jsx(en,{label:"Strand",value:x.feat.strand||"."}),s.jsx(en,{label:"Location",value:`${x.feat.start.toLocaleString()}–${x.feat.end.toLocaleString()}`}),s.jsx(en,{label:"Length",value:`${(x.feat.end-x.feat.start).toLocaleString()} bp`}),(($=x.feat.attributes)==null?void 0:$.gene)&&x.feat.attributes.gene!==x.feat.name&&s.jsx(en,{label:"Gene",value:x.feat.attributes.gene}),((A=x.feat.attributes)==null?void 0:A.locus_tag)&&s.jsx(en,{label:"Locus",value:x.feat.attributes.locus_tag}),((R=x.feat.attributes)==null?void 0:R.product)&&s.jsx(en,{label:"Product",value:x.feat.attributes.product}),((U=x.feat.attributes)==null?void 0:U.note)&&s.jsx(en,{label:"Note",value:String(x.feat.attributes.note).slice(0,120)}),S.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{borderTop:`1px solid ${u.tooltipBorder}`,margin:"4px 0",paddingTop:4},children:s.jsx("span",{style:{color:u.textSecondary,fontWeight:600,fontSize:10,textTransform:"uppercase"},children:"Track totals in gene"})}),S.map(P=>s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:8},children:[s.jsx("span",{style:{color:u.textSecondary,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1},children:P.name}),s.jsx("span",{style:{color:u.textPrimary,fontWeight:600,flexShrink:0},children:P.total.toFixed(1)})]},P.trackId))]})]}),document.body):null;return s.jsxs("div",{style:{position:"relative",width:"100%",height:n},children:[s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onMouseMove:w,onMouseLeave:b,onDoubleClick:j}),E]})}function en({label:e,value:t}){return t?s.jsxs("div",{style:{display:"flex",gap:6},children:[s.jsxs("span",{style:{opacity:.6,flexShrink:0},children:[e,":"]}),s.jsx("span",{children:t})]}):null}function Dy(e,t,n){var o;if(!e||!n)return[];const r=[];for(const l of t){if(l.track_type!=="coverage"&&l.track_type!=="reads")continue;const i=ly(l.id,n);if(!((o=i==null?void 0:i.bins)!=null&&o.length))continue;let a=0;for(const u of i.bins){if(u.end<=e.start||u.start>=e.end)continue;const c=u.forward!=null?u.forward:Math.max(0,u.value||0),h=u.reverse!=null?Math.abs(u.reverse):Math.abs(Math.min(0,u.value||0));a+=c+h}a>0&&r.push({trackId:l.id,name:l.name,total:a})}return r}function Ac(e,t,n,r,o,l,i){e.fillStyle=t;const a=Math.min(_p,o*.4);e.beginPath(),i==="+"?(e.moveTo(n,r),e.lineTo(n+o-a,r),e.lineTo(n+o,r+l/2),e.lineTo(n+o-a,r+l),e.lineTo(n,r+l),e.closePath()):i==="-"?(e.moveTo(n+a,r),e.lineTo(n+o,r),e.lineTo(n+o,r+l),e.lineTo(n+a,r+l),e.lineTo(n,r+l/2),e.closePath()):e.rect(n,r,o,l),e.fill(),e.strokeStyle="rgba(0,0,0,0.25)",e.lineWidth=.5,e.stroke()}function zc(e,t,n){const r=t.annotationColors;switch(e==null?void 0:e.toLowerCase()){case"cds":return(r==null?void 0:r.cds)||(n==null?void 0:n.geneCds)||"#66bb6a";case"exon":return(r==null?void 0:r.exon)||(n==null?void 0:n.geneExon)||"#42a5f5";case"gene":return(r==null?void 0:r.gene)||(n==null?void 0:n.geneGene)||"#7e57c2";case"mrna":case"transcript":return(r==null?void 0:r.transcript)||(n==null?void 0:n.geneTranscript)||"#ab47bc";case"utr":case"3utr":case"5utr":return(r==null?void 0:r.utr)||(n==null?void 0:n.geneUtr)||"#26c6da";case"rrna":return(r==null?void 0:r.rrna)||(n==null?void 0:n.geneRrna)||"#ffa726";case"trna":return(r==null?void 0:r.trna)||(n==null?void 0:n.geneTrna)||"#ef5350";case"repeat_region":return(r==null?void 0:r.repeat)||(n==null?void 0:n.geneRepeat)||"#8d6e63";default:return(r==null?void 0:r.default)||t.color||(n==null?void 0:n.geneDefault)||"#80cbc4"}}function Uy({track:e,width:t,height:n,onWarning:r}){const o=C.useRef(null),{region:l}=at(),{theme:i}=Xe(),{data:a,loading:u}=ei(e,l,t);return C.useEffect(()=>{var f,p;const c=o.current;if(!c)return;const h=window.devicePixelRatio||1;c.width=t*h,c.height=n*h;const d=c.getContext("2d");if(d.scale(h,h),d.clearRect(0,0,t,n),d.fillStyle=i.canvasBg,d.fillRect(0,0,t,n),u&&!((f=a==null?void 0:a.variants)!=null&&f.length)){d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!((p=a==null?void 0:a.variants)!=null&&p.length)){a&&(d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("No variants in region",8,n/2+4)),r&&r(null);return}const g=l.end-l.start,T=e.barAutoWidth!==!1,v=e.barWidth||2,x=T?1:Math.max(.5,v),y=T?5:Math.max(2,v*2);for(const m of a.variants){const w=(m.pos-l.start)/g*t,b=Wy(m.ref,m.alt);d.strokeStyle=b,d.lineWidth=x,d.beginPath(),d.moveTo(w,n-4),d.lineTo(w,14),d.stroke(),d.fillStyle=b,d.beginPath(),d.arc(w,10,y,0,Math.PI*2),d.fill(),g<5e3&&(d.fillStyle=i.textPrimary,d.font="9px Arial, Helvetica, sans-serif",d.textAlign="center",d.fillText(`${m.ref}>${m.alt[0]||"?"}`,w,n-6))}if(r){const m=a.variants.filter(w=>w.pos>=l.start&&w.pos<=l.end).length;r(m>50?`${m} variants overlapping — zoom in for detail`:null)}},[a,u,t,n,l,e.color,e.barAutoWidth,e.barWidth,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Wy(e,t){const n=t[0]||"";return e.length===1&&n.length===1?"#ffb74d":n.length>e.length?"#81c784":n.length<e.length?"#e57373":"#b0bec5"}function Hy({message:e,theme:t}){const[n,r]=C.useState(!1),o=C.useRef(null),l=o.current?o.current.getBoundingClientRect():null;return s.jsxs(s.Fragment,{children:[s.jsx("span",{ref:o,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:12,height:12,borderRadius:"50%",background:"rgba(229, 57, 53, 0.85)",color:"#fff",fontSize:9,fontWeight:800,lineHeight:1,cursor:"default",flexShrink:0,fontFamily:"Arial, Helvetica, sans-serif"},children:"!"}),n&&l&&Wn.createPortal(s.jsx("div",{style:{position:"fixed",left:Math.min(l.right+6,window.innerWidth-220),top:l.top-4,background:t.tooltipBg||"#333",border:`1px solid ${t.tooltipBorder||"#555"}`,borderRadius:4,padding:"4px 8px",color:t.textPrimary||"#e0e0e0",fontSize:11,lineHeight:1.4,maxWidth:200,zIndex:10001,pointerEvents:"none",boxShadow:"0 3px 10px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",fontFamily:"Arial, Helvetica, sans-serif"},children:e}),document.body)]})}function Vy({width:e,height:t,trackData:n,trackType:r}){const{region:o,selection:l,clearSelection:i}=at(),{theme:a}=Xe(),[u,c]=C.useState(!1),[h,d]=C.useState({x:0,y:0}),g=C.useRef(null),T=C.useCallback(A=>{d({x:A.clientX,y:A.clientY}),c(!0)},[]),v=C.useCallback(()=>c(!1),[]);if(!l||!o||l.chrom!==o.chrom)return null;const x=o.end-o.start;if(x<=0)return null;const y=(l.start-o.start)/x,f=(l.end-o.start)/x,p=Math.max(0,y*e),w=Math.min(e,f*e)-p;if(w<1)return null;const b=Gy(l,n,r),j=l.end-l.start,S=260,E=Math.min(h.x+14,window.innerWidth-S-10),$=Math.min(h.y+14,window.innerHeight-200);return s.jsxs("div",{ref:g,style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none"},children:[s.jsx("div",{style:{position:"absolute",left:p,top:0,width:w,height:"100%",background:"rgba(100, 181, 246, 0.2)",borderLeft:"1px solid rgba(100, 181, 246, 0.6)",borderRight:"1px solid rgba(100, 181, 246, 0.6)",pointerEvents:"auto",cursor:"crosshair"},onMouseMove:T,onMouseLeave:v,onClick:A=>{A.stopPropagation(),i()}}),u&&Wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:E,top:$,background:a.panelBg,border:`1px solid ${a.borderAccent}`,borderRadius:6,padding:"8px 12px",fontSize:11,color:a.textPrimary,lineHeight:1.6,pointerEvents:"none",zIndex:1e4,boxShadow:"0 4px 16px rgba(0,0,0,0.4)",minWidth:180,maxWidth:S},children:[s.jsx("div",{style:{fontWeight:700,marginBottom:4,fontSize:12},children:"Selected Region"}),s.jsxs("div",{children:[s.jsx("span",{style:{color:a.textSecondary},children:"Region:"})," ",l.chrom,":",l.start.toLocaleString(),"-",l.end.toLocaleString()]}),s.jsxs("div",{children:[s.jsx("span",{style:{color:a.textSecondary},children:"Length:"})," ",j.toLocaleString()," bp"]}),b.map((A,R)=>s.jsxs("div",{children:[s.jsxs("span",{style:{color:a.textSecondary},children:[A.label,":"]})," ",A.value]},R)),s.jsx("div",{style:{fontSize:9,color:a.textTertiary,marginTop:4},children:"Click to dismiss"})]}),document.body)]})}function Gy(e,t,n){const r=[];if(!t)return r;if(n==="reads"&&t.reads){const o=t.reads.filter(i=>i.end>e.start&&i.start<e.end);r.push({label:"Reads in region",value:o.length.toLocaleString()});let l=0;for(const i of o)if(i.cigar){const a=i.cigar.match(/(\d+)I/g);if(a)for(const u of a)l+=parseInt(u)}if(l>0&&r.push({label:"Insertion bases",value:l.toLocaleString()}),o.length>0){const i=o.reduce((a,u)=>a+(u.mapq||0),0)/o.length;r.push({label:"Avg MAPQ",value:i.toFixed(1)})}}if((n==="coverage"||n==="reads")&&t.bins){const o=t.bins.filter(l=>l.end>e.start&&l.start<e.end);if(o.length>0){const l=o.map(c=>c.value),i=l.reduce((c,h)=>c+h,0)/l.length,a=Math.max(...l),u=Math.min(...l);r.push({label:"Avg coverage",value:i.toFixed(1)}),r.push({label:"Max coverage",value:a.toFixed(1)}),u!==a&&r.push({label:"Min coverage",value:u.toFixed(1)})}}if(n==="variants"&&t.variants){const o=t.variants.filter(l=>l.pos>=e.start&&l.pos<e.end);r.push({label:"Variants in region",value:o.length.toLocaleString()})}if((n==="annotations"||n==="genome_annotations")&&t.features){const o=t.features.filter(l=>l.end>e.start&&l.start<e.end);r.push({label:"Features in region",value:o.length.toLocaleString()})}return r}class Yy extends C.Component{constructor(t){super(t),this.state={hasError:!1,error:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}render(){var t;return this.state.hasError?s.jsxs("div",{style:{padding:8,color:"#ef9a9a",fontSize:11},children:["Track error: ",((t=this.state.error)==null?void 0:t.message)||"Unknown error"]}):this.props.children}}function Qy({track:e,containerWidth:t,labelWidth:n=140,onLabelResizeStart:r,isDragging:o,isDropTarget:l,onDragStart:i,onDragOver:a,onDrop:u,onDragEnd:c}){const{theme:h}=Xe(),{updateTrack:d,removeTrack:g}=Jt(),T=C.useRef(null),v=C.useRef(null),[x,y]=C.useState(!1),[f,p]=C.useState(!1),[m,w]=C.useState(null),b=C.useRef(null),j=C.useRef(null),S=e.track_type==="annotations"||e.track_type==="genome_annotations";Pp(T);const E=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],$=t-n,A={row:{display:"flex",borderBottom:`1px solid ${h.border}`,minHeight:40},label:{width:n,minWidth:n,background:h.panelBg,borderRight:`1px solid ${h.border}`,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 8px",overflow:"hidden",position:"relative"},trackName:{fontSize:11,color:h.trackName,fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},trackType:{fontSize:10,color:h.textTertiary,marginTop:2},trackArea:{flex:1,overflow:"hidden",position:"relative"}},R=C.useCallback(P=>{P.preventDefault(),P.stopPropagation();const W=P.clientY,O=e.height;function Y(L){const N=Math.max(30,Math.min(500,O+(L.clientY-W)));d(e.id,{height:N})}function I(){window.removeEventListener("mousemove",Y),window.removeEventListener("mouseup",I),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ns-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",Y),window.addEventListener("mouseup",I)},[e.id,e.height,d]);function U(){const P={track:e,width:$,height:e.height,onWarning:w};switch(e.track_type){case"reads":return s.jsx(Ay,{...P});case"coverage":return s.jsx(Py,{...P});case"variants":return s.jsx(Uy,{...P});case"annotations":case"genome_annotations":return s.jsx(Iy,{...P});default:return s.jsx("div",{style:{padding:8,color:h.textTertiary,fontSize:11},children:"Unknown track type"})}}return s.jsxs("div",{style:{...A.row,height:e.height,position:"relative",opacity:o?.4:1,borderTop:l?"2px solid #888":void 0},onDragOver:P=>{P.preventDefault(),P.dataTransfer.dropEffect="move",a==null||a()},onDrop:P=>{P.preventDefault(),u==null||u()},onDragEnd:c,children:[s.jsxs("div",{style:A.label,children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("div",{draggable:!0,onDragStart:P=>{P.dataTransfer.effectAllowed="move",P.dataTransfer.setData("text/plain",e.id),i==null||i()},style:{cursor:"grab",color:h.textMuted,fontSize:14,lineHeight:1,userSelect:"none",flexShrink:0,padding:"0 2px"},title:"Drag to reorder tracks",children:"≡"}),s.jsx("div",{ref:b,children:S?s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:"#888",cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)",backgroundImage:"linear-gradient(135deg, #ef5350 25%, #66bb6a 25%, #66bb6a 50%, #42a5f5 50%, #42a5f5 75%, #ffa726 75%)"},title:"Click to customize annotation colors",onMouseDown:P=>{P.stopPropagation(),p(W=>!W)}}),f&&Wn.createPortal(s.jsx(Jy,{track:e,theme:h,anchorRef:b,onClose:()=>p(!1),onChange:(P,W)=>{const O={...e.annotationColors||{},[P]:W};d(e.id,{annotationColors:O})},onReset:()=>d(e.id,{annotationColors:null})}),document.body)]}):s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:e.color,cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)"},title:"Click to pick color, double-click for full palette",onMouseDown:P=>{P.stopPropagation(),y(!0)},onDoubleClick:P=>{var W;P.stopPropagation(),y(!1),(W=j.current)==null||W.click()}}),s.jsx("input",{ref:j,type:"color",value:e.color||"#78909c",onChange:P=>d(e.id,{color:P.target.value}),style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0}}),x&&Wn.createPortal(s.jsx("div",{style:{position:"fixed",left:b.current?b.current.getBoundingClientRect().left:0,top:b.current?b.current.getBoundingClientRect().bottom+4:0,zIndex:10001,background:h.panelBg,border:`1px solid ${h.borderAccent}`,borderRadius:4,padding:6,boxShadow:"0 4px 12px rgba(0,0,0,0.5)",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},onMouseLeave:()=>y(!1),children:E.map(P=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:P,cursor:"pointer",border:P===e.color?`2px solid ${h.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onMouseUp:()=>{d(e.id,{color:P}),y(!1)}},P))}),document.body)]})}),s.jsx("div",{style:{...A.trackName,flex:1},title:e.name,children:e.name}),s.jsx("span",{title:"Remove track",onClick:P=>{P.stopPropagation(),g(e.id)},style:{color:"#e53935",fontSize:13,fontWeight:700,cursor:"pointer",lineHeight:1,flexShrink:0,padding:"0 2px",opacity:.7,transition:"opacity 0.15s"},onMouseEnter:P=>P.currentTarget.style.opacity="1",onMouseLeave:P=>P.currentTarget.style.opacity="0.7",children:"×"})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsxs("div",{style:A.trackType,children:[e.file_format," · ",e.track_type]}),m&&s.jsx(Hy,{message:m,theme:h})]}),r&&s.jsx("div",{onMouseDown:r,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:P=>P.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:P=>P.currentTarget.style.background="transparent"})]}),s.jsxs("div",{style:A.trackArea,ref:T,children:[s.jsx(Yy,{children:U()}),s.jsx(Vy,{width:$,height:e.height,trackData:jp(e.id),trackType:e.track_type})]}),s.jsx("div",{ref:v,onMouseDown:R,title:"Drag to resize track height",style:{position:"absolute",left:0,right:0,bottom:-2,height:5,cursor:"ns-resize",zIndex:10,background:"transparent"},onMouseEnter:P=>P.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:P=>P.currentTarget.style.background="transparent"})]})}const Xy=[{key:"cds",label:"CDS"},{key:"exon",label:"Exon"},{key:"gene",label:"Gene"},{key:"transcript",label:"Transcript"},{key:"utr",label:"UTR"},{key:"rrna",label:"rRNA"},{key:"trna",label:"tRNA"},{key:"repeat",label:"Repeat"},{key:"default",label:"Other"}],Ky=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],qy={cds:"geneCds",exon:"geneExon",gene:"geneGene",transcript:"geneTranscript",utr:"geneUtr",rrna:"geneRrna",trna:"geneTrna",repeat:"geneRepeat",default:"geneDefault"};function Jy({track:e,theme:t,anchorRef:n,onClose:r,onChange:o,onReset:l}){var x;const[i,a]=C.useState(null),u=C.useRef(null),[c,h]=C.useState(null),d=e.annotationColors||{},g=(x=n.current)==null?void 0:x.getBoundingClientRect();function T(y){return d[y]||t[qy[y]]||Sp[y]}function v(y){h(y),u.current&&(u.current.value=T(y),u.current.click())}return s.jsxs("div",{style:{position:"fixed",left:g?Math.min(g.left,window.innerWidth-220):0,top:g?g.bottom+4:0,zIndex:10001,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:6,padding:"8px 0",boxShadow:"0 6px 20px rgba(0,0,0,0.5)",width:210,maxHeight:340,overflowY:"auto"},onMouseLeave:r,children:[s.jsx("div",{style:{fontSize:10,fontWeight:700,color:t.textSecondary,textTransform:"uppercase",letterSpacing:1,padding:"0 10px 6px",borderBottom:`1px solid ${t.border}`,marginBottom:4},children:"Annotation Colors"}),Xy.map(({key:y,label:f})=>{const p=T(y);return s.jsxs("div",{children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 10px",cursor:"pointer",fontSize:11,color:t.textPrimary},onMouseEnter:m=>m.currentTarget.style.background=t.selectedRow,onMouseLeave:m=>m.currentTarget.style.background="transparent",onClick:()=>a(i===y?null:y),children:[s.jsx("span",{style:{display:"inline-block",width:14,height:14,borderRadius:3,background:p,border:"1px solid rgba(255,255,255,0.15)",flexShrink:0,cursor:"pointer"},onDoubleClick:m=>{m.stopPropagation(),v(y)},title:"Click to expand, double-click for full picker"}),s.jsx("span",{style:{flex:1},children:f}),s.jsx("span",{style:{fontSize:9,color:t.textTertiary},children:i===y?"▲":"▼"})]}),i===y&&s.jsx("div",{style:{padding:"4px 10px 6px 32px",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},children:Ky.map(m=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:m,cursor:"pointer",border:m===p?`2px solid ${t.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onClick:()=>{o(y,m),a(null)}},m))})]},y)}),s.jsx("div",{style:{borderTop:`1px solid ${t.border}`,marginTop:4,paddingTop:4},children:s.jsx("div",{style:{padding:"4px 10px",fontSize:10,color:t.textTertiary,cursor:"pointer",textAlign:"center"},onMouseEnter:y=>{y.currentTarget.style.color=t.textPrimary},onMouseLeave:y=>{y.currentTarget.style.color=t.textTertiary},onClick:l,children:"Reset to defaults"})}),s.jsx("input",{ref:u,type:"color",style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0},onChange:y=>{c&&o(c,y.target.value)}})]})}function Zy({labelWidth:e}){const{genome:t,region:n}=at(),{tracks:r}=Jt(),{theme:o,themeName:l,customTheme:i}=Xe(),[a,u]=C.useState(!1),[c,h]=C.useState(!1),d=!!t;C.useEffect(()=>{if(!d)return;function x(y){y.preventDefault(),y.returnValue=""}return window.addEventListener("beforeunload",x),()=>window.removeEventListener("beforeunload",x)},[d]),C.useEffect(()=>{if(!d)return;function x(y){(y.ctrlKey||y.metaKey)&&y.key==="w"&&(y.preventDefault(),u(!0))}return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[d]);const g=C.useCallback(()=>u(!1),[]),T=C.useCallback(()=>{window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[]),v=C.useCallback(()=>{h(!0);try{const x=Da(t,n,r,l,i,e);Ua(x),Rp(x)}catch{}h(!1),window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[t,n,r,l,i,e]);return a?s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center"},onClick:g,children:s.jsxs("div",{style:{background:o.panelBg,border:`1px solid ${o.borderAccent}`,borderRadius:8,padding:"24px 28px",maxWidth:400,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.6)"},onClick:x=>x.stopPropagation(),children:[s.jsx("div",{style:{fontSize:16,fontWeight:700,color:o.textPrimary,marginBottom:8},children:"Leave BiNgo Genome Viewer?"}),s.jsxs("div",{style:{fontSize:12,color:o.textSecondary,lineHeight:1.7,marginBottom:20},children:["You have an active session with"," ",s.jsxs("strong",{style:{color:o.textPrimary},children:[r.length," track",r.length!==1?"s":""]})," loaded. Unsaved changes will be lost."]}),s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[s.jsx("button",{onClick:g,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Return to App"}),s.jsx("button",{onClick:v,disabled:c,style:{background:o.btnBg,border:`1px solid ${o.borderStrong}`,borderRadius:4,color:o.btnText,padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:c?"Saving...":"Save Session & Exit"}),s.jsx("button",{onClick:T,style:{background:"transparent",border:`1px solid ${o.border}`,borderRadius:4,color:"#e57373",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Exit Without Saving"})]})]})}):null}const $c="2.3.5";let ex=0;function Nc({size:e=32}){const[t]=Hs.useState(()=>`blogo${++ex}`);return s.jsxs("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{flexShrink:0},xmlns:"http://www.w3.org/2000/svg",children:[s.jsxs("defs",{children:[s.jsxs("radialGradient",{id:`${t}_bg`,cx:"35%",cy:"30%",r:"65%",children:[s.jsx("stop",{offset:"0%",stopColor:"#5eb8ff"}),s.jsx("stop",{offset:"50%",stopColor:"#1976d2"}),s.jsx("stop",{offset:"100%",stopColor:"#0d47a1"})]}),s.jsxs("radialGradient",{id:`${t}_sh`,cx:"30%",cy:"25%",r:"30%",children:[s.jsx("stop",{offset:"0%",stopColor:"#ffffff",stopOpacity:"0.7"}),s.jsx("stop",{offset:"100%",stopColor:"#ffffff",stopOpacity:"0"})]})]}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_bg)`}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"white"}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"none",stroke:"#1565c0",strokeWidth:"2.5"}),s.jsx("text",{x:"50",y:"39",textAnchor:"middle",fontSize:"13",fontWeight:"800",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"BN"}),s.jsx("text",{x:"50",y:"64",textAnchor:"middle",fontSize:"30",fontWeight:"900",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"1"}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_sh)`})]})}function tx({theme:e,labelWidth:t}){return s.jsxs("div",{style:{display:"flex",borderBottom:`1px solid ${e.border}`,height:60,opacity:.45},children:[s.jsx("div",{"data-tour":"skeleton-track-label",style:{width:t,minWidth:t,background:e.panelBg,borderRight:`1px solid ${e.border}`,padding:"6px 8px",display:"flex",flexDirection:"column",justifyContent:"center",gap:4},children:s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[s.jsx("span",{style:{fontSize:14,color:e.textTertiary,userSelect:"none",lineHeight:1},children:"≡"}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:"#78909c",flexShrink:0}}),s.jsx("span",{style:{fontSize:11,fontWeight:600,color:e.textSecondary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:"Track Name"}),s.jsx("span",{style:{fontSize:13,color:e.textTertiary,lineHeight:1,padding:"0 2px"},children:"×"})]})}),s.jsx("div",{style:{flex:1,background:e.canvasBg}})]})}function nx(){const{theme:e}=Xe(),{genome:t,region:n,setGenome:r,navigateTo:o}=at(),{tracks:l,reorderTracks:i,addTrack:a,uploadTrack:u,commitTrack:c,discardTrack:h,addGenomeAnnotationTrack:d,restoreAnnotationTracks:g}=Jt(),T=C.useRef(null),[v,x]=C.useState(800),[y,f]=C.useState(!1),[p,m]=C.useState(!1),[w,b]=C.useState(!1),[j,S]=C.useState(!1),[E,$]=C.useState(!1),[A,R]=C.useState(!1),[U,P]=C.useState(140),[W,O]=C.useState(null),[Y,I]=C.useState(null),[L,N]=C.useState(!1),[D,z]=C.useState(null),[F,V]=C.useState(null),[M,k]=C.useState(null),Q=C.useRef(0);Sy(U),C.useEffect(()=>{const B=()=>fetch("/api/heartbeat").catch(()=>{});B();const q=setInterval(B,1e4);return()=>clearInterval(q)},[]);const ee=C.useRef(n==null?void 0:n.chrom);C.useEffect(()=>{n!=null&&n.chrom&&n.chrom!==ee.current&&(ee.current=n.chrom,g())},[n==null?void 0:n.chrom,g]);const ce=new Set([".gb",".gbk",".genbank",".fasta",".fa"]),he=new Set([".bam",".bw",".bigwig",".wig",".bedgraph",".bdg",".vcf",".bed",".gtf",".gff",".gff2",".gff3"]),pe=new Set([".bai"]);function ae(B){if(!B)return"";if(B.toLowerCase().endsWith(".vcf.gz"))return".vcf.gz";const q=B.lastIndexOf(".");return q>=0?B.slice(q).toLowerCase():""}const ie=C.useCallback(B=>{var q,X;B.preventDefault(),B.stopPropagation(),(X=(q=B.dataTransfer)==null?void 0:q.types)!=null&&X.includes("Files")&&(Q.current++,Q.current===1&&N(!0))},[]),ne=C.useCallback(B=>{var q,X;B.preventDefault(),B.stopPropagation(),(X=(q=B.dataTransfer)==null?void 0:q.types)!=null&&X.includes("Files")&&(Q.current--,Q.current<=0&&(Q.current=0,N(!1)))},[]),xe=C.useCallback(B=>{B.preventDefault(),B.stopPropagation()},[]);function Me(B){const q=B==null?void 0:B.compatibility;return q&&q.status!=="ok"&&q.status!=="no_genome"}const ve=C.useCallback(async B=>{var Ie,ut,Wa,Ha,Va;if(B.preventDefault(),B.stopPropagation(),Q.current=0,N(!1),!((ut=(Ie=B.dataTransfer)==null?void 0:Ie.types)!=null&&ut.includes("Files")))return;const q=Array.from(B.dataTransfer.files);if(!q.length)return;const X=[],Z=[],le=[],oe=[];for(const Re of q){const Be=ae(Re.name),yt=Re.name.toLowerCase();ce.has(Be)?X.push(Re):he.has(Be)||Be===".vcf.gz"?Z.push(Re):pe.has(Be)||yt.endsWith(".bam.bai")?le.push(Re):oe.push(Re)}const fe=Z.filter(Re=>Re.name.toLowerCase().endsWith(".bam")&&Re.size>50*1024*1024),we=le.filter(Re=>Re.size>10*1024*1024);if(fe.length||we.length){const Re=[...fe,...we].map(yt=>yt.name).join(", "),Be=[...fe,...we].reduce((yt,jo)=>yt+jo.size,0)/(1024*1024);z({error:`${Re} (${Be.toFixed(0)} MB) — large files load faster via the Path button. Click 📂 Path in the toolbar and paste the file path instead of uploading.`}),setTimeout(()=>z(null),1e4);return}if(oe.length&&!X.length&&!Z.length&&!le.length){z({error:`Unsupported file${oe.length>1?"s":""}: ${oe.map(Re=>Re.name).join(", ")}`}),setTimeout(()=>z(null),4e3);return}try{if(X.length>0&&!t){z({msg:`Loading genome: ${X[0].name}...`});const Be=(await yn.load(X[0])).data;if(Be.name&&(Be.name=Ft(Be.name)),r(Be),((Wa=Be.chromosomes)==null?void 0:Wa.length)>0){const yt=Be.chromosomes[0];o(yt.name,0,Math.min(yt.length,5e4))}Be.is_annotated&&d({id:"genome_annotations",name:`${Be.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:Be.annotated_chromosomes||null})}else X.length>0&&t&&V({files:X});if(Z.length>0){if(!t&&X.length===0){z({error:"Load a genome file first (.fasta, .gb, .genbank)"}),setTimeout(()=>z(null),4e3);return}z({msg:`Loading ${Z.length} track${Z.length>1?"s":""}...`});const Re=[],Be=[],yt=[];for(const jo of Z)try{const kn=await u(jo,void 0);Me(kn)?Be.push(kn):(c(kn),Re.push(kn))}catch(kn){yt.push(`${jo.name}: ${((Va=(Ha=kn.response)==null?void 0:Ha.data)==null?void 0:Va.detail)||kn.message}`)}if(yt.length){z({error:yt.join("; ")}),setTimeout(()=>z(null),5e3);return}Be.length>0&&k({tracks:Be})}oe.length?(z({error:`Skipped unsupported: ${oe.map(Re=>Re.name).join(", ")}`}),setTimeout(()=>z(null),4e3)):(z({msg:"Files loaded"}),setTimeout(()=>z(null),2e3))}catch(Re){z({error:Re.message||"Drop failed"}),setTimeout(()=>z(null),5e3)}},[t,r,o,a,d]),Fe=C.useCallback(async()=>{var q,X;if(!F)return;const B=F.files;V(null);try{const Z=[];for(const le of B){z({msg:`Adding chromosomes from ${le.name}...`});try{const fe=(await yn.addChromosomes(le)).data;fe.name&&(fe.name=Ft(fe.name)),r(fe),fe.is_annotated&&d({id:"genome_annotations",name:`${fe.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:fe.annotated_chromosomes||null})}catch(oe){Z.push(`${le.name}: ${((X=(q=oe.response)==null?void 0:q.data)==null?void 0:X.detail)||oe.message}`)}}Z.length?(z({error:Z.join("; ")}),setTimeout(()=>z(null),5e3)):(z({msg:`Added chromosomes from ${B.length} file${B.length>1?"s":""}`}),setTimeout(()=>z(null),3e3))}catch(Z){z({error:Z.message||"Failed to add chromosomes"}),setTimeout(()=>z(null),5e3)}},[F,r,d]),et=C.useCallback(async()=>{var q,X;if(!F)return;const B=F.files;V(null);try{z({msg:`Loading ${B.length} track${B.length>1?"s":""}...`});const Z=[];for(const le of B)try{await a(le,void 0)}catch(oe){Z.push(`${le.name}: ${((X=(q=oe.response)==null?void 0:q.data)==null?void 0:X.detail)||oe.message}`)}Z.length?(z({error:Z.join("; ")}),setTimeout(()=>z(null),5e3)):(z({msg:`Added ${B.length} track${B.length>1?"s":""}`}),setTimeout(()=>z(null),3e3))}catch(Z){z({error:Z.message||"Failed to load tracks"}),setTimeout(()=>z(null),5e3)}},[F,a]),me=C.useCallback(async()=>{if(M){for(const B of M.tracks)await h(B.id);k(null)}},[M,h]),gt=C.useCallback(()=>{if(M){for(const B of M.tracks)c(B);k(null),z({msg:`Added ${M.tracks.length} track${M.tracks.length>1?"s":""}`}),setTimeout(()=>z(null),3e3)}},[M,c]),G=C.useCallback(B=>{B.preventDefault();const q=B.clientX,X=U;function Z(oe){P(Math.max(60,Math.min(400,X+(oe.clientX-q))))}function le(){window.removeEventListener("mousemove",Z),window.removeEventListener("mouseup",le),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ew-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",Z),window.addEventListener("mouseup",le)},[U]);C.useEffect(()=>{if(!T.current)return;const B=new ResizeObserver(q=>{for(const X of q)x(X.contentRect.width)});return B.observe(T.current),()=>B.disconnect()},[]);const J=C.useCallback(B=>B.visible?!B.targetChromosomes||!(n!=null&&n.chrom)?!0:B.targetChromosomes.includes(n.chrom):!1,[n==null?void 0:n.chrom]),te={app:{display:"flex",flexDirection:"column",height:"100vh",background:e.appBg,color:e.textPrimary},header:{background:e.headerBg,borderBottom:`2px solid ${e.borderAccent}`,padding:"8px 16px",display:"flex",alignItems:"center",justifyContent:"space-between"},headerLeft:{display:"flex",alignItems:"center",gap:12},title:{fontSize:18,fontWeight:700,color:e.textPrimary,letterSpacing:1},subtitle:{fontSize:11,color:e.textTertiary},headerBtns:{display:"flex",gap:8},btn:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600,display:"flex",alignItems:"center",gap:6},trackArea:{flex:1,overflowY:"auto",overflowX:"hidden",display:"flex",flexDirection:"column"},emptyState:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",flex:1,color:e.textMuted,gap:12},emptyTitle:{fontSize:22,fontWeight:300},emptyHint:{fontSize:13}};return s.jsxs("div",{style:te.app,onDragEnter:ie,onDragLeave:ne,onDragOver:xe,onDrop:ve,children:[s.jsxs("div",{style:te.header,children:[s.jsxs("div",{style:te.headerLeft,children:[s.jsx(Nc,{size:34}),s.jsxs("div",{children:[s.jsx("div",{style:te.title,children:"BiNgo Genome Viewer"}),t&&s.jsxs("div",{style:te.subtitle,children:[t.name," · ",t.chromosomes.length," chr"]})]}),s.jsxs("button",{onClick:()=>$(!0),title:"About / References",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:B=>{B.currentTarget.style.color=e.textPrimary,B.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:B=>{B.currentTarget.style.color=e.textSecondary,B.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("circle",{cx:"8",cy:"4.5",r:"1.2"}),s.jsx("rect",{x:"7",y:"6.5",width:"2",height:"5.5",rx:"0.8"})]}),"Info"]}),s.jsxs("button",{onClick:()=>R(!0),title:"Guided Tour",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:B=>{B.currentTarget.style.color=e.textPrimary,B.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:B=>{B.currentTarget.style.color=e.textSecondary,B.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("path",{d:"M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zM8 13.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"})]}),"Help"]})]}),s.jsxs("div",{style:te.headerBtns,"data-tour":"header-btns",children:[s.jsxs("button",{style:te.btn,onClick:()=>S(!0),title:"Save or restore a session",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:[s.jsx("path",{d:"M2 2h8v8H2z"}),s.jsx("path",{d:"M4 2v4h4V2"}),s.jsx("path",{d:"M5 3h2"})]}),"Save Session"]}),s.jsxs("button",{style:te.btn,onClick:()=>m(!0),title:"Customize color theme",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",style:{flexShrink:0},children:[s.jsx("rect",{x:"0",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#66bb6a"}),s.jsx("rect",{x:"6.5",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#42a5f5"}),s.jsx("rect",{x:"0",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ffa726"}),s.jsx("rect",{x:"6.5",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ab47bc"})]}),"Theme"]}),s.jsxs("button",{"data-tour":"btn-export",style:{...te.btn,...n&&l.length>0?{}:{opacity:.35,cursor:"default"}},onClick:()=>{n&&l.length>0&&b(!0)},title:"Export current view as SVG or PNG",children:[s.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:s.jsx("path",{d:"M6 1v7M3 5.5L6 8.5 9 5.5M2 11h8"})}),"Export Image"]}),s.jsxs("button",{"data-tour":"btn-settings",style:{...te.btn,...l.length===0?{opacity:.35,cursor:"default"}:{}},onClick:()=>{l.length>0&&f(!0)},title:"Adjust height, scale, color, and bar width for tracks",children:["⚙"," Track Settings"]})]})]}),s.jsx(W0,{}),s.jsx(jy,{}),s.jsxs("div",{style:te.trackArea,ref:T,"data-tour":"track-area",children:[l.filter(J).length===0&&s.jsx(tx,{theme:e,labelWidth:U}),t?n?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{display:"flex"},children:[s.jsx("div",{style:{width:U,minWidth:U,background:e.panelBg,borderRight:`1px solid ${e.border}`,position:"relative"},children:s.jsx("div",{onMouseDown:G,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:B=>B.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:B=>B.currentTarget.style.background="transparent"})}),s.jsx(Ey,{width:v-U})]}),l.filter(J).map(B=>s.jsx(Qy,{track:B,containerWidth:v,labelWidth:U,onLabelResizeStart:G,isDragging:W===B.id,isDropTarget:Y===B.id,onDragStart:()=>O(B.id),onDragOver:()=>I(B.id),onDrop:()=>{W&&W!==B.id&&i(W,B.id),O(null),I(null)},onDragEnd:()=>{O(null),I(null)}},B.id)),l.length===0&&s.jsx("div",{style:{padding:24,color:e.textMuted,fontSize:13},children:"Add tracks above — BAM, VCF, BigWig, BED, GTF, GFF, WIG..."})]}):s.jsx("div",{style:te.emptyState,children:s.jsx("div",{style:te.emptyHint,children:"Select a chromosome to begin"})}):s.jsxs("div",{style:te.emptyState,children:[s.jsx("div",{style:te.emptyTitle,children:"No genome loaded"}),s.jsx("div",{style:te.emptyHint,children:"Load a FASTA or GenBank file above to get started"})]})]}),y&&s.jsx(Q0,{onClose:()=>f(!1)}),p&&s.jsx(Z0,{onClose:()=>m(!1)}),w&&s.jsx(ay,{onClose:()=>b(!1)}),j&&s.jsx(by,{onClose:()=>S(!1),labelWidth:U,setLabelWidth:P}),A&&s.jsx(Ty,{onClose:()=>{R(!1),f(!1),m(!1)},theme:e,onAction:B=>{B==="open-settings"?(f(!0),m(!1)):B==="open-theme"?(m(!0),f(!1)):(f(!1),m(!1))}}),E&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},onClick:()=>$(!1),children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.border}`,borderRadius:8,padding:"28px 36px",maxWidth:520,maxHeight:"85vh",overflowY:"auto",color:e.textPrimary,lineHeight:1.7},onClick:B=>B.stopPropagation(),children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:16},children:[s.jsx(Nc,{size:44}),s.jsx("div",{style:{fontSize:20,fontWeight:700},children:"BiNgo Genome Viewer"})]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Version:"})," ",$c]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Publisher:"})," Billy M Ngo"]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:20},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Published:"})," April 2026"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,background:e.canvasBg,border:`1px solid ${e.border}`,borderRadius:4,padding:"10px 14px",fontFamily:"monospace",lineHeight:1.6,marginBottom:20,userSelect:"all"},children:["Ngo, B.M. (2026). BiNgo Genome Viewer (v",$c,") [Software]."]}),s.jsxs("details",{style:{marginBottom:20},children:[s.jsx("summary",{style:{cursor:"pointer",fontSize:13,fontWeight:600,color:e.textPrimary,marginBottom:8},children:"References & Acknowledgments"}),s.jsxs("div",{style:{fontSize:11,color:e.textSecondary,lineHeight:1.8,paddingTop:8},children:[s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginBottom:4},children:"Software Dependencies"}),s.jsxs("div",{children:[s.jsx("strong",{children:"FastAPI"})," ","—"," Ram","í","rez, S. (2018). A modern web framework for building APIs with Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Uvicorn"})," ","—"," Encode OSS. ASGI server implementation for Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BioPython"})," ","—"," Cock, P.J.A. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(11), 1422","–","1423."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"pyfaidx"})," ","—"," Shirley, M.D. et al. (2015). ",s.jsx("em",{children:"PeerJ PrePrints"}),", 3:e1196."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"bamnostic"})," ","—"," Sherman, M.A. & Mills, R.E. (2019). Pure Python BAM parser."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"React"})," ","—"," Meta Platforms, Inc. JavaScript UI library."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Vite"})," ","—"," You, E. (2020). Next generation frontend tooling."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"File Format Specifications"}),s.jsxs("div",{children:[s.jsx("strong",{children:"SAM/BAM"})," ","—"," Li, H. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(16), 2078","–","2079."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"VCF"})," ","—"," Danecek, P. et al. (2011). ",s.jsx("em",{children:"Bioinformatics"}),", 27(15), 2156","–","2158."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BigWig/WIG"})," ","—"," Kent, W.J. et al. (2010). ",s.jsx("em",{children:"Bioinformatics"}),", 26(17), 2204","–","2207."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BED"})," ","—"," UCSC Genome Browser, UC Santa Cruz."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GFF3"})," ","—"," Sequence Ontology Project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GTF"})," ","—"," Ensembl genome database project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GenBank"})," ","—"," Benson, D.A. et al. (2013). ",s.jsx("em",{children:"Nucleic Acids Res."}),", 41(D1), D36","–","D42."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Inspiration"}),s.jsxs("div",{children:[s.jsx("strong",{children:"IGV"})," ","—"," Robinson, J.T. et al. (2011). ",s.jsx("em",{children:"Nature Biotechnology"}),", 29(1), 24","–","26."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Acknowledgments"}),s.jsx("div",{children:"Early version testing and feedback:"}),s.jsx("div",{children:"Amanda Antoch, Isaac Poarch, Otto Chipashvili, Jake Colautti"})]})]}),s.jsx("div",{style:{textAlign:"right"},children:s.jsx("button",{onClick:()=>$(!1),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 18px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Close"})})]})}),F&&(()=>{const B=F.files.length>1,q=F.files.map(X=>X.name).join(", ");return s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:440,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:X=>X.stopPropagation(),children:[s.jsxs("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:["Genome file",B?"s":""," detected"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[s.jsx("strong",{style:{color:e.textPrimary},children:q}),B?" appear to be genome files. A genome is already loaded.":" appears to be a genome file. A genome is already loaded.",s.jsx("br",{}),"How would you like to handle ",B?"them":"it","?"]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:()=>V(null),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsxs("button",{onClick:et,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Track",B?"s":""]}),s.jsxs("button",{onClick:Fe,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Chromosome",B?"s":""]})]})]})})})(),M&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:480,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:B=>B.stopPropagation(),children:[s.jsx("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:"Track compatibility warning"}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[M.tracks.map(B=>{var q;return s.jsxs("div",{style:{marginBottom:6},children:[s.jsx("strong",{style:{color:e.textPrimary},children:B.name})," — ",((q=B.compatibility)==null?void 0:q.message)||"Possible mismatch with loaded genome"]},B.id)}),s.jsx("div",{style:{marginTop:8},children:M.tracks.length>1?"These tracks may not match the loaded genome.":"This track may not match the loaded genome."})]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:me,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsx("button",{onClick:gt,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Load Anyway"})]})]})}),L&&s.jsx("div",{style:{position:"fixed",inset:0,zIndex:9998,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:s.jsxs("div",{style:{border:`3px dashed ${e.textSecondary}`,borderRadius:16,padding:"40px 60px",textAlign:"center"},children:[s.jsx("div",{style:{fontSize:28,fontWeight:300,color:e.textPrimary,marginBottom:8},children:"Drop files here"}),s.jsx("div",{style:{fontSize:13,color:e.textSecondary},children:"Genome (.gb, .fasta) or track files (.bam, .bw, .wig, .vcf, .bed, .gff, .gtf)"})]})}),D&&s.jsx("div",{style:{position:"fixed",bottom:20,left:"50%",transform:"translateX(-50%)",zIndex:10001,padding:"8px 20px",borderRadius:6,background:D.error?"#c62828":e.panelBg,border:`1px solid ${D.error?"#e53935":e.borderAccent}`,color:D.error?"#fff":"#81c784",fontSize:12,fontWeight:600,boxShadow:"0 4px 16px rgba(0,0,0,0.5)"},children:D.error||D.msg}),t&&s.jsx(Zy,{labelWidth:U})]})}function rx(){return s.jsx(F0,{children:s.jsx(rg,{children:s.jsx($0,{children:s.jsx(nx,{})})})})}Di.createRoot(document.getElementById("root")).render(s.jsx(Hs.StrictMode,{children:s.jsx(rx,{})}));
@@ -10,7 +10,7 @@
10
10
  body { font-family: Arial, Helvetica, sans-serif; background: #1a1a1a; color: #e0e0e0; height: 100vh; overflow: hidden; }
11
11
  #root { height: 100vh; display: flex; flex-direction: column; }
12
12
  </style>
13
- <script type="module" crossorigin src="/assets/index-Dbtbm6Rs.js"></script>
13
+ <script type="module" crossorigin src="/assets/index-auU-stei.js"></script>
14
14
  </head>
15
15
  <body>
16
16
  <div id="root"></div>
@@ -24,7 +24,7 @@ from api.genome import router as genome_router
24
24
  from api.tracks import router as tracks_router
25
25
  from api.data import router as data_router
26
26
 
27
- app = FastAPI(title="BiNgo Genome Viewer API", version="2.3.4")
27
+ app = FastAPI(title="BiNgo Genome Viewer API", version="2.3.5")
28
28
 
29
29
  app.add_middleware(
30
30
  CORSMiddleware,
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "BiNgoViewer"
7
- version = "2.3.4"
7
+ version = "2.3.5"
8
8
  description = "BiNgo Genome Viewer — a lightweight browser-based genomics viewer"
9
9
  readme = "README.md"
10
10
  license = {text = "Proprietary"}
File without changes