figpack-spike-sorting 0.1.3__tar.gz → 0.1.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 (30) hide show
  1. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/PKG-INFO +1 -1
  2. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/__init__.py +1 -1
  3. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/figpack_spike_sorting.js +1 -1
  4. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/Autocorrelograms.py +2 -2
  5. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/AverageWaveforms.py +2 -2
  6. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/CrossCorrelograms.py +2 -2
  7. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/RasterPlot.py +2 -2
  8. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/SortingCuration.py +2 -2
  9. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/SpikeAmplitudes.py +2 -2
  10. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitLocations.py +2 -2
  11. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitMetricsGraph.py +2 -2
  12. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitsTable.py +2 -2
  13. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting.egg-info/PKG-INFO +1 -1
  14. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/setup.py +1 -1
  15. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/README.md +0 -0
  16. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/spike_sorting_extension.py +0 -0
  17. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/style.css +0 -0
  18. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/AutocorrelogramItem.py +0 -0
  19. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/CrossCorrelogramItem.py +0 -0
  20. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/RasterPlotItem.py +0 -0
  21. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/SpikeAmplitudesItem.py +0 -0
  22. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitSimilarityScore.py +0 -0
  23. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitsTableColumn.py +0 -0
  24. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/UnitsTableRow.py +0 -0
  25. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting/views/__init__.py +0 -0
  26. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting.egg-info/SOURCES.txt +0 -0
  27. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting.egg-info/dependency_links.txt +0 -0
  28. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting.egg-info/requires.txt +0 -0
  29. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/figpack_spike_sorting.egg-info/top_level.txt +0 -0
  30. {figpack_spike_sorting-0.1.3 → figpack_spike_sorting-0.1.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: figpack_spike_sorting
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Spike Sorting specific extension for figpack
5
5
  Home-page: https://github.com/flatironinstitute/figpack
6
6
  Author: figpack contributors
@@ -2,4 +2,4 @@
2
2
  figpack_spike_sorting - Spike Sorting specific extension for figpack
3
3
  """
4
4
 
5
- __version__ = "0.1.3"
5
+ __version__ = "0.1.5"
@@ -188,4 +188,4 @@ export default theme;`}function eS(e){return typeof e=="number"?`${(e*100).toFix
188
188
  animation: ${Um} 1.4s ease-in-out infinite;
189
189
  `:null,FB=e=>{const{classes:t,variant:n,color:r,disableShrink:i}=e,a={root:["root",n,`color${Ue(r)}`],svg:["svg"],circle:["circle",`circle${Ue(n)}`,i&&"circleDisableShrink"]};return Un(a,MB,t)},NB=wt("span",{name:"MuiCircularProgress",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,t[n.variant],t[`color${Ue(n.color)}`]]}})(In(({theme:e})=>({display:"inline-block",variants:[{props:{variant:"determinate"},style:{transition:e.transitions.create("transform")}},{props:{variant:"indeterminate"},style:_B||{animation:`${zm} 1.4s linear infinite`}},...Object.entries(e.palette).filter(No()).map(([t])=>({props:{color:t},style:{color:(e.vars||e).palette[t].main}}))]}))),RB=wt("svg",{name:"MuiCircularProgress",slot:"Svg"})({display:"block"}),OB=wt("circle",{name:"MuiCircularProgress",slot:"Circle",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.circle,t[`circle${Ue(n.variant)}`],n.disableShrink&&t.circleDisableShrink]}})(In(({theme:e})=>({stroke:"currentColor",variants:[{props:{variant:"determinate"},style:{transition:e.transitions.create("stroke-dashoffset")}},{props:{variant:"indeterminate"},style:{strokeDasharray:"80px, 200px",strokeDashoffset:0}},{props:({ownerState:t})=>t.variant==="indeterminate"&&!t.disableShrink,style:BB||{animation:`${Um} 1.4s ease-in-out infinite`}}]}))),zB=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiCircularProgress"}),{className:i,color:a="primary",disableShrink:o=!1,size:u=40,style:l,thickness:s=3.6,value:c=0,variant:f="indeterminate",...d}=r,h={...r,color:a,disableShrink:o,size:u,thickness:s,value:c,variant:f},v=FB(h),m={},D={},p={};if(f==="determinate"){const g=2*Math.PI*((Ui-s)/2);m.strokeDasharray=g.toFixed(3),p["aria-valuenow"]=Math.round(c),m.strokeDashoffset=`${((100-c)/100*g).toFixed(3)}px`,D.transform="rotate(-90deg)"}return B.jsx(NB,{className:at(v.root,i),style:{width:u,height:u,...D,...l},ownerState:h,ref:n,role:"progressbar",...p,...d,children:B.jsx(RB,{className:v.svg,ownerState:h,viewBox:`${Ui/2} ${Ui/2} ${Ui} ${Ui}`,children:B.jsx(OB,{className:v.circle,style:m,ownerState:h,cx:Ui,cy:Ui,r:(Ui-s)/2,fill:"none",strokeWidth:s})})})});function UB(e){return yn("MuiIconButton",e)}const cS=bn("MuiIconButton",["root","disabled","colorInherit","colorPrimary","colorSecondary","colorError","colorInfo","colorSuccess","colorWarning","edgeStart","edgeEnd","sizeSmall","sizeMedium","sizeLarge","loading","loadingIndicator","loadingWrapper"]),IB=e=>{const{classes:t,disabled:n,color:r,edge:i,size:a,loading:o}=e,u={root:["root",o&&"loading",n&&"disabled",r!=="default"&&`color${Ue(r)}`,i&&`edge${Ue(i)}`,`size${Ue(a)}`],loadingIndicator:["loadingIndicator"],loadingWrapper:["loadingWrapper"]};return Un(u,UB,t)},$B=wt(sS,{name:"MuiIconButton",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.loading&&t.loading,n.color!=="default"&&t[`color${Ue(n.color)}`],n.edge&&t[`edge${Ue(n.edge)}`],t[`size${Ue(n.size)}`]]}})(In(({theme:e})=>({textAlign:"center",flex:"0 0 auto",fontSize:e.typography.pxToRem(24),padding:8,borderRadius:"50%",color:(e.vars||e).palette.action.active,transition:e.transitions.create("background-color",{duration:e.transitions.duration.shortest}),variants:[{props:t=>!t.disableRipple,style:{"--IconButton-hoverBg":e.alpha((e.vars||e).palette.action.active,(e.vars||e).palette.action.hoverOpacity),"&:hover":{backgroundColor:"var(--IconButton-hoverBg)","@media (hover: none)":{backgroundColor:"transparent"}}}},{props:{edge:"start"},style:{marginLeft:-12}},{props:{edge:"start",size:"small"},style:{marginLeft:-3}},{props:{edge:"end"},style:{marginRight:-12}},{props:{edge:"end",size:"small"},style:{marginRight:-3}}]})),In(({theme:e})=>({variants:[{props:{color:"inherit"},style:{color:"inherit"}},...Object.entries(e.palette).filter(No()).map(([t])=>({props:{color:t},style:{color:(e.vars||e).palette[t].main}})),...Object.entries(e.palette).filter(No()).map(([t])=>({props:{color:t},style:{"--IconButton-hoverBg":e.alpha((e.vars||e).palette[t].main,(e.vars||e).palette.action.hoverOpacity)}})),{props:{size:"small"},style:{padding:5,fontSize:e.typography.pxToRem(18)}},{props:{size:"large"},style:{padding:12,fontSize:e.typography.pxToRem(28)}}],[`&.${cS.disabled}`]:{backgroundColor:"transparent",color:(e.vars||e).palette.action.disabled},[`&.${cS.loading}`]:{color:"transparent"}}))),kB=wt("span",{name:"MuiIconButton",slot:"LoadingIndicator"})(({theme:e})=>({display:"none",position:"absolute",visibility:"visible",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:(e.vars||e).palette.action.disabled,variants:[{props:{loading:!0},style:{display:"flex"}}]})),cl=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiIconButton"}),{edge:i=!1,children:a,className:o,color:u="default",disabled:l=!1,disableFocusRipple:s=!1,size:c="medium",id:f,loading:d=null,loadingIndicator:h,...v}=r,m=t9(f),D=h??B.jsx(zB,{"aria-labelledby":m,color:"inherit",size:16}),p={...r,edge:i,color:u,disabled:l,disableFocusRipple:s,loading:d,loadingIndicator:D,size:c},g=IB(p);return B.jsxs($B,{id:d?m:f,className:at(g.root,o),centerRipple:!0,focusRipple:!s,disabled:l||d,ref:n,...v,ownerState:p,children:[typeof d=="boolean"&&B.jsx("span",{className:g.loadingWrapper,style:{display:"contents"},children:B.jsx(kB,{className:g.loadingIndicator,ownerState:p,children:d&&D})}),a]})});function LB({props:e,states:t,muiFormControl:n}){return t.reduce((r,i)=>(r[i]=e[i],n&&typeof e[i]>"u"&&(r[i]=n[i]),r),{})}const jB=M.createContext(void 0);function fS(){return M.useContext(jB)}function HB(e){return yn("PrivateSwitchBase",e)}bn("PrivateSwitchBase",["root","checked","disabled","input","edgeStart","edgeEnd"]);const PB=e=>{const{classes:t,checked:n,disabled:r,edge:i}=e,a={root:["root",n&&"checked",r&&"disabled",i&&`edge${Ue(i)}`],input:["input"]};return Un(a,HB,t)},qB=wt(sS,{name:"MuiSwitchBase"})({padding:9,borderRadius:"50%",variants:[{props:{edge:"start",size:"small"},style:{marginLeft:-3}},{props:({edge:e,ownerState:t})=>e==="start"&&t.size!=="small",style:{marginLeft:-12}},{props:{edge:"end",size:"small"},style:{marginRight:-3}},{props:({edge:e,ownerState:t})=>e==="end"&&t.size!=="small",style:{marginRight:-12}}]}),VB=wt("input",{name:"MuiSwitchBase",shouldForwardProp:Cm})({cursor:"inherit",position:"absolute",opacity:0,width:"100%",height:"100%",top:0,left:0,margin:0,padding:0,zIndex:1}),dS=M.forwardRef(function(t,n){const{autoFocus:r,checked:i,checkedIcon:a,defaultChecked:o,disabled:u,disableFocusRipple:l=!1,edge:s=!1,icon:c,id:f,inputProps:d,inputRef:h,name:v,onBlur:m,onChange:D,onFocus:p,readOnly:g,required:y=!1,tabIndex:S,type:w,value:b,slots:E={},slotProps:C={},...A}=t,[T,_]=Y9({controlled:i,default:!!o}),x=fS(),F=k=>{p&&p(k),x&&x.onFocus&&x.onFocus(k)},R=k=>{m&&m(k),x&&x.onBlur&&x.onBlur(k)},z=k=>{if(k.nativeEvent.defaultPrevented)return;const q=k.target.checked;_(q),D&&D(k,q)};let N=u;x&&typeof N>"u"&&(N=x.disabled);const U=w==="checkbox"||w==="radio",I={...t,checked:T,disabled:N,disableFocusRipple:l,edge:s},L=PB(I),G={slots:E,slotProps:{input:d,...C}},[X,P]=Fo("root",{ref:n,elementType:qB,className:L.root,shouldForwardComponentProp:!0,externalForwardedProps:{...G,component:"span",...A},getSlotProps:k=>({...k,onFocus:q=>{k.onFocus?.(q),F(q)},onBlur:q=>{k.onBlur?.(q),R(q)}}),ownerState:I,additionalProps:{centerRipple:!0,focusRipple:!l,disabled:N,role:void 0,tabIndex:null}}),[j,H]=Fo("input",{ref:h,elementType:VB,className:L.input,externalForwardedProps:G,getSlotProps:k=>({...k,onChange:q=>{k.onChange?.(q),z(q)}}),ownerState:I,additionalProps:{autoFocus:r,checked:i,defaultChecked:o,disabled:N,id:U?f:void 0,name:v,readOnly:g,required:y,tabIndex:S,type:w,...w==="checkbox"&&b===void 0?{}:{value:b}}});return B.jsxs(X,{...P,children:[B.jsx(j,{...H}),T?a:c]})}),GB=Mm(B.jsx("path",{d:"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"})),YB=Mm(B.jsx("path",{d:"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"})),XB=Mm(B.jsx("path",{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z"}));function ZB(e){return yn("MuiCheckbox",e)}const Im=bn("MuiCheckbox",["root","checked","disabled","indeterminate","colorPrimary","colorSecondary","sizeSmall","sizeMedium"]),QB=e=>{const{classes:t,indeterminate:n,color:r,size:i}=e,a={root:["root",n&&"indeterminate",`color${Ue(r)}`,`size${Ue(i)}`]},o=Un(a,ZB,t);return{...t,...o}},KB=wt(dS,{shouldForwardProp:e=>Cm(e)||e==="classes",name:"MuiCheckbox",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.indeterminate&&t.indeterminate,t[`size${Ue(n.size)}`],n.color!=="default"&&t[`color${Ue(n.color)}`]]}})(In(({theme:e})=>({color:(e.vars||e).palette.text.secondary,variants:[{props:{color:"default",disableRipple:!1},style:{"&:hover":{backgroundColor:e.alpha((e.vars||e).palette.action.active,(e.vars||e).palette.action.hoverOpacity)}}},...Object.entries(e.palette).filter(No()).map(([t])=>({props:{color:t,disableRipple:!1},style:{"&:hover":{backgroundColor:e.alpha((e.vars||e).palette[t].main,(e.vars||e).palette.action.hoverOpacity)}}})),...Object.entries(e.palette).filter(No()).map(([t])=>({props:{color:t},style:{[`&.${Im.checked}, &.${Im.indeterminate}`]:{color:(e.vars||e).palette[t].main},[`&.${Im.disabled}`]:{color:(e.vars||e).palette.action.disabled}}})),{props:{disableRipple:!1},style:{"&:hover":{"@media (hover: none)":{backgroundColor:"transparent"}}}}]}))),WB=B.jsx(YB,{}),JB=B.jsx(GB,{}),eF=B.jsx(XB,{}),hS=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiCheckbox"}),{checkedIcon:i=WB,color:a="primary",icon:o=JB,indeterminate:u=!1,indeterminateIcon:l=eF,inputProps:s,size:c="medium",disableRipple:f=!1,className:d,slots:h={},slotProps:v={},...m}=r,D=u?l:o,p=u?l:i,g={...r,disableRipple:f,color:a,indeterminate:u,size:c},y=QB(g),S=v.input??s,[w,b]=Fo("root",{ref:n,elementType:KB,className:at(y.root,d),shouldForwardComponentProp:!0,externalForwardedProps:{slots:h,slotProps:v,...m},ownerState:g,additionalProps:{type:"checkbox",icon:M.cloneElement(D,{fontSize:D.props.fontSize??c}),checkedIcon:M.cloneElement(p,{fontSize:p.props.fontSize??c}),disableRipple:f,slots:h,slotProps:{input:Z9(typeof S=="function"?S(g):S,{"data-indeterminate":u})}}});return B.jsx(w,{...b,classes:y})});function tF(e){return yn("MuiFormGroup",e)}bn("MuiFormGroup",["root","row","error"]);const nF=e=>{const{classes:t,row:n,error:r}=e;return Un({root:["root",n&&"row",r&&"error"]},tF,t)},rF=wt("div",{name:"MuiFormGroup",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.row&&t.row]}})({display:"flex",flexDirection:"column",flexWrap:"wrap",variants:[{props:{row:!0},style:{flexDirection:"row"}}]}),iF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiFormGroup"}),{className:i,row:a=!1,...o}=r,u=fS(),l=LB({props:r,muiFormControl:u,states:["error"]}),s={...r,row:a,error:l.error},c=nF(s);return B.jsx(rF,{className:at(c.root,i),ownerState:s,ref:n,...o})});function aF(e){return yn("MuiSwitch",e)}const on=bn("MuiSwitch",["root","edgeStart","edgeEnd","switchBase","colorPrimary","colorSecondary","sizeSmall","sizeMedium","checked","disabled","input","thumb","track"]),oF=e=>{const{classes:t,edge:n,size:r,color:i,checked:a,disabled:o}=e,u={root:["root",n&&`edge${Ue(n)}`,`size${Ue(r)}`],switchBase:["switchBase",`color${Ue(i)}`,a&&"checked",o&&"disabled"],thumb:["thumb"],track:["track"],input:["input"]},l=Un(u,aF,t);return{...t,...l}},uF=wt("span",{name:"MuiSwitch",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.edge&&t[`edge${Ue(n.edge)}`],t[`size${Ue(n.size)}`]]}})({display:"inline-flex",width:34+12*2,height:14+12*2,overflow:"hidden",padding:12,boxSizing:"border-box",position:"relative",flexShrink:0,zIndex:0,verticalAlign:"middle","@media print":{colorAdjust:"exact"},variants:[{props:{edge:"start"},style:{marginLeft:-8}},{props:{edge:"end"},style:{marginRight:-8}},{props:{size:"small"},style:{width:40,height:24,padding:7,[`& .${on.thumb}`]:{width:16,height:16},[`& .${on.switchBase}`]:{padding:4,[`&.${on.checked}`]:{transform:"translateX(16px)"}}}}]}),lF=wt(dS,{name:"MuiSwitch",slot:"SwitchBase",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.switchBase,{[`& .${on.input}`]:t.input},n.color!=="default"&&t[`color${Ue(n.color)}`]]}})(In(({theme:e})=>({position:"absolute",top:0,left:0,zIndex:1,color:e.vars?e.vars.palette.Switch.defaultColor:`${e.palette.mode==="light"?e.palette.common.white:e.palette.grey[300]}`,transition:e.transitions.create(["left","transform"],{duration:e.transitions.duration.shortest}),[`&.${on.checked}`]:{transform:"translateX(20px)"},[`&.${on.disabled}`]:{color:e.vars?e.vars.palette.Switch.defaultDisabledColor:`${e.palette.mode==="light"?e.palette.grey[100]:e.palette.grey[600]}`},[`&.${on.checked} + .${on.track}`]:{opacity:.5},[`&.${on.disabled} + .${on.track}`]:{opacity:e.vars?e.vars.opacity.switchTrackDisabled:`${e.palette.mode==="light"?.12:.2}`},[`& .${on.input}`]:{left:"-100%",width:"300%"}})),In(({theme:e})=>({"&:hover":{backgroundColor:e.alpha((e.vars||e).palette.action.active,(e.vars||e).palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}},variants:[...Object.entries(e.palette).filter(No(["light"])).map(([t])=>({props:{color:t},style:{[`&.${on.checked}`]:{color:(e.vars||e).palette[t].main,"&:hover":{backgroundColor:e.alpha((e.vars||e).palette[t].main,(e.vars||e).palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${on.disabled}`]:{color:e.vars?e.vars.palette.Switch[`${t}DisabledColor`]:`${e.palette.mode==="light"?e.lighten(e.palette[t].main,.62):e.darken(e.palette[t].main,.55)}`}},[`&.${on.checked} + .${on.track}`]:{backgroundColor:(e.vars||e).palette[t].main}}}))]}))),sF=wt("span",{name:"MuiSwitch",slot:"Track"})(In(({theme:e})=>({height:"100%",width:"100%",borderRadius:14/2,zIndex:-1,transition:e.transitions.create(["opacity","background-color"],{duration:e.transitions.duration.shortest}),backgroundColor:e.vars?e.vars.palette.common.onBackground:`${e.palette.mode==="light"?e.palette.common.black:e.palette.common.white}`,opacity:e.vars?e.vars.opacity.switchTrack:`${e.palette.mode==="light"?.38:.3}`}))),cF=wt("span",{name:"MuiSwitch",slot:"Thumb"})(In(({theme:e})=>({boxShadow:(e.vars||e).shadows[1],backgroundColor:"currentColor",width:20,height:20,borderRadius:"50%"}))),mS=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiSwitch"}),{className:i,color:a="primary",edge:o=!1,size:u="medium",sx:l,slots:s={},slotProps:c={},...f}=r,d={...r,color:a,edge:o,size:u},h=oF(d),v={slots:s,slotProps:c},[m,D]=Fo("root",{className:at(h.root,i),elementType:uF,externalForwardedProps:v,ownerState:d,additionalProps:{sx:l}}),[p,g]=Fo("thumb",{className:h.thumb,elementType:cF,externalForwardedProps:v,ownerState:d}),y=B.jsx(p,{...g}),[S,w]=Fo("track",{className:h.track,elementType:sF,externalForwardedProps:v,ownerState:d});return B.jsxs(m,{...D,children:[B.jsx(lF,{type:"checkbox",icon:y,checkedIcon:y,ref:n,ownerState:d,...f,classes:{...h,root:h.switchBase},slots:{...s.switchBase&&{root:s.switchBase},...s.input&&{input:s.input}},slotProps:{...c.switchBase&&{root:typeof c.switchBase=="function"?c.switchBase(d):c.switchBase},input:{role:"switch"},...c.input&&{input:typeof c.input=="function"?c.input(d):c.input}}}),B.jsx(S,{...w})]})}),pS=M.createContext();function fF(e){return yn("MuiTable",e)}bn("MuiTable",["root","stickyHeader"]);const dF=e=>{const{classes:t,stickyHeader:n}=e;return Un({root:["root",n&&"stickyHeader"]},fF,t)},hF=wt("table",{name:"MuiTable",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.stickyHeader&&t.stickyHeader]}})(In(({theme:e})=>({display:"table",width:"100%",borderCollapse:"collapse",borderSpacing:0,"& caption":{...e.typography.body2,padding:e.spacing(2),color:(e.vars||e).palette.text.secondary,textAlign:"left",captionSide:"bottom"},variants:[{props:({ownerState:t})=>t.stickyHeader,style:{borderCollapse:"separate"}}]}))),gS="table",mF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTable"}),{className:i,component:a=gS,padding:o="normal",size:u="medium",stickyHeader:l=!1,...s}=r,c={...r,component:a,padding:o,size:u,stickyHeader:l},f=dF(c),d=M.useMemo(()=>({padding:o,size:u,stickyHeader:l}),[o,u,l]);return B.jsx(pS.Provider,{value:d,children:B.jsx(hF,{as:a,role:a===gS?null:"table",ref:n,className:at(f.root,i),ownerState:c,...s})})}),Df=M.createContext();function pF(e){return yn("MuiTableBody",e)}bn("MuiTableBody",["root"]);const gF=e=>{const{classes:t}=e;return Un({root:["root"]},pF,t)},vF=wt("tbody",{name:"MuiTableBody",slot:"Root"})({display:"table-row-group"}),yF={variant:"body"},vS="tbody",bF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableBody"}),{className:i,component:a=vS,...o}=r,u={...r,component:a},l=gF(u);return B.jsx(Df.Provider,{value:yF,children:B.jsx(vF,{className:at(l.root,i),as:a,ref:n,role:a===vS?null:"rowgroup",ownerState:u,...o})})});function DF(e){return yn("MuiTableCell",e)}const SF=bn("MuiTableCell",["root","head","body","footer","sizeSmall","sizeMedium","paddingCheckbox","paddingNone","alignLeft","alignCenter","alignRight","alignJustify","stickyHeader"]),xF=e=>{const{classes:t,variant:n,align:r,padding:i,size:a,stickyHeader:o}=e,u={root:["root",n,o&&"stickyHeader",r!=="inherit"&&`align${Ue(r)}`,i!=="normal"&&`padding${Ue(i)}`,`size${Ue(a)}`]};return Un(u,DF,t)},wF=wt("td",{name:"MuiTableCell",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,t[n.variant],t[`size${Ue(n.size)}`],n.padding!=="normal"&&t[`padding${Ue(n.padding)}`],n.align!=="inherit"&&t[`align${Ue(n.align)}`],n.stickyHeader&&t.stickyHeader]}})(In(({theme:e})=>({...e.typography.body2,display:"table-cell",verticalAlign:"inherit",borderBottom:e.vars?`1px solid ${e.vars.palette.TableCell.border}`:`1px solid
190
190
  ${e.palette.mode==="light"?e.lighten(e.alpha(e.palette.divider,1),.88):e.darken(e.alpha(e.palette.divider,1),.68)}`,textAlign:"left",padding:16,variants:[{props:{variant:"head"},style:{color:(e.vars||e).palette.text.primary,lineHeight:e.typography.pxToRem(24),fontWeight:e.typography.fontWeightMedium}},{props:{variant:"body"},style:{color:(e.vars||e).palette.text.primary}},{props:{variant:"footer"},style:{color:(e.vars||e).palette.text.secondary,lineHeight:e.typography.pxToRem(21),fontSize:e.typography.pxToRem(12)}},{props:{size:"small"},style:{padding:"6px 16px",[`&.${SF.paddingCheckbox}`]:{width:24,padding:"0 12px 0 16px","& > *":{padding:0}}}},{props:{padding:"checkbox"},style:{width:48,padding:"0 0 0 4px"}},{props:{padding:"none"},style:{padding:0}},{props:{align:"left"},style:{textAlign:"left"}},{props:{align:"center"},style:{textAlign:"center"}},{props:{align:"right"},style:{textAlign:"right",flexDirection:"row-reverse"}},{props:{align:"justify"},style:{textAlign:"justify"}},{props:({ownerState:t})=>t.stickyHeader,style:{position:"sticky",top:0,zIndex:2,backgroundColor:(e.vars||e).palette.background.default}}]}))),Sf=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableCell"}),{align:i="inherit",className:a,component:o,padding:u,scope:l,size:s,sortDirection:c,variant:f,...d}=r,h=M.useContext(pS),v=M.useContext(Df),m=v&&v.variant==="head";let D;o?D=o:D=m?"th":"td";let p=l;D==="td"?p=void 0:!p&&m&&(p="col");const g=f||v&&v.variant,y={...r,align:i,component:D,padding:u||(h&&h.padding?h.padding:"normal"),size:s||(h&&h.size?h.size:"medium"),sortDirection:c,stickyHeader:g==="head"&&h&&h.stickyHeader,variant:g},S=xF(y);let w=null;return c&&(w=c==="asc"?"ascending":"descending"),B.jsx(wF,{as:D,ref:n,className:at(S.root,a),"aria-sort":w,scope:p,ownerState:y,...d})});function EF(e){return yn("MuiTableHead",e)}bn("MuiTableHead",["root"]);const AF=e=>{const{classes:t}=e;return Un({root:["root"]},EF,t)},CF=wt("thead",{name:"MuiTableHead",slot:"Root"})({display:"table-header-group"}),TF={variant:"head"},yS="thead",MF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableHead"}),{className:i,component:a=yS,...o}=r,u={...r,component:a},l=AF(u);return B.jsx(Df.Provider,{value:TF,children:B.jsx(CF,{as:a,className:at(l.root,i),ref:n,role:a===yS?null:"rowgroup",ownerState:u,...o})})});function _F(e){return yn("MuiTableRow",e)}const bS=bn("MuiTableRow",["root","selected","hover","head","footer"]),BF=e=>{const{classes:t,selected:n,hover:r,head:i,footer:a}=e;return Un({root:["root",n&&"selected",r&&"hover",i&&"head",a&&"footer"]},_F,t)},FF=wt("tr",{name:"MuiTableRow",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.head&&t.head,n.footer&&t.footer]}})(In(({theme:e})=>({color:"inherit",display:"table-row",verticalAlign:"middle",outline:0,[`&.${bS.hover}:hover`]:{backgroundColor:(e.vars||e).palette.action.hover},[`&.${bS.selected}`]:{backgroundColor:e.alpha((e.vars||e).palette.primary.main,(e.vars||e).palette.action.selectedOpacity),"&:hover":{backgroundColor:e.alpha((e.vars||e).palette.primary.main,`${(e.vars||e).palette.action.selectedOpacity} + ${(e.vars||e).palette.action.hoverOpacity}`)}}}))),DS="tr",SS=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableRow"}),{className:i,component:a=DS,hover:o=!1,selected:u=!1,...l}=r,s=M.useContext(Df),c={...r,component:a,hover:o,selected:u,head:s&&s.variant==="head",footer:s&&s.variant==="footer"},f=BF(c);return B.jsx(FF,{as:a,ref:n,className:at(f.root,i),role:a===DS?null:"row",ownerState:c,...l})}),NF={paddingLeft:0,paddingRight:0,paddingTop:1,paddingBottom:1},fl=35,RF=e=>{const t=e.selected?"secondary":"inherit";return B.jsx("span",{title:e.title,children:e.icon?B.jsx(cl,{title:e.title,onClick:e.onClick,color:t,style:NF,disabled:!!e.disabled,sx:{fontSize:18},children:e.icon},e.elementIndex):B.jsx("button",{title:e.title,onClick:e.onClick,disabled:!!e.disabled,style:{padding:0,margin:0,fontSize:10},children:e.text},e.elementIndex)},e.elementIndex+"-span")},OF=e=>e.useHorizontalLayout?B.jsx(B.Fragment,{}):B.jsx("hr",{},e.elementIndex),zF=e=>{const t=Number.isFinite(e.content)?e.content:0,n=e.contentSigFigs||0,r=Math.abs(t-Math.round(t))*10**(n+1)<1,i=Number.isFinite(e.content)?r&&!e.contentAlwaysShowDecimal?Math.round(t)+"":t.toFixed(e.contentSigFigs||2):e.content||"",a=e.useHorizontalLayout?"span":"div";return Nt.createElement(a,{key:e.elementIndex,title:e.title,style:{textAlign:"left",fontWeight:"bold",cursor:"default",fontSize:10}},i)},UF=e=>{switch(e.subtype){case"checkbox":return B.jsx(IF,{...e});case"slider":return B.jsx($F,{...e});default:return B.jsxs("span",{children:["ERROR: Bad toggle subtype ",e.subtype]},e.elementIndex)}},IF=e=>B.jsx(hS,{checked:e.selected,onClick:e.onClick,style:{padding:0,paddingLeft:0},title:e.title,disabled:e.disabled},e.elementIndex),$F=e=>B.jsx(iF,{children:B.jsx(mS,{checked:e.selected,size:"small",style:{left:-3},onChange:e.onClick,disabled:e.disabled,title:e.title})},e.elementIndex),kF=e=>{switch(e.type){case"button":return B.jsx(RF,{...e});case"divider":return B.jsx(OF,{...e});case"text":return B.jsx(zF,{...e});case"toggle":return B.jsx(UF,{...e});default:return B.jsx("span",{},e.elementIndex)}},LF=e=>(e||[]).map((t,n)=>({type:t.type||"button",subtype:t.subtype,title:t.title,onClick:t.callback,icon:t.icon||"",text:t.text||"",selected:t.selected,disabled:t.disabled,content:t.content,contentSigFigs:t.contentSigFigs,contentAlwaysShowDecimal:t.boolean,elementIndex:n})),dl=e=>{const t=M.useMemo(()=>LF(e.customActions),[e.customActions]),n=M.useMemo(()=>t.map((a,o)=>B.jsx(kF,{...a,useHorizontalLayout:e.useHorizontalLayout},o)),[t,e.useHorizontalLayout]),r=M.useMemo(()=>({width:e.width,height:e.height,top:e.top??0,paddingTop:e.topPadding??0}),[e.width,e.height,e.top,e.topPadding]),i=e.useHorizontalLayout?"HorizontalToolbar":"VerticalToolbar";return B.jsx("div",{className:i,style:{...r},children:n})},xf={onlyShowSelected:!1},wf=({options:e,setOptions:t,onRedistributeUnitColors:n})=>B.jsxs("div",{children:[B.jsx(mS,{checked:e.onlyShowSelected,onClick:()=>{t({...e,onlyShowSelected:!e.onlyShowSelected})}}),B.jsx("span",{style:{position:"relative",top:2,overflow:"hidden"},children:"only show selected"}),"  ",n&&B.jsx("button",{onClick:n,title:"Redistribute unit colors",children:"rc"})]}),jF=(e,t)=>{const n=t-e;let r;n<=30?r=10:n<=120?r=20:n<=300?r=50:n<=600?r=100:n<=1e3?r=150:r=100;const i=[];let a=Math.ceil(e/r);for(;a*r<=t;)i.push(a*r),a++;return i},xS=({binEdgesSec:e,binCounts:t,color:n,width:r,height:i,hideXAxis:a})=>{const o=M.useMemo(()=>(t||[]).map((c,f)=>{const d=(e||[])[f]*1e3,h=(e||[])[f+1]*1e3;return{key:f,xStart:d,xEnd:h,height:c,tooltip:`[${d}, ${h}]: ${c}`,color:n}}),[t,e,n]),{xMin:u,xMax:l}=M.useMemo(()=>o.length>0?{xMin:o[0].xStart,xMax:o[o.length-1].xEnd}:{xMin:0,xMax:1},[o]),s=M.useMemo(()=>jF(u,l).map(f=>({x:f,label:`${f}`})),[u,l]);return t?B.jsx(h_,{bars:o,ticks:a?void 0:s,width:r,height:i,xLabel:a?void 0:"dt (msec)"}):B.jsx("div",{style:{position:"relative",width:r,height:i,color:"orange"}})},HF=10,PF=4,qF=2,Ro=Nt.forwardRef((e,t)=>{const{width:n,height:r,initialPosition:i,onChange:a,adjustable:o=!0,positionFromRight:u=!1,direction:l="horizontal"}=e,s=l==="horizontal"?n:r,[c,f]=M.useState(i),[d,h]=M.useState(!1),[v,m]=M.useState({x:0,y:0}),[D,p]=M.useState(0),g=M.useRef(null);if(M.useEffect(()=>{c>s-4?f(s-4):c<4&&s>20&&f(4)},[c,n,s]),!e.children)throw Error("Unexpected: no props.children");let y,S;if(!Array.isArray(e.children))y=e.children,S=null;else{const G=e.children.filter(X=>X!==void 0);y=G[0]||null,S=G[1]||null}if(y||(y=S,S=null),!y)throw Error("Splitter must have at least one child.");const w=u?s-c:c,b=o?e.gripThickness??HF:0,E=o?e.gripInnerThickness??PF:0,C=o?e.gripMargin??qF:0,A=w-b/2-C,T=s-A-b-2*C,_={top:0,left:0,width:n,height:r,overflow:"hidden"},x={left:0,top:0,width:l==="horizontal"?A:n,height:l==="horizontal"?r:A,zIndex:0,overflowY:l==="horizontal"?"auto":"hidden",overflowX:l==="horizontal"?"hidden":"auto"},F={left:l==="horizontal"?A+b+2*C:0,top:l==="horizontal"?0:A+b+2*C,width:l==="horizontal"?T:n,height:l==="horizontal"?r:T,zIndex:0,overflowY:l==="horizontal"?"auto":"hidden",overflowX:l==="horizontal"?"hidden":"auto"},R={left:0,top:0,width:l==="horizontal"?b+2*C:n,height:l==="horizontal"?r:b+2*C,backgroundColor:"transparent",cursor:l==="horizontal"?"col-resize":"row-resize",zIndex:9998},z={left:l==="horizontal"?C:0,top:l==="horizontal"?0:C,width:l==="horizontal"?b:n,height:l==="horizontal"?r:b,background:"rgb(230, 230, 230)",cursor:l==="horizontal"?"col-resize":"row-resize"},N={top:l==="horizontal"?0:(b-E)/2,left:l==="horizontal"?(b-E)/2:0,width:l==="horizontal"?E:n,height:l==="horizontal"?r:E,background:"gray",cursor:l==="horizontal"?"col-resize":"row-resize"},U=M.useCallback(G=>{G.preventDefault(),h(!0),m({x:G.clientX,y:G.clientY}),p(w)},[w]),I=M.useCallback(G=>{if(!d)return;const X=G.clientX-v.x,P=G.clientY-v.y;let H=D+(l==="horizontal"?X:P);const k=4,q=s-4;H=Math.max(k,Math.min(q,H));const Y=u?s-H:H;f(Y),a&&a(Y)},[d,v,D,l,s,u,a]),L=M.useCallback(()=>{h(!1)},[]);return M.useEffect(()=>{if(d)return document.addEventListener("mousemove",I),document.addEventListener("mouseup",L),()=>{document.removeEventListener("mousemove",I),document.removeEventListener("mouseup",L)}},[d,I,L]),S?B.jsxs("div",{className:"splitter",style:{..._,position:"relative"},children:[B.jsx("div",{style:{...x,position:"absolute"},className:"SplitterChild",children:B.jsx(y.type,{...y.props,width:l==="horizontal"?A:n,height:l==="horizontal"?r:A})},"child1"),o&&B.jsx("div",{ref:g,style:{...R,position:"absolute",left:l==="horizontal"?w-b/2-C:0,top:l==="horizontal"?0:w-b/2-C},onMouseDown:U,children:B.jsx("div",{style:{...z,position:"absolute"},children:B.jsx("div",{style:{...N,position:"absolute"}})})},"drag"),B.jsx("div",{style:{...F,position:"absolute"},className:"SplitterChild",children:B.jsx(S.type,{ref:t,...S.props,width:l==="horizontal"?T:n,height:l==="horizontal"?r:T})},"child2")]}):B.jsx(y.type,{...y.props,width:n,height:r})}),VF=({data:e,width:t,height:n})=>{const[r,i]=M.useState(xf),{selectedUnitIds:a,orderedUnitIds:o,plotClickHandlerGenerator:u,unitIdSelectionDispatch:l}=qr(),[s,c]=M.useState(1),[f,d]=M.useState(!1);M.useEffect(()=>{l({type:oo,newUnitOrder:yr(e.autocorrelograms.map(g=>g.unitId))})},[e.autocorrelograms,l]);const h=M.useMemo(()=>e.autocorrelograms.filter(g=>r.onlyShowSelected?a.has(g.unitId):!0).map(g=>({unitId:g.unitId,key:g.unitId,label:`Unit ${g.unitId}`,labelColor:wr(Ct(g.unitId)),clickHandler:r.onlyShowSelected?void 0:u(g.unitId),props:{binEdgesSec:g.binEdgesSec,binCounts:g.binCounts,color:wr(Ct(g.unitId)),width:120*s,height:120*s,hideXAxis:!f}})),[e.autocorrelograms,u,r.onlyShowSelected,a,f,s]),v=M.useMemo(()=>o&&o.length>0?o.map(g=>h.filter(y=>y.unitId===g)[0]).filter(g=>g!==void 0):h,[h,o]),m=M.useMemo(()=>{const g=[{type:"button",callback:()=>c(S=>S*1.3),title:"Increase box size",icon:B.jsx(Tc,{})},{type:"button",callback:()=>c(S=>S/1.3),title:"Decrease box size",icon:B.jsx(Cc,{})}],y={type:"toggle",subtype:"checkbox",callback:()=>d(S=>!S),title:"Show X Axis",selected:f===!0};return[...g,{type:"divider"},y]},[f]),D=30,p=fl;return B.jsxs("div",{children:[B.jsxs(Ro,{width:t,height:n-D,initialPosition:p,adjustable:!1,children:[B.jsx(dl,{width:p,height:n,customActions:m}),B.jsx(wc,{width:0,height:0,children:B.jsx(xc,{plots:v,plotComponent:xS,selectedPlotKeys:r.onlyShowSelected?void 0:a})})]}),B.jsx("div",{style:{position:"absolute",top:n-D,height:D,overflow:"hidden"},children:B.jsx(wf,{options:r,setOptions:i})})]})},Ef=e=>{const[t,n]=M.useState(e?.stateRef.current),r=e?.stateRef,i=e?.onChange;return M.useEffect(()=>{n(r?.current);const a=i?.(o=>{n(o)});return()=>{a&&a()}},[i,r]),t===void 0?{state:void 0,dispatch:void 0}:{state:t,dispatch:e?.dispatch}},GF=(e,t,n)=>{const{state:r,dispatch:i}=Ef(e?.figureAnnotations);M.useEffect(()=>{i&&n&&i({type:"reportViewWithAnnotations"})},[i,n]);const a=M.useMemo(()=>r?.annotations[t],[r,t]),o=M.useMemo(()=>r?.editingAnnotations?(u,l)=>{i&&i({type:"setAnnotation",path:t,key:u,value:l})}:void 0,[i,t,r?.editingAnnotations]);return{annotations:a,setAnnotation:o}},YF=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null);return M.useEffect(()=>{let o=!1;return(async()=>{const l=[],s=e.attrs.num_autocorrelograms||0;if(s===0){o||a({type:"Autocorrelograms",autocorrelograms:[]});return}const c=await e.getDatasetData("bin_edges_sec",{}),f=await e.getDatasetData("bin_counts",{});if(!c||!f){console.error("Failed to load autocorrelograms data");return}const d=Array.from(c),h=new Int32Array(f),v=d.length-1,m=e.attrs.autocorrelograms;for(let D=0;D<s;D++){const p=m[D],g=D*v,y=Array.from(h.slice(g,g+v));l.push({unitId:p.unit_id,binEdgesSec:d,binCounts:y})}o||a({type:"Autocorrelograms",autocorrelograms:l})})(),()=>{o=!0}},[e]),i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx(VF,{data:i,width:n,height:r})}):B.jsx("div",{children:"Loading..."})},Jr=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?B.jsx(B.Fragment,{children:"Waiting for context..."}):B.jsx(xy.Provider,{value:{unitSelection:n,unitSelectionDispatch:r},children:t})},XF=e=>{const{unitId:t,mergeGroup:n}=e,r=wr(Ct(t)),i=n?n.map(a=>`${a}`).join(", "):"";return B.jsxs("span",{children:[B.jsx("div",{className:"unitLabel",style:{backgroundColor:r}})," ",`${t}`,n&&n.length>0&&B.jsx("span",{children:` (${i})`},"mergeGroup")]})},ZF=(e,t)=>((t||{}).mergeGroups||[]).filter(r=>r.includes(e))[0]||null,QF=e=>{const{selectedUnitIds:t,currentUnitId:n,selectionDispatch:r,rows:i,columns:a,orderedUnitIds:o,visibleUnitIds:u,primarySortRule:l,height:s,selectionDisabled:c,hideSelectionColumn:f}=e,[d,h]=M.useState(l),v=M.useMemo(()=>u&&u.length>0?u:o,[u,o]),m=M.useMemo(()=>my({selectedUnitIds:t,orderedUnitIds:o,visibleUnitIds:v}),[t,o,v]),D=M.useCallback((S,w)=>{const b=d?.columnName===S?!d?.sortAscending:!0;h({columnName:S,sortAscending:b}),r&&r({type:"UPDATE_SORT_FIELDS",newSortField:S,ascending:b})},[d,r]),p=M.useCallback(()=>{r&&r(m==="all"?{type:"DESELECT_ALL"}:{type:"TOGGLE_SELECT_ALL"})},[m,r]),g=M.useMemo(()=>{const S=v.map(b=>i.get(b)).filter(b=>b!==void 0);if(!d)return S;const w=a.find(b=>b.columnName===d.columnName);return w?[...S].sort((b,E)=>{const C=b.data[d.columnName]?.sortValue,A=E.data[d.columnName]?.sortValue,T=w.sort(C,A);return d.sortAscending?T:-T}):S},[v,i,d,a]),y=S=>d?.columnName!==S?"":d.sortAscending?"↑":"↓";return B.jsx("div",{className:"compact-table-container",style:{height:s?`${s}px`:"100%",overflow:"auto"},children:B.jsxs("table",{className:"compact-table",children:[B.jsx("thead",{children:B.jsxs("tr",{children:[!f&&B.jsx("th",{className:"compact-table-header",children:B.jsx("input",{type:"checkbox",checked:m==="all",ref:S=>{S&&(S.indeterminate=m==="partial")},onChange:p,disabled:c})}),a.map(S=>B.jsxs("th",{className:"compact-table-header",onClick:()=>D(S.columnName,S),title:S.tooltip,style:{cursor:"pointer"},children:[S.label,B.jsx("span",{className:"sort-indicator",children:y(S.columnName)})]},S.columnName))]})}),B.jsx("tbody",{children:g.map(S=>B.jsxs("tr",{className:`compact-table-row ${t.has(S.rowId)?"selected":""} ${n===S.rowId?"current":""}`,children:[!f&&B.jsx("td",{className:"compact-table-cell",children:B.jsx("input",{type:"checkbox",checked:t.has(S.rowId),onChange:w=>{S.checkboxFn&&S.checkboxFn(w)},disabled:c})}),a.map(w=>B.jsx("td",{className:"compact-table-cell",children:w.dataElement(S.data[w.columnName]?.value)},w.columnName))]},S.rowId))})]})})},KF={},Af=(e,t)=>{if(t.type!=="REOPEN_CURATION"&&e.isClosed&&console.log(`WARNING: Applying curation action to a closed sorting curation:
191
- Action: ${t.type}`),t.type==="SET_CURATION")return t.curation;if(t.type==="CLOSE_CURATION")return{...e,isClosed:!0};if(t.type==="REOPEN_CURATION")return{...e,isClosed:!1};if(t.type==="ADD_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId],r={...e.labelsByUnit||{}};let i=!1;for(const a of n){const o=r[a+""]||[];o.includes(t.label)||(i=!0,r[a+""]=[...o,t.label].sort())}return i?{...e,labelsByUnit:r}:e}else if(t.type==="TOGGLE_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId];let r=!0;for(const i of n)((e.labelsByUnit||{})[i+""]||[]).includes(t.label)||(r=!1);return r?Af(e,{type:"REMOVE_UNIT_LABEL",unitId:t.unitId,label:t.label}):Af(e,{type:"ADD_UNIT_LABEL",unitId:t.unitId,label:t.label})}else if(t.type==="REMOVE_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId],r={...e.labelsByUnit||{}};let i=!1;for(const a of n){const o=r[a+""]||[];o.includes(t.label)&&(i=!0,r[a+""]=o.filter(u=>u!==t.label))}return i?{...e,labelsByUnit:r}:e}else{if(t.type==="MERGE_UNITS")return{...e,mergeGroups:AS([...e.mergeGroups||[],t.unitIds])};if(t.type==="UNMERGE_UNITS")return{...e,mergeGroups:AS((e.mergeGroups||[]).map(n=>n.filter(r=>!t.unitIds.includes(r))))};if(t.type==="SET_LABEL_CHOICES")return{...e,labelChoices:t.labelChoices}}return e},WF={sortingCuration:KF,sortingCurationDispatch:e=>{console.warn("No sortingCurationDispatch function provided.")},curating:!1},wS=Nt.createContext(WF),ES=()=>{const e=M.useContext(wS);if(!e)throw Error("useSortingCuration must be used within a SortingCurationContext.Provider");return e},JF=(e,t)=>e.filter(n=>t.includes(n)),eN=(e,t)=>[...e,...t.filter(n=>!e.includes(n))].sort(),AS=e=>{const t=e.map(r=>[...r]);let n=!0;for(;n;){n=!1;for(let r=0;r<t.length;r++){const i=t[r];for(let a=r+1;a<t.length;a++){const o=t[a];JF(i,o).length>0&&(t[r]=eN(i,o),t[a]=[],n=!0)}}}return t.filter(r=>r.length>=2)},CS=({data:e,width:t,height:n})=>{const[r,i]=M.useState({...xf,onlyShowSelected:!1}),{selectedUnitIds:a,currentUnitId:o,orderedUnitIds:u,visibleUnitIds:l,primarySortRule:s,checkboxClickHandlerGenerator:c,unitIdSelectionDispatch:f}=qr(),{sortingCuration:d}=ES(),h=M.useMemo(()=>r.onlyShowSelected?l?l.filter(w=>a.has(w)):[...a]:l,[l,a,r.onlyShowSelected]),v=M.useMemo(()=>{const w=[];return w.push({columnName:"_unitId",label:"Unit",tooltip:"Unit ID",sort:(b,E)=>Ct(b)-Ct(E),dataElement:b=>B.jsx(XF,{unitId:b.unitId,mergeGroup:b.mergeGroup}),calculating:!1}),d&&w.push({columnName:"_labels",label:"Labels",tooltip:"Curation labels",sort:(b,E)=>b<E?-1:b>E?1:0,dataElement:b=>B.jsx("span",{children:b.join(", ")}),calculating:!1}),e.similarityScores&&w.push({columnName:"_similarity",label:"Similarity",tooltip:"Similarity with current unit",sort:(b,E)=>{if(b.unitId===o)return 1;if(E.unitId===o)return-1;const C=b.score,A=E.score;return C===void 0&&A!==void 0?-1:C!==void 0&&A===void 0?1:C===void 0&&A===void 0?0:C!==void 0&&A!==void 0?C<A?-1:C>A?1:0:0},dataElement:b=>B.jsx("span",{children:b}),calculating:!1,onlyAllowDescendingSort:!0}),e.columns.filter(b=>b.key!=="unitId").forEach(b=>{w.push({columnName:b.key,label:b.label,tooltip:b.label,sort:b.dtype==="str"?(E,C)=>E<C?-1:E>C?1:0:b.dtype==="int"?(E,C)=>E-C:b.dtype=="bool"?(E,C)=>(E?1:0)-(C?1:0):b.dtype==="float"?(E,C)=>E-C:(E,C)=>E-C,dataElement:E=>B.jsx("span",{children:E}),calculating:!1})}),w},[e.columns,o,d,e.similarityScores]),m=M.useMemo(()=>{for(let b=0;b<0;b++)u.push("never-added");const w={};if(e.similarityScores&&o!==void 0)for(const b of e.similarityScores)b.unitId1===o?w[b.unitId2]=b.similarity:b.unitId2===o&&(w[b.unitId1]=b.similarity);return e.rows.map(b=>{const E=(d?.labelsByUnit||{})[`${b.unitId}`]||[],C={value:{unitId:b.unitId,mergeGroup:ZF(b.unitId,d)},sortValue:b.unitId},A=w[b.unitId],T={_unitId:C,_labels:{value:E,sortValue:E.join(", ")},_similarity:{value:A!==void 0?A.toFixed(3):void 0,sortValue:{unitId:b.unitId,score:A}}};for(const _ of e.columns){const x=`${b.values[_.key]!==void 0?b.values[_.key]:""}`;T[_.key]={value:x,sortValue:b.values[_.key]}}return{rowId:b.unitId,data:T,checkboxFn:c(b.unitId)}})},[e.rows,e.columns,o,e.similarityScores,d,c,u]);M.useEffect(()=>{f({type:oo,newUnitOrder:yr(m.map(w=>w.rowId))})},[m,f]);const D=M.useMemo(()=>{const w=new Map;return m.forEach(b=>w.set(b.rowId,b)),w},[m]),p=30,g=M.useMemo(()=>({width:t-20,height:n-p,top:0,position:"relative",overflowY:"auto"}),[t,n]),y=M.useCallback(w=>{if(w.ctrlKey)return w.key==="ArrowDown"?f({type:vy}):w.key==="ArrowUp"?f({type:yy}):w.key==="Home"?f({type:by}):w.key==="End"&&f({type:Dy}),!1},[f]),S=M.useCallback(()=>{f({type:"REDISTRIBUTE_UNIT_COLORS"})},[f]);return B.jsxs("div",{children:[B.jsx("div",{style:g,onKeyDown:y,children:B.jsx(QF,{columns:v,rows:D,orderedUnitIds:u,visibleUnitIds:h,selectedUnitIds:a,currentUnitId:o,selectionDispatch:f,primarySortRule:s})}),B.jsx("div",{style:{position:"absolute",top:n-p,height:p,overflow:"hidden"},children:B.jsx(wf,{options:r,setOptions:i,onRedistributeUnitColors:S})})]})},tN=({defaultLabelOptions:e,width:t,height:n})=>{const{selectedUnitIdsArray:r}=qr(),{sortingCuration:i,sortingCurationDispatch:a,curating:o}=ES(),{labelChoices:u=[],labelsByUnit:l={},mergeGroups:s=[],isClosed:c=!1}=i,[f,d]=M.useState(""),[h,v]=M.useState(!1),m=M.useMemo(()=>u.length===0&&e.length>0&&o?(a({type:"SET_LABEL_CHOICES",labelChoices:e}),e):u,[u,e,a,o]);M.useEffect(()=>{},[m]);const D=M.useCallback(j=>{if(r.length===0)return"none";const H=r.filter(k=>(l[k.toString()]||[]).includes(j));return H.length===0?"none":H.length===r.length?"full":"partial"},[r,l]),p=M.useCallback(j=>{o&&(r.length===0||c||a({type:"TOGGLE_UNIT_LABEL",unitId:r,label:j}))},[r,c,a,o]),g=M.useCallback(()=>{if(!o)return;const j=f.trim();j&&!m.includes(j)&&(a({type:"SET_LABEL_CHOICES",labelChoices:[...m,j]}),d(""))},[f,m,a,o]),y=M.useCallback(j=>Object.values(l).some(H=>H.includes(j)),[l]),S=M.useCallback(j=>{o&&(y(j)||a({type:"SET_LABEL_CHOICES",labelChoices:m.filter(H=>H!==j)}))},[m,a,y,o]),w=M.useCallback(j=>s.find(H=>H.includes(j)),[s]),b=M.useMemo(()=>{if(r.length===0)return{canMerge:!1,canUnmerge:!1,groupsInvolved:[],unmergedUnits:[]};const j=new Set,H=[];r.forEach(Y=>{const ee=w(Y);ee?j.add(ee):H.push(Y)});const k=r.length>=2,q=j.size>0;return{canMerge:k,canUnmerge:q,groupsInvolved:Array.from(j),unmergedUnits:H}},[r,w]),E=M.useCallback(()=>{o&&(r.length<2||c||a({type:"MERGE_UNITS",unitIds:r}))},[r,c,a,o]),C=M.useCallback(()=>{o&&(r.length===0||c||a({type:"UNMERGE_UNITS",unitIds:r}))},[r,c,a,o]),A=M.useCallback(()=>{o&&a(c?{type:"REOPEN_CURATION"}:{type:"CLOSE_CURATION"})},[c,a,o]),T=M.useMemo(()=>r.length===0?"No units selected":r.length<=5?`Units: ${r.join(", ")}`:`${r.length} units selected`,[r]),_={width:t,height:n,padding:"8px",fontSize:"12px",fontFamily:"Arial, sans-serif",border:"1px solid #ddd",borderRadius:"4px",backgroundColor:"#fafafa",overflow:"auto",display:"flex",flexDirection:"column",gap:"8px"},x={marginBottom:"6px"},F={fontWeight:"bold",marginBottom:"4px",fontSize:"11px",color:"#333"},R={display:"inline-flex",alignItems:"center",padding:"2px 6px",margin:"2px",backgroundColor:"#e0e0e0",borderRadius:"12px",fontSize:"10px",border:"1px solid #ccc"},z={marginLeft:"4px",cursor:"pointer",color:"#666",fontWeight:"bold"},N={padding:"2px 4px",fontSize:"10px",border:"1px solid #ccc",borderRadius:"2px",marginRight:"4px",flex:1},U={padding:"2px 6px",fontSize:"10px",border:"1px solid #ccc",borderRadius:"2px",backgroundColor:"#f0f0f0",cursor:"pointer"},I={display:"inline-flex",alignItems:"center",margin:"2px 8px 2px 0",cursor:r.length>0&&!c?"pointer":"default",opacity:r.length>0&&!c?1:.5},L={...x,textAlign:"center"},G={...U,backgroundColor:c?"#f8d7da":"#d4edda",borderColor:c?"#f5c6cb":"#c3e6cb",color:c?"#721c24":"#155724"},X={display:"flex",alignItems:"center",cursor:"pointer",fontSize:"11px",fontWeight:"bold",color:"#333",marginBottom:"4px"},P={marginRight:"4px",fontSize:"10px",transform:h?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.2s"};return B.jsxs("div",{style:_,children:[B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Selected Units"}),B.jsx("div",{style:{fontSize:"10px",color:"#666"},children:T})]}),B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Label Assignment"}),m.map(j=>{const H=D(j);return B.jsxs("div",{style:I,onClick:o?()=>p(j):void 0,children:[B.jsx("input",{type:"checkbox",checked:H==="full",ref:k=>{k&&(k.indeterminate=H==="partial")},onChange:()=>{},style:{marginRight:"4px"},disabled:r.length===0||c}),B.jsx("span",{style:{fontSize:"10px"},children:j})]},j)}),r.length===0&&B.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic"},children:"Select units to assign labels"})]}),B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Unit Merging"}),r.length>0&&b.groupsInvolved.length>0&&B.jsxs("div",{style:{marginBottom:"6px"},children:[B.jsx("div",{style:{fontSize:"10px",color:"#666",marginBottom:"2px"},children:"Merge groups involving selected units:"}),b.groupsInvolved.map((j,H)=>{const k={...R,backgroundColor:"#e3f2fd",borderColor:"#90caf9",color:"#1565c0"};return B.jsx("span",{style:k,children:j.join(", ")},H)})]}),B.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center",flexWrap:"wrap"},children:[B.jsx("button",{onClick:o?E:void 0,style:{...U,backgroundColor:b.canMerge&&!c?"#d4edda":"#f8f9fa",borderColor:b.canMerge&&!c?"#c3e6cb":"#dee2e6",color:b.canMerge&&!c?"#155724":"#6c757d",cursor:b.canMerge&&!c?"pointer":"default"},disabled:!b.canMerge||c,title:c?"Cannot merge when curation is closed":r.length<2?"Select 2 or more units to merge":"Merge selected units",children:"Merge Selected"}),B.jsx("button",{onClick:o?C:void 0,style:{...U,backgroundColor:b.canUnmerge&&!c?"#fff3cd":"#f8f9fa",borderColor:b.canUnmerge&&!c?"#ffeaa7":"#dee2e6",color:b.canUnmerge&&!c?"#856404":"#6c757d",cursor:b.canUnmerge&&!c?"pointer":"default"},disabled:!b.canUnmerge||c,title:c?"Cannot unmerge when curation is closed":b.canUnmerge?"Unmerge selected units":"Select units that are part of merge groups to unmerge",children:"Unmerge Selected"})]}),r.length>0&&B.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"4px"},children:[b.groupsInvolved.length>0&&B.jsxs("div",{children:["Selected units in"," ",b.groupsInvolved.length," merge group(s)"]}),b.unmergedUnits.length>0&&B.jsxs("div",{children:[b.unmergedUnits.length," unmerged unit(s) selected"]})]}),r.length===0&&B.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic",marginTop:"4px"},children:"Select units to merge or unmerge"})]}),B.jsxs("div",{style:x,children:[B.jsxs("div",{style:X,onClick:()=>v(!h),children:[B.jsx("span",{style:P,children:"▶"}),"Manage Label Choices"]}),h&&B.jsxs("div",{children:[B.jsx("div",{style:{marginBottom:"4px"},children:m.map(j=>{const H=y(j);return B.jsxs("span",{style:R,children:[j,!c&&!H&&B.jsx("span",{style:z,onClick:o?()=>S(j):void 0,title:"Remove label choice",children:"×"})]},j)})}),!c&&B.jsxs("div",{style:{display:"flex",alignItems:"center"},children:[B.jsx("input",{type:"text",value:f,onChange:j=>d(j.target.value),onKeyPress:j=>j.key==="Enter"&&o&&g(),placeholder:"Add label...",style:N}),B.jsx("button",{onClick:o?g:void 0,style:U,disabled:!f.trim(),children:"Add"})]})]})]}),B.jsxs("div",{style:L,children:[B.jsx("button",{onClick:o?A:void 0,style:G,children:c?"Reopen Curation":"Finalize Curation"}),B.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"2px"},children:["Status: ",c?"Closed":"Open"]})]})]})},nN=({zarrGroup:e,contexts:t,width:n,height:r})=>B.jsx(Jr,{context:t.unitSelection,children:B.jsx(TS,{contexts:t,editable:!0,children:B.jsx(rN,{zarrGroup:e,contexts:t,width:n,height:r})})}),rN=({zarrGroup:e,width:t,height:n})=>{const r=e.attrs.default_label_options||[];return B.jsx(tN,{defaultLabelOptions:r,width:t,height:n})},TS=({contexts:e,children:t,editable:n})=>{const{annotations:r,setAnnotation:i}=GF(e,"/",n),a=M.useMemo(()=>{try{return JSON.parse(r?.sorting_curation||"{}")}catch(u){return console.error("Error parsing sorting_curation:",u),{}}},[r]),o=M.useMemo(()=>u=>{if(!i)return;const l=Af(a,u);i("sorting_curation",JSON.stringify(l))},[i,a]);return B.jsx(wS.Provider,{value:{sortingCuration:a,sortingCurationDispatch:o,curating:!!i},children:t})},iN=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.columns||[],h=await e.getDatasetData("rows_data",{});if(!h||h.length===0)throw new Error("Empty rows data");const v=new Uint8Array(h),m=new TextDecoder("utf-8").decode(v),D=JSON.parse(m);let p;try{const g=await e.getDatasetData("similarity_scores_data",{});if(g&&g.length>0){const y=new Uint8Array(g),S=new TextDecoder("utf-8").decode(y);p=JSON.parse(S)}}catch(g){console.warn("No similarity scores data found: "+g)}if(c)return;a({type:"UnitsTable",columns:d,rows:D,similarityScores:p})}catch(d){console.error("Error loading units table data:",d),u(`Failed to load units table data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading units table data..."}):i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx(TS,{contexts:t,editable:!1,children:B.jsx(CS,{data:i,width:n,height:r})})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No units table data available"})},aN=e=>{const{ampScaleFactor:t,setAmpScaleFactor:n}=e,r=()=>{n(t*1.2)},i=()=>{n(t/1.2)},a=()=>{n(1)};return[{type:"button",callback:r,title:"Scale amplitude up [shift + mouse-wheel]",icon:B.jsx(M_,{}),keyCode:38},{type:"button",callback:a,title:"Reset scale amplitude",icon:B.jsx(XD,{})},{type:"button",callback:i,title:"Scale amplitude down [shift + mouse-wheel]",icon:B.jsx(A_,{}),keyCode:40}]},MS={forward:[[1,0,0],[0,1,0]],inverse:[[1,0,0],[0,1,0]]},ha=(e,t)=>({x:t.x*e.forward[0][0]+t.y*e.forward[0][1]+e.forward[0][2],y:t.x*e.forward[1][0]+t.y*e.forward[1][1]+e.forward[1][2]}),$m=(e,t)=>({x:t.x*e.inverse[0][0]+t.y*e.inverse[0][1]+e.inverse[0][2],y:t.x*e.inverse[1][0]+t.y*e.inverse[1][1]+e.inverse[1][2]}),oN=(e,t)=>({forward:_S(e.forward,t.forward),inverse:_S(t.inverse,e.inverse)}),uN=e=>({forward:[...e.map(t=>[...t])],inverse:sN(e)}),lN=e=>({forward:e.inverse,inverse:e.forward}),km=e=>e.forward[0][0]*e.forward[1][1]-e.forward[0][1]*e.forward[1][0],_S=(e,t)=>[[e[0][0]*t[0][0]+e[0][1]*t[1][0],e[0][0]*t[0][1]+e[0][1]*t[1][1],e[0][0]*t[0][2]+e[0][1]*t[1][2]+e[0][2]],[e[1][0]*t[0][0]+e[1][1]*t[1][0],e[1][0]*t[0][1]+e[1][1]*t[1][1],e[1][0]*t[0][2]+e[1][1]*t[1][2]+e[1][2]]],sN=e=>{const t=[[e[0][0],e[0][1]],[e[1][0],e[1][1]]],n=[e[0][2],e[1][2]],r=t[0][0]*t[1][1]-t[0][1]*t[1][0],i=[[t[1][1]/r,-t[0][1]/r],[-t[1][0]/r,t[0][0]/r]],a=[i[0][0]*n[0]+i[0][1]*n[1],i[1][0]*n[0]+i[1][1]*n[1]];return[[i[0][0],i[0][1],-a[0]],[i[1][0],i[1][1],-a[1]]]},Lm=(e,t,n={})=>{const r=n.shift!==void 0?n.shift:!0,i=n.shift!==void 0?n.alt:!1,[a,o]=M.useState(MS),u=M.useCallback(l=>{if(r&&!l.shiftKey||!r&&l.shiftKey||i&&!l.altKey||!i&&l.altKey)return;const s=l.currentTarget.getBoundingClientRect(),c={x:l.clientX-s.x,y:l.clientY-s.y},f=l.deltaY,d=1.3;let h=uN([[d,0,(1-d)*c.x],[0,d,(1-d)*c.y]]);f>0&&(h=lN(h));let v=oN(h,a);const m=ha(v,{x:0,y:0}),D=ha(v,{x:e,y:t});return 0<=m.x&&m.x<e&&0<=m.y&&m.y<t&&0<=D.x&&D.x<e&&0<=D.y&&D.y<t&&(v=MS),o(v),!1},[a,t,e,r,i]);return{affineTransform:a,handleWheel:u}},hl={border:"rgb(30, 30, 30)",base:"rgb(0, 0, 255)",selected:"rgb(50, 200, 50)",hover:"rgb(128, 128, 255)",selectedHover:"rgb(200, 200, 196)",dragged:"rgb(0, 0, 196)",draggedSelected:"rgb(180, 180, 150)",dragRect:"rgba(196, 196, 196, 0.5)",textLight:"rgb(228, 228, 228)",textDark:"rgb(32, 32, 32)"},cN=2*Math.PI,fN=(e,t)=>{const{layoutMode:n,affineTransform:r}=t;if(e.save(),r){const i=r.forward;e.transform(i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2])}n==="geom"?hN(e,t):dN(e,t),e.restore()},dN=(e,t)=>{const{pixelElectrodes:n,pixelRadius:r,showLabels:i,xMargin:a}=t,o=r>5&&i,u=t.colors??hl,l=o?2*r:0;e.clearRect(0,0,e.canvas.width,e.canvas.height);const s=a+l,c=e.canvas.width-a;if(e.beginPath(),n.forEach(f=>{e.moveTo(s,f.pixelY),e.lineTo(c,f.pixelY)}),e.strokeStyle=u.border,e.stroke(),o){const f=s-.5*r;e.font=`${r-3}px Arial`,e.fillStyle=u.textDark,e.textAlign="right",e.textBaseline="middle",n.forEach(d=>{e.fillText(`${d.e.label}`,f,d.pixelY)})}},hN=(e,t)=>{const{pixelElectrodes:n,selectedElectrodeIds:r,hoveredElectrodeId:i,draggedElectrodeIds:a,pixelRadius:o,showLabels:u,offsetLabels:l}=t,s=o>5&&u,c=t.colors??hl,f=n.map(d=>{const h=r.includes(d.e.id),v=(i??-1)===d.e.id,m=a.includes(d.e.id),D=h?m?c.draggedSelected:v?c.selectedHover:c.selected:m?c.dragged:v?c.hover:c.base;return{...d,color:D,textColor:h||v&&!m?c.textDark:c.textLight}});if(e.clearRect(0,0,e.canvas.width,e.canvas.height),f.forEach(d=>{e.fillStyle=d.color,e.beginPath(),e.ellipse(d.pixelX,d.pixelY,o,o,0,0,cN),e.fill()}),s){e.font=`${o}px Arial`,e.textAlign=l?"right":"center",e.textBaseline="middle";const d=l?1.4*o:0;f.forEach(h=>{e.fillStyle=l?c.textDark:h.textColor,e.fillText(`${h.e.label}`,h.pixelX-d,h.pixelY)})}},Cf=e=>e.reduce((t,n)=>t<=n?t:n,1/0),Tf=e=>e.reduce((t,n)=>t>=n?t:n,-1/0),Oo=10,ml=10,mN=(e,t)=>{const n=t||{};return t&&(Object.keys(n).length!==e.length||e.some(i=>!n[`${i}`]))?(console.warn("Attempt to compute electrode locations with mismatched lists. Skipping..."),[]):e.map(i=>{const a=n[`${i}`]||[i,0];return{id:i,label:`${i}`,x:a[0],y:a[1]}})},BS=new Map,FS=e=>{const t=JSON.stringify(e),n=BS.get(t);if(n!==void 0)return n;let r=Number.MAX_VALUE;e.forEach(a=>{e.forEach(o=>{const u=OD([a.x-o.x,a.y-o.y]);u!==0&&(r=Math.min(r,u))})});const i=.45*r;return BS.set(t,i),i},NS=(e,t)=>({xmin:Cf(e.map(n=>n.x))-t,xmax:Tf(e.map(n=>n.x))+t,ymin:Cf(e.map(n=>n.y))-t,ymax:Tf(e.map(n=>n.y))+t}),pN=e=>{const t=FS(e),n=NS(e,t),r=Sc(n),i=zD(n),a={x:r/2+n.xmin,y:i/2+n.ymin};return{boxAspect:r/i,boxCenter:a}},gN=e=>{const t={xmin:Cf(e.map(n=>n.x)),xmax:Tf(e.map(n=>n.x)),ymin:Cf(e.map(n=>n.y)),ymax:Tf(e.map(n=>n.y))};return t.xmin===t.xmax&&t.ymin===t.ymax?e.map((n,r)=>({...n,x:r,y:0})):e},vN=(e,t)=>s_(n=>{const r=Oo+n[0]*(e-2*Oo),i=ml+n[1]*(t-2*ml);return[r,i]}),yN=(e,t)=>{const n=e.map((a,o)=>({e:a,ind:o})).sort((a,o)=>-a.e.y+o.e.y).map(a=>a.ind),r=[];for(let a=0;a<e.length;a++)r.push([0,0]);for(let a=0;a<n.length;a++){const o=n[a];r[o]=[.5,(.5+a)/(1+e.length)]}const i=Zh(t,r);return e.map((a,o)=>{const[u,l]=i[o];return{e:a,pixelX:u,pixelY:l}})},bN=(e,t,n,r,i)=>{const a=e-Oo*2,o=t-ml*2,u=Sc(i),l=zD(i);return L5(a/u,o/l,r/n)},DN=(e,t,n,r)=>{const i=Sc(r),a=(e-i*n)/2,o=[n,0,a-r.xmin*n],u=[0,-n,(t+n*(r.ymin+r.ymax))/2];return[o,u,[0,0,1]]},SN=(e,t,n,r={})=>{const i=(e-Oo*2)/(t-ml*2),a=gN(n),{boxAspect:o}=pN(a);return r.disableAutoRotate||o===1||i===1||o>1==i>1?{electrodes:n,rotated:!1}:{electrodes:n.map(u=>({...u,x:u.y,y:-u.x})),rotated:!0}},xN=(e,t)=>{const n=e.map(i=>[i.x,i.y]),r=Zh(t,n);return e.map((i,a)=>{const[o,u]=r[a];return{e:i,pixelX:o,pixelY:u}})},RS=(e,t,n)=>{for(const r of e)if(OD([r.pixelX-n[0],r.pixelY-n[1]])<t)return r.e.id},OS=(e,t,n)=>{const r=t.xmin-n,i=t.xmax+n,a=t.ymin-n,o=t.ymax+n;return e.filter(u=>u.pixelX>r&&u.pixelX<i&&u.pixelY>a&&u.pixelY<o).map(u=>u.e.id)},jm=(e,t,n,r="geom",i=IS,a)=>{if(r==="vertical"){const m=vN(e,t),D=yN(n,m),p=(t-2*ml)/(1+n.length);return{transform:m,convertedElectrodes:D,pixelRadius:p}}const{electrodes:o,rotated:u}=SN(e,t,n,{disableAutoRotate:a.disableAutoRotate}),l=FS(o),s=NS(o,l),c=bN(e,t,l,i,s),f=l*c;let d=DN(e,t,c,s);const h=(e-Sc(s)*c)/2,v=xN(o,d);return u&&(d=[[-d[0][1],d[0][0],d[0][2]],[-d[1][1],d[1][0],d[1][2]],[-d[2][1],d[2][0],d[2][2]]]),{transform:d,convertedElectrodes:v,pixelRadius:f,xMargin:h}},zS={isActive:!1},wN=(e,t)=>{if(t.type==="INITIALIZE"){const{width:n,height:r,electrodes:i,layoutMode:a,maxElectrodePixelRadius:o}=t,{convertedElectrodes:u,pixelRadius:l,xMargin:s}=jm(n,r,i,a,o,{disableAutoRotate:t.disableAutoRotate});return{...e,convertedElectrodes:u,pixelRadius:l,draggedElectrodeIds:[],hoveredElectrodeId:void 0,dragState:zS,xMarginWidth:s??Oo}}else if(t.type==="DRAGUPDATE"){const n=r_(e.dragState,t.dragAction);if(!n.isActive&&n.dragRect){const r=ID(n.dragRect),i=OS(e.convertedElectrodes,r,e.pixelRadius),a=t.dragAction.shift?[...i,...t.selectedElectrodeIds||[]]:i;return{...e,draggedElectrodeIds:[],hoveredElectrodeId:void 0,pendingSelectedElectrodeIds:a,dragState:zS}}else if(n.dragRect){const r=ID(n.dragRect),i=OS(e.convertedElectrodes,r,e.pixelRadius);return i.length===e.draggedElectrodeIds.length&&i.filter(a=>!e.draggedElectrodeIds.includes(a)).length===0?{...e,hoveredElectrodeId:void 0,dragState:n}:{...e,hoveredElectrodeId:void 0,draggedElectrodeIds:i,dragState:n}}else return{...e,dragState:n}}else if(t.type==="UPDATEHOVER"){const n=RS(e.convertedElectrodes,e.pixelRadius,t.point);return n===e.hoveredElectrodeId?e:{...e,hoveredElectrodeId:n}}else if(t.type==="UPDATECLICK"){const n=RS(e.convertedElectrodes,e.pixelRadius,t.point);if(n===void 0)return!(t.shift||t.ctrl)&&t.selectedElectrodeIds.length>0?{...e,pendingSelectedElectrodeIds:[]}:e;const r=t.ctrl?t.selectedElectrodeIds.includes(n)?t.selectedElectrodeIds.filter(i=>i!==n):[...t.selectedElectrodeIds,n]:t.shift?[...t.selectedElectrodeIds,n]:[n];return{...e,hoveredElectrodeId:void 0,pendingSelectedElectrodeIds:r}}else return console.log("Error: unrecognized verb in electrode geometry reducer."),e},US=!1,IS=25,$S={showLabels:!0,maxElectrodePixelRadius:IS},EN=e=>{const t=e.currentTarget.getBoundingClientRect();return[e.clientX-t.x,e.clientY-t.y]},AN=()=>({selectedElectrodeIds:[],setSelectedElectrodeIds:e=>{}}),kS=e=>{const{width:t,height:n,electrodes:r,disableAutoRotate:i,affineTransform:a}=e,{selectedElectrodeIds:o,setSelectedElectrodeIds:u}=AN(),l=e.disableSelection??!1,s=e.offsetLabels??!1,c=e.colors??hl,f=e.layoutMode??"geom",d=e.maxElectrodePixelRadius||$S.maxElectrodePixelRadius,[h,v]=M.useReducer(wN,{convertedElectrodes:[],pixelRadius:-1,draggedElectrodeIds:[],pendingSelectedElectrodeIds:o||[],dragState:{isActive:!1},xMarginWidth:-1}),{affineTransform:m,handleWheel:D}=Lm(t,n,{shift:!0,alt:!1}),p=M.useMemo(()=>{const T=h.convertedElectrodes.map(_=>{const x=ha(m,{x:_.pixelX,y:_.pixelY});return{..._,pixelX:x.x,pixelY:x.y}});return{...h,convertedElectrodes:T,pixelRadius:h.pixelRadius*Math.sqrt(km(m))}},[m,h]),g=M.useMemo(()=>T=>{const _=EN(T),x=$m(m,{x:_[0],y:_[1]});return[x.x,x.y]},[m]);M.useEffect(()=>{v({type:"INITIALIZE",electrodes:r,width:t,height:n,maxElectrodePixelRadius:d,layoutMode:f,disableAutoRotate:i})},[t,n,r,f,d,i]),M.useEffect(()=>{u(h.pendingSelectedElectrodeIds)},[u,h.pendingSelectedElectrodeIds]);const y=M.useRef(null),S=M.useRef(0),w=l||B.jsx(l_,{width:t,height:n,newState:h.dragState}),b=M.useCallback(T=>{if(!a_(T,{nextDragStateUpdate:y,nextFrame:S,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})){const x=g(T);v({type:"UPDATEHOVER",point:x})}},[g]),E=M.useCallback(T=>{o_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})},[]),C=M.useCallback(T=>{if(h.dragState.isActive)u_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE",selectedElectrodeIds:o}});else{const _=g(T);v({type:"UPDATECLICK",point:_,shift:T.shiftKey,ctrl:T.ctrlKey,selectedElectrodeIds:o||[]})}},[h.dragState.isActive,o,g]),A=M.useMemo(()=>{const T={pixelElectrodes:p.convertedElectrodes,selectedElectrodeIds:o||[],hoveredElectrodeId:h.hoveredElectrodeId,draggedElectrodeIds:h.draggedElectrodeIds,pixelRadius:p.pixelRadius,showLabels:e.showLabels??$S.showLabels,offsetLabels:s,layoutMode:e.layoutMode??"geom",xMargin:h.xMarginWidth,colors:c,affineTransform:a};return B.jsx(ir,{width:t,height:n,draw:fN,drawData:T})},[t,n,p.convertedElectrodes,o,h.hoveredElectrodeId,h.draggedElectrodeIds,p.pixelRadius,e.showLabels,s,e.layoutMode,h.xMarginWidth,c,a]);return M.useMemo(()=>US,[h.convertedElectrodes,o,h.hoveredElectrodeId,h.draggedElectrodeIds,h.pixelRadius,e.showLabels,s,e.layoutMode,h.xMarginWidth,t,n,c]),B.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:b,onMouseUp:C,onMouseDown:E,onWheel:D,children:[w,US,A]})},CN=e=>1/e,ma=(e,t,n,r,i)=>{const a=[];return n.forEach((o,u)=>{for(const l of t){const s=l.electrodeIndices.indexOf(u);if(s>=0){let c;const f=l.waveformStdDev,d=l.waveformPercentiles;if(r==="normal"?c=l.waveform[s]:r==="lower"?c=f?l.waveform[s].map((h,v)=>l.waveform[s][v]-f[s][v]):void 0:r==="upper"?c=f?l.waveform[s].map((h,v)=>l.waveform[s][v]+f[s][v]):void 0:r==="percentile1"?c=d?l.waveform[s].map((h,v)=>d[0][s][v]):void 0:r==="percentile2"?c=d?l.waveform[s].map((h,v)=>d[1][s][v]):void 0:r==="percentile3"?c=d&&2<d.length?l.waveform[s].map((h,v)=>d[2][s][v]):void 0:r==="percentile4"&&(c=d&&3<d.length?l.waveform[s].map((h,v)=>d[3][s][v]):void 0),c){const h=c.map((m,D)=>[(c?.length||0)/2+(D-(c?.length||0)/2)*i,m]),v=Zh(e,h);a.push({pointsInPaintBox:v,offsetFromParentCenter:[o.pixelX,o.pixelY],color:l.waveformColors.base})}}}}),a},TN=(e,t)=>{const{pixelSpacePaths:n,pixelSpacePathsLower:r,pixelSpacePathsUpper:i,pixelSpacePathsPercentile1:a,pixelSpacePathsPercentile2:o,pixelSpacePathsPercentile3:u,pixelSpacePathsPercentile4:l,xMargin:s,waveformWidth:c,affineTransform:f,useUnitColors:d}=t;if(!n||n.length===0)return;if(e.resetTransform(),e.clearRect(0,0,e.canvas.width,e.canvas.height),e.save(),f){const g=f.forward;e.transform(g[0][0],g[1][0],g[0][1],g[1][1],g[0][2],g[1][2])}e.translate(s,0);const h=e.getTransform();r&&i&&r.forEach((g,y)=>{const S=r[y],w=i[y];e.fillStyle="#dddddd",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)});let v,m,D,p;a&&o&&u&&l?(v=a,m=o,D=u,p=l):a&&o&&!u&&!l?(v=void 0,m=a,D=o,p=void 0):(v=void 0,m=void 0,D=void 0,p=void 0),v&&v.length>0&&p&&p.length>0&&v.forEach((g,y)=>{if(!v||!p)throw Error("unexpected");const S=v[y],w=p[y];e.fillStyle="#dddddd",e.strokeStyle="#dddddd",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)}),m&&m.length>0&&m.length>0&&D&&D.length>0&&m.forEach((g,y)=>{if(!m||!D)throw Error("unexpected");const S=m[y],w=D[y];e.fillStyle="#bbbbbb",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)}),n.forEach(g=>{e.strokeStyle=d?g.color:"black",e.lineWidth=c,e.translate(g.offsetFromParentCenter[0],g.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(g.pointsInPaintBox[0][0],g.pointsInPaintBox[0][1]),g.pointsInPaintBox.forEach(y=>{e.lineTo(y[0],y[1])}),e.stroke(),e.setTransform(h)}),e.restore()},MN=e=>{const{electrodes:t,waveforms:n,oneElectrodeHeight:r,oneElectrodeWidth:i,yScale:a,horizontalStretchFactor:o,width:u,height:l,layoutMode:s,waveformWidth:c,affineTransform:f,useUnitColors:d}=e;return M.useMemo(()=>{const v=n.length>0&&n[0].waveform.length>0?n[0].waveform[0].length:0,m=i/v,D=-i*(.5+1/v),p=a*r/2,g=ze([[m,0,D],[0,-p,0],[0,0,1]]).toArray(),y=ma(g,n,t,"normal",o),S=ma(g,n,t,"lower",o),w=ma(g,n,t,"upper",o);let b=ma(g,n,t,"percentile1",o),E=ma(g,n,t,"percentile2",o),C=ma(g,n,t,"percentile3",o),A=ma(g,n,t,"percentile4",o);b.length===0&&(b=void 0),E.length===0&&(E=void 0),C.length===0&&(C=void 0),A.length===0&&(A=void 0);const T=s==="vertical"?(u-i)/2:0,_={pixelSpacePaths:y,pixelSpacePathsLower:S,pixelSpacePathsUpper:w,pixelSpacePathsPercentile1:b,pixelSpacePathsPercentile2:E,pixelSpacePathsPercentile3:C,pixelSpacePathsPercentile4:A,xMargin:T,waveformWidth:c,affineTransform:f,useUnitColors:d};return B.jsx(ir,{width:u,height:l,draw:TN,drawData:_})},[n,t,a,u,l,i,r,s,c,f,o,d])},_N={colors:{border:"rgb(120, 100, 120)",base:"rgb(240, 240, 240)",selected:"rgb(196, 196, 128)",hover:"rgb(128, 128, 255)",selectedHover:"rgb(200, 200, 196)",dragged:"rgb(0, 0, 196)",draggedSelected:"rgb(180, 180, 150)",dragRect:"rgba(196, 196, 196, 0.5)",textLight:"rgb(162, 162, 162)",textDark:"rgb(32, 150, 150)"}},BN=e=>{const t=e.colors??_N.colors,{electrodes:n,waveforms:r,ampScaleFactor:i,horizontalStretchFactor:a,layoutMode:o,hideElectrodes:u,width:l,height:s,showChannelIds:c,useUnitColors:f,waveformWidth:d,disableAutoRotate:h}=e,v=1e3,{handleWheel:m,affineTransform:D}=Lm(l,s,{shift:!0,alt:!0}),p=M.useMemo(()=>B.jsx(kS,{electrodes:n,width:l,height:s,layoutMode:o,colors:t,showLabels:c,maxElectrodePixelRadius:v,disableSelection:!0,disableAutoRotate:h,affineTransform:D}),[n,l,s,o,t,c,h,D]),{convertedElectrodes:g,pixelRadius:y,xMargin:S}=jm(l,s,n,o,v,{disableAutoRotate:h}),w=S||Oo,b=M.useMemo(()=>CN(e.peakAmplitude),[e.peakAmplitude]),E=M.useMemo(()=>i*b,[i,b]),C=o==="geom"?y*2:s/n.length,A=o==="geom"?y*2:l-w-(c?2*y:0),T=B.jsx(MN,{electrodes:g,waveforms:r,oneElectrodeHeight:C,oneElectrodeWidth:A,horizontalStretchFactor:a,yScale:E,width:l,height:s,layoutMode:o,waveformWidth:d,affineTransform:D,useUnitColors:f});return B.jsxs("div",{style:{width:l,height:s,position:"relative"},onWheel:m,children:[!u&&p,T]})},FN=({allChannelIds:e,channelIds:t,units:n,layoutMode:r,hideElectrodes:i,channelLocations:a,samplingFrequency:o,peakAmplitude:u,ampScaleFactor:l,horizontalStretchFactor:s,showChannelIds:c,useUnitColors:f,showReferenceProbe:d,disableAutoRotate:h,width:v,height:m})=>{const D=M.useMemo(()=>{const w=a||{};return t.map(b=>({id:b,label:`${b}`,x:w[`${b}`]!==void 0?w[`${b}`][0]:Ct(b),y:w[`${b}`]!==void 0?w[`${b}`][1]:0}))},[t,a]),p=M.useMemo(()=>{const w=a||{};return e.map(b=>({id:b,label:`${b}`,x:w[`${b}`]!==void 0?w[`${b}`][0]:Ct(b),y:w[`${b}`]!==void 0?w[`${b}`][1]:0}))},[e,a]),g=v/4,y=M.useMemo(()=>n.map(w=>{const b={base:w.waveformColor},E=[];for(const C of w.channelIds)E.push(D.map(A=>A.id).indexOf(C));return{electrodeIndices:E,waveform:w.waveform,waveformStdDev:w.waveformStdDev,waveformPercentiles:w.waveformPercentiles,waveformColors:b}}),[D,n]),S=B.jsx(BN,{waveforms:y,electrodes:D,ampScaleFactor:l,horizontalStretchFactor:s,layoutMode:a?r:"vertical",hideElectrodes:i,width:d?v-g:v,height:m,showLabels:!0,peakAmplitude:u,samplingFrequency:o,showChannelIds:c,useUnitColors:f,waveformWidth:2,disableAutoRotate:h});return d?B.jsxs("div",{style:{position:"relative",width:v,height:m},children:[B.jsx("div",{style:{position:"absolute",left:0,top:0,width:g,height:m},children:B.jsx(kS,{electrodes:p,disableSelection:!1,width:g,height:m})}),B.jsx("div",{style:{position:"absolute",left:g,top:0,width:v-g,height:m},children:S})]}):S},NN=({data:e,width:t,height:n})=>{const r=M.useMemo(()=>{const k=[];for(const q of e.averageWaveforms)for(const Y of q.channelIds)k.includes(Y)||k.push(Y);return yr(k)},[e.averageWaveforms]),[i,a]=M.useState({...xf,onlyShowSelected:!1}),{selectedUnitIds:o,currentUnitId:u,orderedUnitIds:l,plotClickHandlerGenerator:s,unitIdSelectionDispatch:c}=qr(),[f,d]=M.useState(1),[h,v]=M.useState("geom"),[m,D]=M.useState(!0),[p,g]=M.useState(!1),[y,S]=M.useState(e.showReferenceProbe||!1),[w,b]=M.useState(!1),[E,C]=M.useState(1),[A,T]=M.useState(!0),[_,x]=M.useState(!0);M.useEffect(()=>{c({type:oo,newUnitOrder:yr(e.averageWaveforms.map(k=>k.unitId))})},[e.averageWaveforms,c]);const[F,R]=M.useState(2),z=M.useMemo(()=>{let k=0;return e.averageWaveforms.forEach(q=>{q.waveform.forEach(Y=>{Y.forEach(ee=>{const te=Math.abs(ee);te>k&&(k=te)})})}),k},[e.averageWaveforms]),N=M.useMemo(()=>e.averageWaveforms.filter(k=>i.onlyShowSelected?o.has(k.unitId):!0).map(k=>{const q=[{channelIds:k.channelIds,waveform:ON(k.waveform),waveformStdDev:m&&!w?k.waveformStdDev:void 0,waveformPercentiles:m&&!w&&k.waveformPercentiles?zN(k.waveformPercentiles,k.waveform):void 0,waveformColor:wr(Ct(k.unitId))}],Y={allChannelIds:r,channelIds:k.channelIds,units:q,layoutMode:h,hideElectrodes:A,channelLocations:e.channelLocations,samplingFrequency:e.samplingFrequency,peakAmplitude:z,ampScaleFactor:f,horizontalStretchFactor:E,showChannelIds:p,useUnitColors:_,width:120*F+(y?120*F/4:0),height:120*F,showReferenceProbe:y,disableAutoRotate:!0};return{unitId:k.unitId,key:k.unitId,label:`Unit ${k.unitId}`,labelColor:wr(Ct(k.unitId)),clickHandler:i.onlyShowSelected?void 0:s(k.unitId),props:Y}}),[e.averageWaveforms,e.channelLocations,e.samplingFrequency,r,z,h,f,s,i.onlyShowSelected,o,F,m,p,y,w,E,A,_]),U=M.useMemo(()=>l?l.map(k=>N.filter(q=>q.unitId===k)[0]).filter(k=>k!==void 0):N,[N,l]),I=M.useMemo(()=>w?RN(U):U,[U,w]),L=M.useMemo(()=>[{type:"button",callback:()=>{C(k=>k*1.1)},title:"Increase horizontal stretch [alt + mouse-wheel]",icon:B.jsx(T_,{})},{type:"button",callback:()=>{C(1)},title:"Reset scale amplitude",icon:B.jsx(XD,{})},{type:"button",callback:()=>{C(k=>k/1.1)},title:"Decrease horizontal stretch [alt + mouse-wheel]",icon:B.jsx(C_,{})}],[]),G=M.useMemo(()=>{const k=aN({ampScaleFactor:f,setAmpScaleFactor:d}),q={type:"toggle",subtype:"checkbox",callback:()=>v(de=>de==="geom"?"vertical":"geom"),title:"Show electrode geometry",selected:h==="geom"},Y={type:"toggle",subtype:"checkbox",callback:()=>T(de=>!de),title:"Show electrodes",selected:!A},ee=[{type:"button",callback:()=>R(de=>de*1.3),title:"Increase box size",icon:B.jsx(Tc,{})},{type:"button",callback:()=>R(de=>de/1.3),title:"Decrease box size",icon:B.jsx(Cc,{})}],te={type:"toggle",subtype:"checkbox",callback:()=>D(de=>!de),title:"Show waveform stdev",selected:m===!0},ne={type:"toggle",subtype:"checkbox",callback:()=>g(de=>!de),title:"Show channel IDs",selected:p===!0},oe={type:"toggle",subtype:"checkbox",callback:()=>S(de=>!de),title:"Show reference probes",selected:y===!0},W={type:"toggle",subtype:"checkbox",callback:()=>b(de=>!de),title:"Show overlapping",selected:w===!0},ce={type:"toggle",subtype:"checkbox",callback:()=>x(de=>!de),title:"Use unit colors",selected:_===!0};return[{type:"divider"},...ee,{type:"divider"},...k,{type:"divider"},...L,{type:"divider"},q,Y,{type:"divider"},te,{type:"divider"},ne,{type:"divider"},oe,{type:"divider"},W,{type:"divider"},ce]},[h,f,m,p,w,y,L,A,_]),X=M.useCallback(k=>{k.shiftKey&&!k.altKey?k.deltaY<0?d(q=>q*1.3):d(q=>q/1.3):k.altKey&&!k.shiftKey&&(k.deltaY<0?C(q=>q*1.1):C(q=>q/1.1))},[]),P=30,j=M.useCallback(k=>{k&&k.addEventListener("wheel",q=>{(q.shiftKey||q.altKey)&&q.preventDefault()})},[]),H=fl;return B.jsxs("div",{ref:k=>j(k),onWheel:X,children:[B.jsxs(Ro,{width:t,height:n-P,initialPosition:H,adjustable:!1,children:[B.jsx(dl,{width:H,height:n,customActions:G}),B.jsx(wc,{width:0,height:0,children:B.jsx(xc,{plots:I,plotComponent:FN,selectedPlotKeys:i.onlyShowSelected?void 0:o,currentPlotKey:u})})]}),B.jsx("div",{style:{position:"absolute",top:n-P,height:P,overflow:"hidden"},children:B.jsx(wf,{options:i,setOptions:a})})]})},RN=e=>{if(e.length===0)return e;const t={...e[0],props:{...e[0].props}},n=t.props;t.key="overlapping",t.label="Overlapping",t.labelColor="black",t.unitId="overlapping",n.height*=3;const r=new Set;for(const a of e)for(const o of a.props.channelIds)r.add(o);const i=yr([...r]);return n.channelIds=i,n.units=e.map(a=>a.props.units[0]),[t]},ON=e=>e.map(t=>{const n=LS(t);return t.map(r=>r-n)}),zN=(e,t)=>{const n=[];for(let r=0;r<e.length;r++)n.push(e[r].map((i,a)=>{const o=LS(t[a]);return i.map(u=>u-o)}));return n},LS=e=>e.length>0?W5(e):0,UN=e=>B.jsx(Jr,{context:e.contexts.unitSelection,children:B.jsx(IN,{...e})}),IN=({zarrGroup:e,width:t,height:n})=>{const[r,i]=M.useState(null);return M.useEffect(()=>{let a=!1;return(async()=>{const u=[],l=e.attrs.num_average_waveforms||0,s=e.attrs.average_waveforms,c=s.length;c!==l&&console.warn(`numUnits (${c}) !== numAverageWaveforms (${l})`);for(let f=0;f<l;f++){const d=`waveform_${f}`,h=await e.getGroup(d);if(!h){console.warn(`No group for ${d}`);continue}if(h.datasets.find(g=>g.name==="waveform")===void 0){console.warn(`No waveform dataset for ${d}`);continue}const v=await e.getDataset(`${d}/waveform`);if(!v){console.warn(`Could not load waveform dataset for ${d}`);continue}const m=v.shape,D=await e.getDatasetData(`${d}/waveform`,{});let p;if(h.datasets.find(g=>g.name==="waveform_std_dev")===void 0?p=void 0:p=await e.getDatasetData(`${d}/waveform_std_dev`,{}),D){const g=s.find(y=>y.name===d);g&&u.push({unitId:g.unit_id,channelIds:g.channel_ids,waveform:jS(D,m),waveformStdDev:p?jS(p,m):void 0})}}a||i({type:"AverageWaveforms",averageWaveforms:u})})(),()=>{a=!0}},[e]),r?B.jsx(NN,{data:r,width:t,height:n}):B.jsx("div",{children:"Loading..."})},jS=(e,t)=>{if(t.length!==2)throw Error("shape.length should be 2");const[n,r]=t;if(e.length!==n*r)throw Error(`data.length does not match shape. Expected ${n*r}, got ${e.length}`);const i=[];for(let a=0;a<r;a++){const o=[];for(let u=0;u<n;u++)o.push(e[u*r+a]);i.push(o)}return i},HS=20,$N=({data:e,width:t,height:n})=>{const[r,i]=M.useState(!1),{selectedUnitIds:a}=qr(),o=M.useMemo(()=>yr([...a]),[a]),u=e.hideUnitSelector,l=M.useMemo(()=>{const p=e.crossCorrelograms.filter(y=>o.includes(y.unitId1)&&o.includes(y.unitId2)),g=[];for(const y of o)for(const S of o){const w=p.filter(b=>b.unitId1===y&&b.unitId2===S)[0];w?g.push(w):g.push(void 0)}return g},[e.crossCorrelograms,o]),s=u?0:100,c=fl,f=t-s-c,d=n,h=M.useMemo(()=>{const p=o.length,{plotWidth:g,plotHeight:y}=PS(f,d,p);return l.map((S,w)=>({key:`${w}`,unitId:S?S.unitId1:0,label:S?g>80?`Unit ${S.unitId1}/${S.unitId2}`:`${S.unitId1}/${S.unitId2}`:"",labelColor:"black",clickHandler:void 0,props:{binEdgesSec:S?S.binEdgesSec:void 0,binCounts:S?S.binCounts:void 0,color:S?.unitId1===S?.unitId2?wr(Ct(S?.unitId1)):"gray",width:g,height:y,hideXAxis:!r}}))},[l,f,d,o,r]),v=M.useMemo(()=>[{type:"toggle",subtype:"checkbox",callback:()=>i(g=>!g),title:"Show X Axis",selected:r===!0}],[r]),m=M.useMemo(()=>{const p=new Set;e.crossCorrelograms.forEach(y=>{p.add(y.unitId1),p.add(y.unitId2)});const g=yr(Array.from(p));return{type:"UnitsTable",columns:[],rows:g.map(y=>({unitId:y,values:{}}))}},[e.crossCorrelograms]),D=B.jsxs(Ro,{width:t-s,height:n,initialPosition:c,adjustable:!1,children:[B.jsx(dl,{width:c,height:n,customActions:v}),B.jsx(wc,{width:0,height:0,disableScroll:!0,children:o.length>HS?B.jsxs("div",{children:["Not showing cross-correlogram matrix. Too many units selected (max ="," ",HS,")."]}):o.length===0?B.jsx("div",{children:"Select one or more units to view cross-correlograms."}):B.jsx(xc,{plots:h,plotComponent:xS,selectedPlotKeys:void 0,numPlotsPerRow:o.length})})]});return u?D:B.jsxs("div",{style:{position:"relative",width:t,height:n},children:[B.jsx("div",{style:{position:"absolute",left:0,top:0,width:s,height:n,borderRight:"1px solid #ccc",boxSizing:"border-box",padding:10,backgroundColor:"#f9f9f9"},children:B.jsx(CS,{data:m,width:s,height:n})}),B.jsx("div",{style:{position:"absolute",left:s,top:0,width:t-s,height:n},children:D})]})},PS=(e,t,n)=>{const r=Math.min((e-30-(n-1)*7)/n,(t-30-(n-1)*7)/n);return{plotWidth:r,plotHeight:r}},kN=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null);return M.useEffect(()=>{let o=!1;return(async()=>{const l=[],s=e.attrs.num_cross_correlograms||0;if(s===0){o||a({type:"CrossCorrelograms",crossCorrelograms:[],hideUnitSelector:e.attrs.hide_unit_selector||!1});return}const c=await e.getDatasetData("bin_edges_sec",{}),f=await e.getDatasetData("bin_counts",{});if(!c||!f){console.error("Failed to load cross-correlograms data");return}const d=Array.from(c),h=new Int32Array(f),v=d.length-1,m=e.attrs.cross_correlograms;for(let p=0;p<s;p++){const g=m[p],y=p*v,S=Array.from(h.slice(y,y+v));l.push({unitId1:g.unit_id1,unitId2:g.unit_id2,binEdgesSec:d,binCounts:S})}const D=e.attrs.hide_unit_selector||!1;o||a({type:"CrossCorrelograms",crossCorrelograms:l,hideUnitSelector:D})})(),()=>{o=!0}},[e]),i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx($N,{data:i,width:n,height:r})}):B.jsx("div",{children:"Loading..."})},LN=1.4,jN=(e,t,n,r)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: * Attempt to call zoomTime() with uninitialized state ${e}.`),{visibleStartTimeSec:e.visibleStartTimeSec,visibleEndTimeSec:e.visibleEndTimeSec};const i=e.endTimeSec-e.startTimeSec,a=e.visibleEndTimeSec-e.visibleStartTimeSec;if(a===i&&t==="out")return{visibleStartTimeSec:e.startTimeSec,visibleEndTimeSec:e.endTimeSec};let o=n??LN;o=t==="in"?1/o:o;const u=Math.min(a*o,i);if(u>=i)return{...e,visibleStartTimeSec:e.startTimeSec,visibleEndTimeSec:e.endTimeSec};const l=r!==void 0?r:e.currentTime??e.visibleStartTimeSec+a/2,s=(l-e.visibleStartTimeSec)/a;let c=Math.max(l-s*u,e.startTimeSec);const f=Math.min(c+u,e.endTimeSec);return c=f-u,{visibleStartTimeSec:c,visibleEndTimeSec:f}},qS=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: Attempt to call panTime() with uninitialized state ${e}.`),e;const n=e.visibleEndTimeSec-e.visibleStartTimeSec;let r=e.visibleStartTimeSec,i=e.visibleEndTimeSec;if(t>0)i=Math.min(e.visibleEndTimeSec+t,e.endTimeSec),r=Math.max(i-n,e.startTimeSec);else if(t<0)r=Math.max(e.visibleStartTimeSec+t,e.startTimeSec),i=Math.min(r+n,e.endTimeSec);else return e;const o=!0?e.currentTime:void 0;return r===e.visibleStartTimeSec&&i===e.visibleEndTimeSec?e:{...e,visibleStartTimeSec:r,visibleEndTimeSec:i,currentTimeSec:o}},HN=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: * Attempt to call panTime() with uninitialized state ${e}.`),{visibleStartTimeSec:e.visibleStartTimeSec,visibleEndTimeSec:e.visibleEndTimeSec};const n=e.visibleEndTimeSec-e.visibleStartTimeSec,r=t.panAmountPct/100*n*(t.type==="back"?-1:1);return qS(e,r)},PN=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: Attempt to call panTime() with uninitialized state ${e}.`),e;const n=t.deltaT;return qS(e,n)},VS=Nt.createContext(void 0),Mf=()=>{const e=M.useContext(VS);if(!e)throw new Error("useTimeseriesSelection must be used within a TimeseriesSelectionContext");const t=e.dispatch,n=M.useCallback(u=>{t({type:"initializeTimeseries",startTimeSec:u.startTimeSec,endTimeSec:u.endTimeSec,initialVisibleStartTimeSec:u.initialVisibleStartTimeSec,initialVisibleEndTimeSec:u.initialVisibleEndTimeSec})},[t]),r=M.useCallback((u,l)=>{t({type:"setVisibleTimeRange",visibleStartTimeSec:u,visibleEndTimeSec:l})},[t]),i=M.useCallback(u=>{t({type:"setCurrentTime",currentTime:u})},[t]),a=M.useCallback(u=>{t({type:"zoomVisibleTimeRange",factor:u})},[t]),o=M.useCallback(u=>{t({type:"translateVisibleTimeRangeFrac",frac:u})},[t]);if(e===void 0)throw new Error("useTimeseriesSelection must be used within a TimeseriesSelectionContext.Provider");return{initializeTimeseriesSelection:n,setVisibleTimeRange:r,setCurrentTime:i,zoomVisibleTimeRange:a,translateVisibleTimeRangeFrac:o,timeseriesSelection:e.timeseriesSelection,startTimeSec:e.timeseriesSelection.startTimeSec,endTimeSec:e.timeseriesSelection.endTimeSec,visibleStartTimeSec:e.timeseriesSelection.visibleStartTimeSec,visibleEndTimeSec:e.timeseriesSelection.visibleEndTimeSec,currentTime:e.timeseriesSelection.currentTime}},_f=()=>{const{visibleStartTimeSec:e,visibleEndTimeSec:t,currentTime:n,setCurrentTime:r,startTimeSec:i,endTimeSec:a,setVisibleTimeRange:o}=Mf(),u=M.useCallback((d,h,v)=>{const m=jN({visibleStartTimeSec:e,visibleEndTimeSec:t,currentTime:n,startTimeSec:i,endTimeSec:a},d,h,v);m.visibleStartTimeSec!==void 0&&m.visibleEndTimeSec!==void 0&&o(m.visibleStartTimeSec,m.visibleEndTimeSec)},[e,t,n,i,a,o]),l=M.useCallback((d,h)=>{const v=HN({visibleStartTimeSec:e,visibleEndTimeSec:t,startTimeSec:i,endTimeSec:a,currentTime:n},{type:d,panAmountPct:h??10});v.visibleStartTimeSec!==void 0&&v.visibleEndTimeSec!==void 0&&o(v.visibleStartTimeSec,v.visibleEndTimeSec)},[e,t,i,a,n,o]),s=M.useCallback(d=>{const h=PN({visibleStartTimeSec:e,visibleEndTimeSec:t,startTimeSec:i,endTimeSec:a,currentTime:n},{deltaT:d});h.visibleStartTimeSec!==void 0&&h.visibleEndTimeSec!==void 0&&o(h.visibleStartTimeSec,h.visibleEndTimeSec)},[e,t,i,a,n,o]),c=M.useCallback(d=>{if(e===void 0||t===void 0)return;const h=t-e,v=d,m=v+h;o(v,m)},[e,t,o]),f=M.useCallback((d,h)=>{if(e===void 0||t===void 0)return;const v=e+d*(t-e);r(v)},[e,t,r]);return{visibleStartTimeSec:e,visibleEndTimeSec:t,setVisibleTimeRange:o,zoomTimeseriesSelection:u,panTimeseriesSelection:l,panTimeseriesSelectionDeltaT:s,panTimeseriesSelectionVisibleStartTimeSec:c,setCurrentTimeFraction:f}},GS=()=>{const[e,t]=M.useState(!1),n=M.useMemo(()=>[{id:"only-show-selected",label:"Only Show Selected",tooltip:"Toggle visibility of only selected units",icon:e?"👁️":"👁️‍🗨️",isActive:e,onClick:()=>t(r=>!r)}],[e]);return{onlyShowSelected:e,customToolbarActions:n}},qN=[{name:"1ms",secondsPerTick:.001,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%1e3} ms`},{name:"10ms",secondsPerTick:.01,countPerLargerUnit:10,scale_appropriate_label:e=>`${e*10%1e3} ms`},{name:"100ms",secondsPerTick:.1,countPerLargerUnit:10,scale_appropriate_label:e=>`${e*100%1e3} ms`},{name:"1s",secondsPerTick:1,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%60} s`},{name:"10s",secondsPerTick:10,countPerLargerUnit:6,scale_appropriate_label:e=>`${e*10%60} s`},{name:"1min",secondsPerTick:60,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%60} min`},{name:"10min",secondsPerTick:60*10,countPerLargerUnit:6,scale_appropriate_label:e=>`${e*10%60} min`},{name:"1hr",secondsPerTick:60*60,countPerLargerUnit:6,scale_appropriate_label:e=>`${e%24} hr`},{name:"6hr",secondsPerTick:60*60*6,countPerLargerUnit:4,scale_appropriate_label:e=>`${e*6%24} hr`},{name:"1day",secondsPerTick:60*60*24,countPerLargerUnit:10,scale_appropriate_label:e=>`${e} day`},{name:"10day",secondsPerTick:60*60*24*10,countPerLargerUnit:1e4,scale_appropriate_label:e=>`${10*e} day`}],VN=(e,t,n,r)=>M.useMemo(()=>{if(t===void 0||n===void 0)return[];if(n<=t)return[];const i=[],a=e/(n-t);for(const o of qN){const u=a*o.secondsPerTick;if(u<=50)continue;const l=Math.ceil(t/o.secondsPerTick),s=Math.floor(n/o.secondsPerTick),c=u>200||s-l<5;for(let f=l;f<=s;f++){if(f%o.countPerLargerUnit===0)continue;const d=f*o.secondsPerTick;i.push({value:d,label:o.scale_appropriate_label(f),major:c,xPixelPosition:r(d)})}}return i},[t,n,r,e]),GN=e=>{if(!e||typeof e=="function")return;const t=e.current,n=t&&t.getContext("2d");if(n)return n},YN={position:"absolute",left:0,top:0},YS=e=>{const{width:t,height:n,draw:r,drawData:i}=e,a=M.useRef(null);return M.useEffect(()=>{const o=GN(a);o&&o.canvas&&r(o,i)},[r,a,i]),B.jsx("canvas",{ref:a,width:t,height:n,style:YN})},XN=(e,t)=>{const{width:n,height:r,margins:i,timeTicks:a,gridlineOpts:o,yTickSet:u,yLabel:l}=t;e.clearRect(0,0,e.canvas.width,e.canvas.height);const s=r-i.bottom;ZN(e,a,s,i.top,{hideGridlines:o?.hideX},t.hideTimeAxisLabels),e.strokeStyle="lightgray",Hm(e,i.left,s,n-i.right,s),u&&QN(e,u,s,i.left,n-i.right,i.top,{hideGridlines:o?.hideY}),l&&KN(e,l,i.left,i.bottom,i.top,e.canvas.height)},ZN=(e,t,n,r,i,a)=>{const o=a||!1;if(!t||t.length===0)return;const u=2,l=n+(o?0:5);e.textAlign="center",e.textBaseline="top",t.forEach(s=>{e.strokeStyle=s.major?"gray":"lightgray";const c=i.hideGridlines?n:r;Hm(e,s.xPixelPosition,l,s.xPixelPosition,c),o||(e.fillStyle=s.major?"black":"gray",e.fillText(s.label,s.xPixelPosition,l+u))})},QN=(e,t,n,r,i,a,o)=>{const l=r-5,s=l-2,{ticks:c}=t;e.fillStyle="black",e.textAlign="right",e.textBaseline="middle",c.forEach(f=>{if(!f.pixelValue)return;const d=f.pixelValue;e.strokeStyle=f.isMajor?"gray":"lightgray",e.fillStyle=f.isMajor?"black":"gray";const h=o.hideGridlines?r:i;Hm(e,l,d,h,d),e.fillText(f.label,s,d)})},KN=(e,t,n,r,i,a)=>{e.textAlign="center",e.textBaseline="middle",e.save(),e.translate(15,(a-r-i)/2+i),e.fillStyle="black",e.font="13px sans-serif",e.rotate(-Math.PI/2),e.fillText(t,0,0),e.restore()},Hm=(e,t,n,r,i)=>{e.beginPath(),e.moveTo(t,n),e.lineTo(r,i),e.stroke()},WN={},JN=e=>{const{width:t,height:n}=e,r=M.useCallback(i=>{XN(i,e)},[e]);return B.jsx("span",{className:"TSV2AxesLayer",children:B.jsx(YS,{width:t,height:n,draw:r,drawData:WN})})},e7=(e,t)=>{const{margins:n,currentTimePixels:r,currentTimeIntervalPixels:i}=t;if(e.clearRect(0,0,e.canvas.width,e.canvas.height),i!==void 0){e.fillStyle="rgba(255, 225, 225, 0.4)",e.strokeStyle="rgba(150, 50, 50, 0.9)";const a=i[0],o=n.top,u=i[1]-i[0],l=e.canvas.height-n.bottom-n.top;e.fillRect(a,o,u,l),e.strokeRect(a,o,u,l)}if(r!==void 0&&i===void 0){e.fillStyle="rgba(255, 255, 0, 0.1)";const a=4;e.fillRect(r-a/2,n.top,a,e.canvas.height-n.bottom-n.top),e.strokeStyle="rgba(200, 200, 0, 0.4)",e.lineWidth=1,e.beginPath(),e.moveTo(r,n.top),e.lineTo(r,e.canvas.height-n.bottom),e.stroke()}},t7=e=>{const{width:t,height:n,timeRange:r,currentTimePixels:i,currentTimeIntervalPixels:a,margins:o}=e,u=M.useMemo(()=>({width:t,height:n,timeRange:r,currentTimePixels:i,currentTimeIntervalPixels:a,margins:o}),[t,n,r,i,a,o]);return B.jsx(YS,{width:t,height:n,draw:e7,drawData:u})},n7=({width:e,height:t,selectionRect:n})=>{if(!n)return null;const{startX:r,endX:i}=n,a=Math.abs(i-r),o=Math.min(r,i);return B.jsx("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none",zIndex:10},children:B.jsx("div",{style:{position:"absolute",left:o,top:0,width:a,height:t,backgroundColor:"rgba(0, 123, 255, 0.2)",border:"1px solid rgba(0, 123, 255, 0.6)",borderRadius:"2px"}})})},r7=e=>{const{pixelToTime:t,visibleStartTimeSec:n,setCurrentTime:r,onMouseDown:i,onMouseUp:a,onMouseMove:o,onMouseOut:u,onCanvasClick:l,interactionMode:s}=e,{panTimeseriesSelectionVisibleStartTimeSec:c,setVisibleTimeRange:f}=_f(),[d,h]=M.useState(!1),[v,m]=M.useState(void 0),[D,p]=M.useState(null),g=M.useRef({mouseDownAchorX:null,mouseDownAnchorTime:null,mouseDownAnchorVisibleStartTime:null,mouseDownAnchorPixelToTime:null,moved:!1,selectionStartX:null,selectionEndX:null}),y=M.useCallback(E=>{if(h(!0),!E.shiftKey&&!E.ctrlKey&&!E.altKey){const C=E.clientX-E.currentTarget.getBoundingClientRect().x;s==="select-zoom"?(g.current.selectionStartX=C,g.current.selectionEndX=C,p({startX:C,endX:C})):(g.current.mouseDownAchorX=C,g.current.mouseDownAnchorTime=t(C),g.current.mouseDownAnchorVisibleStartTime=n||null,g.current.mouseDownAnchorPixelToTime=t),g.current.moved=!1}else i&&i(E)},[t,i,n,s]),S=M.useCallback(E=>{if(!E.shiftKey&&!E.ctrlKey&&!E.altKey){const C=E.clientX-E.currentTarget.getBoundingClientRect().x;if(s==="select-zoom"&&g.current.selectionStartX!==null){const A=Math.min(g.current.selectionStartX,C),T=Math.max(g.current.selectionStartX,C);if(Math.abs(T-A)>5){const _=t(A),x=t(T);f(_,x)}else if(!g.current.moved){const _=t(C);if(r(_),l){const x=E.clientY-E.currentTarget.getBoundingClientRect().y;l(C,x)}}p(null),g.current.selectionStartX=null,g.current.selectionEndX=null}else if(g.current.mouseDownAchorX=null,g.current.mouseDownAnchorTime=null,g.current.mouseDownAnchorPixelToTime=null,!g.current.moved){const A=t(C);if(r(A),l){const T=E.clientY-E.currentTarget.getBoundingClientRect().y;l(C,T)}}}else a&&a(E)},[a,t,r,s,f,l]),w=M.useCallback(E=>{const C=E.clientX-E.currentTarget.getBoundingClientRect().x,A=t(C);if(m(A),!E.shiftKey&&!E.ctrlKey&&!E.altKey){if(s==="select-zoom"&&g.current.selectionStartX!==null)g.current.selectionEndX=C,p({startX:Math.min(g.current.selectionStartX,C),endX:Math.max(g.current.selectionStartX,C)}),g.current.moved=!0;else if(s==="pan"&&g.current.mouseDownAchorX!==null&&g.current.mouseDownAnchorPixelToTime!==null){const T=g.current.mouseDownAnchorPixelToTime(C),_=g.current.mouseDownAnchorTime,x=g.current.mouseDownAnchorVisibleStartTime;if(_!==null&&x!==null){const F=T-_,R=C-g.current.mouseDownAchorX;if(Math.abs(R)>2||Math.abs(F)>.01){const z=x-F;c(z),E.preventDefault(),E.stopPropagation(),g.current.moved=!0}}}}o&&o(E)},[t,o,s,c]),b=M.useCallback(E=>{m(void 0),h(!1),p(null),g.current.selectionStartX=null,g.current.selectionEndX=null,u&&u(E)},[u]);return{isViewClicked:d,hoverTime:v,selectionRect:D,handleMouseDown:y,handleMouseUp:S,handleMouseMove:w,handleMouseOut:b}},i7=({width:e,height:t,leftMargin:n,customToolbarActions:r,hideTimeAxisLabels:i,hideNavToolbar:a})=>{const o=r&&r.length>0,u=M.useMemo(()=>({left:n||60,right:20,top:10,bottom:i?10:30}),[n,i]);let l=0;a||(l+=40),o&&(l+=40);const s=e,c=t-l;return{margins:u,canvasWidth:s,canvasHeight:c}},a7=23,o7=60,u7=(e,t,n,r)=>{const i=Math.ceil((t-r)/n);return isNaN(i)||i<1?[]:Array(i).fill(0).map((a,o)=>r+o*n).filter(a=>a>e)},l7=(e,t)=>{let n=0;const r=Math.trunc(Math.log10(t));if(Math.trunc(Math.log10(e))!==r)return n;const i=Math.trunc(Math.log10(t-e));if(r<=i)return n;const a=i+1,o=Math.pow(10,-a),u=Math.trunc(t*o).toString(),l=Math.trunc(e*o).toString();for(const[s,c]of[...u].entries()){if(c!==l[s]){n=n*Math.pow(10,s-a);break}n=n*10+parseInt(c)}return n*Math.pow(10,a)},s7=(e,t)=>Math.floor(e*Math.pow(10,-(t+1)))*Math.pow(10,t+1),c7=(e,t,n)=>{const r=e-t,i=Math.trunc(r*Math.pow(10,-n)),a=i%10===0;return{label:Math.abs(n)>3?`${(i/10).toFixed(1)}e${n+1}`:`${Math.round(i*Math.pow(10,n)*1e9)/1e9}`,isMajor:a,dataValue:e}},f7=(e,t,n,r,i)=>{const a=u7(t,n,r,e).map(l=>Math.round(l*1e9)/1e9),o=l7(t,n);return a.map(l=>c7(l,o,i))},XS={ticks:[],datamin:0,datamax:0},d7=(e,t)=>{const n=Math.floor(Math.log10(e/t)),r=Math.pow(10,n),i=[1,2,5,10],o=i.map(u=>e/(r*u)).findIndex(u=>u<t);return o===3?{step:1,scale:n+1}:{step:i[o],scale:n}},h7=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;i<=1&&(i=1);const a=r??1;return M.useMemo(()=>{if(t===void 0||n===void 0||t===n)return XS;const o=t/a,u=n/a,l=u-o,s=i/o7,c=i/a7,f=d7(l,c),d=f.step*Math.pow(10,f.scale);if(l/d<s)return console.warn("Error: Unable to compute valid y-axis step size. Suppressing display."),XS;const h=s7(o,f.scale);return{ticks:f7(h,o,u,d,f.scale),datamin:o,datamax:u}},[n,t,a,i])},m7=e=>{const t=Math.round(e*1e3),n=Math.floor(t/(1e3*60*60)),r=Math.floor(t%(1e3*60*60)/(1e3*60)),i=Math.floor(t%(1e3*60)/1e3),a=t%1e3;return`${n.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}.${a.toString().padStart(3,"0")}`},p7=({width:e,height:t,interactionMode:n,onInteractionModeChange:r,currentTime:i,onZoomToFit:a})=>{const{zoomTimeseriesSelection:o,panTimeseriesSelection:u}=_f(),l=M.useCallback(()=>{o("in",1.2)},[o]),s=M.useCallback(()=>{o("out",1.2)},[o]),c=M.useCallback(()=>{u("back",10)},[u]),f=M.useCallback(()=>{u("forward",10)},[u]),d=M.useCallback(h=>{r(h)},[r]);return B.jsxs("div",{style:{width:e,height:t,backgroundColor:"#f8f9fa",borderTop:"1px solid #dee2e6",display:"flex",alignItems:"center",justifyContent:"space-between",padding:"0 12px",fontSize:"13px",fontFamily:"system-ui, -apple-system, sans-serif"},children:[B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[B.jsx("button",{onClick:()=>d("pan"),style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:n==="pan"?"#007bff":"#ffffff",color:n==="pan"?"#ffffff":"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease"},title:"Pan mode: Drag to pan, wheel to zoom",children:"🖱️ Pan"}),B.jsx("button",{onClick:()=>d("select-zoom"),style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:n==="select-zoom"?"#007bff":"#ffffff",color:n==="select-zoom"?"#ffffff":"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease"},title:"Select zoom mode: Drag to select region and zoom in",children:"🔍 Select"})]}),B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[B.jsx("button",{onClick:c,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Pan left",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"⬅️"}),B.jsx("button",{onClick:s,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Zoom out",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🔍➖"}),B.jsx("button",{onClick:l,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Zoom in",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🔍➕"}),B.jsx("button",{onClick:f,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Pan right",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"➡️"}),B.jsx("div",{style:{width:"1px",height:"20px",backgroundColor:"#dee2e6",margin:"0 4px"}}),B.jsx("button",{onClick:a,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Reset zoom to show all data",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🏠"})]}),B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[B.jsx("span",{style:{color:"#6c757d",fontWeight:"500"},children:"Time:"}),B.jsx("span",{style:{padding:"4px 8px",backgroundColor:"#e9ecef",borderRadius:"4px",fontFamily:"Monaco, Consolas, monospace",fontSize:"12px",fontWeight:"600",color:"#495057",minWidth:"120px",textAlign:"center"},children:i!==void 0?m7(i):"--:--:--.---"})]})]})},g7=({width:e,height:t,customActions:n})=>!n||n.length===0?null:B.jsx("div",{style:{width:e,height:t,backgroundColor:"#f8f9fa",borderTop:"1px solid #dee2e6",display:"flex",alignItems:"center",justifyContent:"flex-start",padding:"0 12px",fontSize:"13px",fontFamily:"system-ui, -apple-system, sans-serif"},children:B.jsx("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:n.map(r=>r.component?B.jsx("div",{style:{display:"flex",alignItems:"center"},children:r.component},r.id):B.jsxs("button",{onClick:r.onClick,style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:r.isActive?"#007bff":"#ffffff",color:r.isActive?"#ffffff":"#495057",cursor:r.onClick?"pointer":"default",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:r.tooltip||r.label,onMouseEnter:i=>{!r.isActive&&r.onClick&&(i.currentTarget.style.backgroundColor="#e9ecef")},onMouseLeave:i=>{!r.isActive&&r.onClick&&(i.currentTarget.style.backgroundColor="#ffffff")},children:[r.icon&&B.jsx("span",{children:r.icon}),r.label]},r.id))})}),v7=e=>{if(!e||!e.current)return;e.current.querySelectorAll("canvas").forEach(n=>{n.addEventListener("wheel",r=>{r.preventDefault()})})},ZS=({width:e,height:t,onCanvasElement:n,gridlineOpts:r,onKeyDown:i,onMouseDown:a,onMouseMove:o,onMouseOut:u,onMouseUp:l,yAxisInfo:s,shiftZoom:c,requireClickToZoom:f,leftMargin:d,customToolbarActions:h,onCanvasClick:v,hideNavToolbar:m=!1,hideTimeAxisLabels:D=!1})=>{const{visibleStartTimeSec:p,visibleEndTimeSec:g,zoomTimeseriesSelection:y,panTimeseriesSelection:S,setVisibleTimeRange:w}=_f(),{currentTime:b,setCurrentTime:E,startTimeSec:C,endTimeSec:A}=Mf(),T=M.useMemo(()=>[p,g],[p,g]),{margins:_,canvasWidth:x,canvasHeight:F}=i7({width:e,height:t,leftMargin:d,customToolbarActions:h,hideNavToolbar:m}),R=M.useMemo(()=>p===void 0||g===void 0?()=>0:g<=p?()=>0:O=>_.left+(O-p)/(g-p)*(x-_.left-_.right),[x,p,g,_]),z=M.useMemo(()=>p===void 0||g===void 0?()=>0:g<=p?()=>0:O=>p+(O-_.left)/(x-_.left-_.right)*(g-p),[x,p,g,_]),N=M.useMemo(()=>{const O=s?.yMin||0,$=s?.yMax||0;return $<=O?()=>0:V=>F-_.bottom-(V-O)/($-O)*(F-_.top-_.bottom)},[s,F,_]),U=VN(x,p,g,R),I=h7({datamin:s?.yMin||0,datamax:s?.yMax||0,pixelHeight:F-_.left-_.right}),L=M.useMemo(()=>({datamin:I.datamin,datamax:I.datamax,ticks:I.ticks.map(O=>({...O,pixelValue:N(O.dataValue)}))}),[I,N]),G=F,X=M.useMemo(()=>B.jsx(JN,{width:x,height:G,timeRange:T,margins:_,timeTicks:U,yTickSet:s?.showTicks?L:void 0,yLabel:s?.yLabel,gridlineOpts:r,hideTimeAxisLabels:D}),[x,G,T,_,U,s,L,D,r]),P=M.useMemo(()=>b!==void 0?R(b):void 0,[b,R]),j=M.useMemo(()=>B.jsx(t7,{width:x,height:G,timeRange:T,margins:_,currentTimePixels:P}),[x,G,T,_,P]),H=M.useRef(null),[k,q]=M.useState("pan"),{isViewClicked:Y,hoverTime:ee,selectionRect:te,handleMouseDown:ne,handleMouseUp:oe,handleMouseMove:W,handleMouseOut:ce}=r7({pixelToTime:z,visibleStartTimeSec:p,setCurrentTime:E,onMouseDown:a,onMouseUp:l,onMouseMove:o,onMouseOut:u,onCanvasClick:v,interactionMode:k});M.useEffect(()=>{(f===!1||Y)&&v7(H)},[f,Y]);const de=M.useCallback(O=>{if(c&&!O.shiftKey||O.deltaY===0||f!==!1&&!Y)return;const $=-O.deltaY/100;y($>0?"in":"out",1.2,ee)},[c,y,ee,f,Y]),ve=M.useCallback(O=>{O.key==="="?y("in"):O.key==="-"?y("out"):O.key==="ArrowRight"?S("forward"):O.key==="ArrowLeft"&&S("back"),i&&i(O)},[i,y,S]),De=M.useCallback(()=>{C!==void 0&&A!==void 0&&w(C,A)},[C,A,w]),Se=M.useMemo(()=>B.jsx(n7,{width:x,height:G,selectionRect:te}),[x,G,te]),[Ee,Re]=M.useState(null);M.useEffect(()=>{Ee&&n(Ee,x,F,_)},[Ee,x,F,_,n]);const Ce=M.useMemo(()=>B.jsxs("div",{style:{position:"relative",overflow:"hidden",width:x,height:G},onWheel:!f||Y?de:void 0,onMouseDown:ne,onMouseUp:oe,onMouseMove:W,onMouseOut:ce,tabIndex:0,onKeyDown:ve,children:[X,B.jsx("canvas",{style:{position:"absolute",width:x,height:G},ref:O=>Re(O),width:x,height:G}),j,Se]}),[x,G,ve,de,ne,oe,W,ce,f,Y,X,j,Se]),Ne=M.useMemo(()=>B.jsx(p7,{width:e,height:40,interactionMode:k,onInteractionModeChange:q,currentTime:b,onZoomToFit:De}),[e,k,q,b,De]),pe=M.useMemo(()=>B.jsx(g7,{width:e,height:40,customActions:h}),[e,h]);return B.jsxs("div",{className:"time-scroll-view-3",ref:H,style:{position:"absolute",width:e,height:t,background:"white"},children:[Ce,!m&&B.jsxs("div",{style:{position:"absolute",bottom:0,left:0,right:0},children:[Ne,pe]})]})},QS=15,y7={hideX:!1,hideY:!0},b7={showTicks:!1,yMin:void 0,yMax:void 0},D7=({dataClient:e,width:t,height:n})=>{const{visibleStartTimeSec:r,visibleEndTimeSec:i}=_f(),{initializeTimeseriesSelection:a}=Mf(),{selectedUnitIds:o,unitIdSelectionDispatch:u}=qr(),[l,s]=M.useState(void 0),c=M.useRef(null),[f,d]=M.useState(null),[h,v]=M.useState(null),[m,D]=M.useState(!1),[p,g]=M.useState(null),[y,S]=M.useState(null),w=M.useMemo(()=>r===void 0||i===void 0?"raster":i-r>120?"heatmap":"raster",[r,i]),b=e.metadata.unitIds;M.useEffect(()=>{e.metadata&&a({startTimeSec:e.metadata.startTimeSec,endTimeSec:e.metadata.endTimeSec,initialVisibleStartTimeSec:e.metadata.startTimeSec,initialVisibleEndTimeSec:e.metadata.endTimeSec})},[a,e.metadata]),M.useEffect(()=>{let H=!1;const k=async()=>{if(!(r===void 0||i===void 0))try{if(w==="raster"){const q=await e.getDataForRange({startTimeSec:r,endTimeSec:i});if(H)return;v(q),S(null)}else{const q=e.getSpikeCountsForRange({startTimeSec:r,endTimeSec:i});if(H)return;S(q),v(null)}g(null)}catch(q){if(H)return;console.error("Error loading data:",q),g(`Error loading data: ${q}`)}};return D(!0),k().finally(()=>{H||D(!1)}),()=>{H=!0}},[e,r,i,w]);const{onlyShowSelected:E,customToolbarActions:C}=GS(),[A,T]=M.useState(t),[_,x]=M.useState(n),[F,R]=M.useState(null),z=M.useMemo(()=>{const H=[];return E&&b.forEach((k,q)=>{o.has(k)&&H.push(q)}),H},[E,o,b]),N=M.useMemo(()=>z.map(H=>b[H]),[z,b]),U=M.useCallback(()=>{if(!F||!c.current||!f||!y||!e.metadata||r===void 0||i===void 0)return;if(f.clearRect(0,0,A,_),m&&(f.fillStyle="rgba(0, 0, 0, 0.02)",f.fillRect(0,0,A,_),f.fillStyle="black",f.font="16px Arial",f.textAlign="center",f.fillText("Loading...",A/2,_/2)),p){f.fillStyle="rgba(255, 0, 0, 0.1)",f.fillRect(0,0,A,_),f.fillStyle="red",f.font="14px Arial",f.textAlign="center",f.fillText(p,A/2,_/2);return}const k=_-F.top-F.bottom,q=A-F.left-F.right,Y=i-r;let ee;if(E){let oe=0;b.forEach((W,ce)=>{o.has(W)&&oe++}),ee=oe}else b.forEach((oe,W)=>{}),ee=b.length;const te=k/(ee||1);f.save(),f.beginPath(),f.rect(F.left,F.top,q,k),f.clip();let ne=1;if(y.counts.forEach(oe=>{E?z.forEach(W=>{const ce=oe[W];ce>ne&&(ne=ce)}):oe.forEach(W=>{W>ne&&(ne=W)})}),y.counts.forEach((oe,W)=>{const ce=y.binEdges[W],de=y.binEdges[W+1],ve=F.left+(ce-r)/Y*q,De=F.left+(de-r)/Y*q;if(E)for(let Se=0;Se<z.length;Se++){const Ee=z[Se],Ce=oe[Ee]/ne,Ne=F.top+(z.length-1-Se)*te,pe=KS(Ce);f.fillStyle=pe,f.fillRect(ve,Ne,De-ve+.5,te)}else oe.forEach((Se,Ee)=>{const Re=Se/ne,Ce=F.top+(b.length-1-Ee)*te,Ne=KS(Re);f.fillStyle=Ne,f.fillRect(ve,Ce,De-ve+.5,te)})}),f.restore(),te>=QS){f.globalAlpha=1;const oe=E?N:b;oe.forEach((W,ce)=>{const ve=F.top+(oe.length-1-ce)*te+te/2,De=mh(Ct(W));f.fillStyle=De,f.font="12px Arial",f.textAlign="right",f.fillText(`Unit ${W}`,F.left-5,ve)})}},[A,_,F,y,r,i,e.metadata,m,p,f,o,E,b,z,N]);console.log(o,z,N);const I=M.useCallback(()=>{if(!F||!c.current||!f||!h||!e.metadata||r===void 0||i===void 0)return;if(f.clearRect(0,0,A,_),m&&(f.fillStyle="rgba(0, 0, 0, 0.02)",f.fillRect(0,0,A,_),f.fillStyle="black",f.font="16px Arial",f.textAlign="center",f.fillText("Loading...",A/2,_/2)),p){f.fillStyle="rgba(255, 0, 0, 0.1)",f.fillRect(0,0,A,_),f.fillStyle="red",f.font="14px Arial",f.textAlign="center",f.fillText(p,A/2,_/2);return}const k=_-F.top-F.bottom,q=A-F.left-F.right,Y=i-r,ee=e.metadata.unitIds,te={};let ne;if(E){for(let W=0;W<z.length;W++){const ce=z[W];te[ce]=W}ne=z.length}else ee.forEach((W,ce)=>{te[ce]=ce}),ne=ee.length;const oe=k/(ne||1);f.save(),f.beginPath(),f.rect(F.left,F.top,q,k),f.clip();for(let W=0;W<h.timestamps.length;W++){const ce=h.timestamps[W],de=te[h.unitIndices[W]];if(de===void 0)continue;const ve=ee[h.unitIndices[W]],De=F.top+(ne-1-de)*oe+oe/2,Se=mh(Ct(ve)),Ee=l===ve,Re=o.has(ve);f.strokeStyle=Se,f.lineWidth=Ee||Re?2:1,f.globalAlpha=Re?1:Ee?.8:.6;const Ce=F.left+(ce-r)/Y*q;f.beginPath(),f.moveTo(Ce,De-oe*.4),f.lineTo(Ce,De+oe*.4),f.stroke()}if(f.restore(),oe>=QS){f.globalAlpha=1;const W=E?N:ee;W.forEach((ce,de)=>{const De=F.top+(W.length-1-de)*oe+oe/2,Se=mh(Ct(ce));f.fillStyle=Se,f.font="12px Arial",f.textAlign="right",f.fillText(`Unit ${ce}`,F.left-5,De)})}},[A,_,F,h,e.metadata,r,i,m,p,l,o,E,f,N,z]);M.useEffect(()=>{w==="heatmap"&&y?U():I()},[I,U,w,y]);const L=M.useCallback(()=>{},[]),G=M.useCallback(H=>{if(!F||!e.metadata)return;const k=e.metadata.unitIds,q=k.length,Y=1-(H.y-F.top)/(_-F.top-F.bottom),ee=Math.round(Y*q-.5);if(0<=ee&&ee<q)return k[ee]},[_,F,e.metadata]),X=M.useCallback(H=>{const k=H.currentTarget.getBoundingClientRect(),q={x:H.clientX-k.x,y:H.clientY-k.y},Y=G(q);H.shiftKey||H.ctrlKey?u({type:"TOGGLE_UNIT",targetUnit:Y}):u({type:"UNIQUE_SELECT",targetUnit:Y})},[G,u]),P=M.useCallback(H=>{const k=H.currentTarget.getBoundingClientRect(),q={x:H.clientX-k.x,y:H.clientY-k.y},Y=G(q);Y!==void 0&&s(Y)},[G]),j=M.useCallback(()=>{s(void 0)},[]);return e.metadata?B.jsx(ZS,{width:t,height:n,customToolbarActions:C,onCanvasElement:(H,k,q,Y)=>{c.current=H;const ee=H?.getContext("2d");d(ee),T(k),x(q),R(Y)},gridlineOpts:y7,onKeyDown:L,onMouseDown:X,onMouseMove:P,onMouseOut:j,yAxisInfo:b7}):B.jsx("div",{children:"Loading metadata..."})},KS=e=>{if(e===0)return"rgb(255,255,255)";const t=Math.max(0,Math.min(1,.7*(1-e))),n=Math.round(t*255);return`rgb(${n}, ${n}, ${n})`};class Pm{constructor(t,n,r,i,a,o){this.zarrGroup=t,this.metadata=n,this.referenceTimes=r,this.referenceIndices=i,this.counts2dArray=a,this.binEdges=o,this.zarrGroup=t}static async create(t){const n={startTimeSec:t.attrs.start_time_sec,endTimeSec:t.attrs.end_time_sec,unitIds:t.attrs.unit_ids||[],totalSpikes:t.attrs.total_spikes||0},r=await t.getDatasetData("reference_times",{}),i=await t.getDatasetData("reference_indices",{});if(!r||!i)throw new Error(`Reference arrays not found in Zarr group: ${t.path}`);const a=await t.getDatasetData("spike_counts_1sec",{}).catch(()=>{});if(!a)throw new Error(`Spike counts data not found in Zarr group: ${t.path}`);const o=Math.ceil(n.endTimeSec-n.startTimeSec),u=n.unitIds.length,l=Array(o);for(let f=0;f<o;f++){l[f]=Array(u);for(let d=0;d<u;d++){const h=f*u+d;l[f][d]=h<a.length?a[h]:0}}const s=Array(o+1);for(let f=0;f<=o;f++)s[f]=n.startTimeSec+f;return new Pm(t,n,r,i,l,s)}async getDataForRange(t){const n=this.findStartIndex(this.referenceTimes,this.referenceIndices,t.startTimeSec),r=this.findEndIndex(this.referenceTimes,this.referenceIndices,t.endTimeSec);if(n>=r)return{timestamps:[],unitIndices:[]};const i=await this.zarrGroup.getDatasetData("timestamps",{slice:[[n,r]]}),a=await this.zarrGroup.getDatasetData("unit_indices",{slice:[[n,r]]});return{timestamps:Array.from(i),unitIndices:Array.from(a)}}findStartIndex(t,n,r){let i=0;for(;i+1<t.length&&t[i+1]<r;)i++;return n[i]}getSpikeCountsForRange(t){const{startTimeSec:n,endTimeSec:r}=t,i=Math.floor(n-this.metadata.startTimeSec),a=Math.ceil(r-this.metadata.startTimeSec);let o=1;for(;(a-i)/o>500;)o+=1;const u=this.counts2dArray.slice(i,a),l=this.binEdges.slice(i,a+1);if(o===1)return{binEdges:l,counts:u};{const s=[],c=[];for(let f=0;f<u.length;f+=o){const d=Array(this.metadata.unitIds.length).fill(0);for(let h=0;h<o;h++)if(f+h<u.length)for(let v=0;v<d.length;v++)d[v]+=u[f+h][v];s.push(d),c.push(l[f])}return l.length>0&&c.push(l[Math.min(l.length-1,c.length*o)]),{binEdges:c,counts:s}}}findEndIndex(t,n,r){let i=t.length-1;for(;i-1>=0&&t[i-1]>r;)i--;return n[i]}}const S7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=x7(e);return i?B.jsx(WS,{context:t.timeseriesSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(D7,{dataClient:i,width:n,height:r})})}):null},WS=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?B.jsx(B.Fragment,{children:"Waiting for context..."}):B.jsx(VS.Provider,{value:{timeseriesSelection:n,dispatch:r},children:t})},x7=e=>{const[t,n]=M.useState(null);return M.useEffect(()=>{let r=!0;return Pm.create(e).then(i=>{r&&n(i)}),()=>{r=!1}},[e]),t},w7=({dataClient:e,width:t,height:n})=>{const{selectedUnitIds:r,unitIdSelectionDispatch:i}=qr(),{initializeTimeseriesSelection:a,visibleStartTimeSec:o,visibleEndTimeSec:u}=Mf(),[l,s]=M.useState(null),[c,f]=M.useState(null),[d,h]=M.useState(!1),[v,m]=M.useState(null),D=fl,{onlyShowSelected:p,customToolbarActions:g}=GS(),[y,S]=M.useState(t),[w,b]=M.useState(n),[E,C]=M.useState(null),A=e.metadata;M.useEffect(()=>{A&&i({type:oo,newUnitOrder:yr(A.unitIds)})},[A,i]),M.useEffect(()=>{A&&a({startTimeSec:A.startTimeSec,endTimeSec:A.endTimeSec,initialVisibleStartTimeSec:A.startTimeSec,initialVisibleEndTimeSec:A.endTimeSec})},[a,A]),M.useEffect(()=>{let x=!1;const F=async()=>{if(o!==void 0&&u!==void 0){let R=1e4;for(;;){const z=await e.getDataForRange({startTimeSec:o,endTimeSec:u},{maxNumEvents:R});if(x)return;if(z&&f(z),z.subsampleFactor>1){if(R===1e6)break;R=Math.max(R*3,z.timestamps.length*3),R>1e6&&(R=1e6)}else break}}};return h(!0),m(null),F().catch(R=>{x||m(`Failed to load data: ${R}`),m(`Failed to load data: ${R}`)}).finally(()=>{h(!1)}),()=>{x=!0}},[o,u,e]);const T=M.useMemo(()=>{if(!c||!A||c.amplitudes.length===0)return{yMin:0,yMax:10};let x=1/0,F=-1/0;for(let z=0;z<c.amplitudes.length;z++){const N=A.unitIds[c.unitIndices[z]];if(p?r.has(N):!0){const I=c.amplitudes[z];I<x&&(x=I),I>F&&(F=I)}}if(x===1/0)return{yMin:0,yMax:10};const R=(F-x)*.1;return{yMin:x-R,yMax:F+R}},[c,A,p,r]);M.useEffect(()=>{if(!l||!c||!A||!E||u===void 0||o===void 0)return;let x=!1;return(async()=>{if(x)return;if(l.clearRect(0,0,y,w),d&&(l.fillStyle="rgba(0, 0, 0, 0.1)",l.fillRect(0,0,y,w),l.fillStyle="black",l.font="16px Arial",l.textAlign="center",l.fillText("Loading...",y/2,w/2)),v){l.fillStyle="rgba(255, 0, 0, 0.1)",l.fillRect(0,0,y,w),l.fillStyle="red",l.font="14px Arial",l.textAlign="center",l.fillText(v,y/2,w/2);return}l.save(),l.beginPath(),l.rect(E.left,E.top,y-E.left-E.right,w-E.top-E.bottom),l.clip();const R=N=>E.left+(N-o)/(u-o)*(y-E.left-E.right),z=N=>w-E.bottom-(N-T.yMin)/(T.yMax-T.yMin)*(w-E.top-E.bottom);for(let N=0;N<c.timestamps.length;N++){const U=c.timestamps[N],I=c.amplitudes[N],L=A.unitIds[c.unitIndices[N]];if(U<o||U>u||!(p?r.has(L):!0))continue;const X=wr(Ct(L)),j=r.has(L)?1:.3;l.fillStyle=X,l.globalAlpha=j;const H=R(U),k=z(I);l.beginPath(),l.arc(H,k,2,0,Math.PI*2),l.fill()}l.globalAlpha=1,c.subsampleFactor>1&&(l.fillStyle="#2196F3",l.font="12px Arial",l.textAlign="left",l.fillText(`Subsampled ${c.subsampleFactor}x`,E.left+10,E.top+20)),l.restore()})(),()=>{x=!0}},[l,c,A,o,u,y,w,E,T,r,p,d,v]);const _=M.useMemo(()=>({showTicks:!0,yMin:T.yMin,yMax:T.yMax,yLabel:"Amplitude"}),[T]);return A?B.jsx("div",{children:B.jsxs(Ro,{width:t,height:n,initialPosition:D,adjustable:!1,children:[B.jsx(dl,{width:D,height:n}),B.jsx(ZS,{width:t-D,height:n,onCanvasElement:(x,F,R,z)=>{if(!x)return;const N=x.getContext("2d");s(N),S(F),b(R),C(z)},yAxisInfo:_,customToolbarActions:g})]})}):B.jsx("div",{children:"Loading metadata..."})};class Bf{constructor(t,n,r={},i,a){this.zarrGroup=t,this.metadata=n,this.subsampleClients=r,this.referenceTimes=i,this.referenceIndices=a,this.zarrGroup=t}static async create(t){const n={startTimeSec:t.attrs.start_time_sec,endTimeSec:t.attrs.end_time_sec,unitIds:t.attrs.unit_ids||[],totalSpikes:t.attrs.total_spikes||0},r={},i=t.subgroups.find(u=>u.name==="subsampled_data"),a=await t.getDatasetData("reference_times",{}),o=await t.getDatasetData("reference_indices",{});if(!a||!o)throw new Error(`Reference arrays not found in Zarr group: ${t.path}`);if(i){const u=await t.getGroup(i.name);if(!u)throw new Error(`Failed to load subsampled_data group at ${i.name} in ${t.path}`);let l=4;for(;;){const s=u.subgroups.find(d=>d.name===`factor_${l}`);if(!s)break;const c=await u.getGroup(s.name);if(!c)throw console.warn(u.subgroups),new Error(`Failed to load subsampled group at ${s.name} in ${t.path}`);const f=await Bf.create(c);r[l]=f,l*=4}}return new Bf(t,n,r,a,o)}async getDataForRange(t,n){const r=this.findStartIndex(this.referenceTimes,this.referenceIndices,t.startTimeSec),i=this.findEndIndex(this.referenceTimes,this.referenceIndices,t.endTimeSec);if(r>=i)return{timestamps:[],unitIndices:[],amplitudes:[],subsampleFactor:1};if(n.maxNumEvents>0&&i-r>n.maxNumEvents){let s=4;for(;s*4 in this.subsampleClients&&(i-r)/s>n.maxNumEvents;)s*=4;if(s in this.subsampleClients){const f=await this.subsampleClients[s].getDataForRange(t,{maxNumEvents:0});return f.subsampleFactor=s,f}}const a=await this.zarrGroup.getDatasetData("timestamps",{slice:[[r,i]]}),o=await this.zarrGroup.getDatasetData("unit_indices",{slice:[[r,i]]}),u=await this.zarrGroup.getDatasetData("amplitudes",{slice:[[r,i]]});return{timestamps:Array.from(a),unitIndices:Array.from(o),amplitudes:Array.from(u),subsampleFactor:1}}findStartIndex(t,n,r){let i=0;for(;i+1<t.length&&t[i+1]<r;)i++;return n[i]}findEndIndex(t,n,r){let i=t.length-1;for(;i-1>=0&&t[i-1]>r;)i--;return n[i]}}const E7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=A7(e);return i?B.jsx(WS,{context:t.timeseriesSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(w7,{dataClient:i,width:n,height:r})})}):null},A7=e=>{const[t,n]=M.useState(null);return M.useEffect(()=>{let r=!0;return Bf.create(e).then(i=>{r&&n(i)}),()=>{r=!1}},[e]),t},C7=25,qm=2*Math.PI,T7={maxElectrodePixelRadius:C7},Vm={},zo=8,M7=()=>({selectedElectrodeIds:[]}),_7=e=>{const{width:t,height:n,electrodes:r,units:i,disableAutoRotate:a,onlyShowSelected:o}=e,{selectedElectrodeIds:u}=M7(),{selectedUnitIds:l,unitIdSelectionDispatch:s}=qr(),{affineTransform:c,handleWheel:f}=Lm(t,n,{shift:!0,alt:!1}),d=M.useMemo(()=>new Set([...l]),[l]),h=i.filter(U=>o?d.has(U.unitId):!0).sort((U,I)=>d.has(U.unitId)&&!d.has(I.unitId)?1:!d.has(U.unitId)&&d.has(I.unitId)?-1:Ct(U.unitId)-Ct(I.unitId)),v=e.maxElectrodePixelRadius||T7.maxElectrodePixelRadius,m=e.colors??hl,D=e.showLabels??!1,p=e.offsetLabels??!1,{convertedElectrodes:g,pixelRadius:y,transform:S}=M.useMemo(()=>jm(t,n,r,"geom",v,{disableAutoRotate:a}),[r,n,v,t,a]),w=Math.sqrt(km(c)),b=M.useCallback((U,I)=>{const L=y*w,G=g.map(X=>{const P=(u||[]).includes(X.e.id),j=!1,H=!1,k=P?H?m.draggedSelected:j?m.selectedHover:m.selected:H?m.dragged:j?m.hover:m.base;return{...X,color:k,textColor:P||j&&!H?m.textDark:m.textLight}});if(U.clearRect(0,0,U.canvas.width,U.canvas.height),G.forEach(X=>{const P=ha(c,{x:X.pixelX,y:X.pixelY});U.fillStyle=X.color,U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.fill()}),U.strokeStyle=hl.border,g.forEach(X=>{const P=ha(c,{x:X.pixelX,y:X.pixelY});U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.stroke()}),D){U.font=`${L}px Arial`,U.textAlign=p?"right":"center",U.textBaseline="middle";const X=p?1.4*L:0;G.forEach(P=>{const j=ha(c,{x:P.pixelX,y:P.pixelY});U.fillStyle=p?m.textDark:P.textColor,U.fillText(`${P.e.label}`,j.x-X,j.y)})}},[m,p,g,y,u,D,c,w]),E=M.useCallback((U,I)=>{const L=zo;U.clearRect(0,0,U.canvas.width,U.canvas.height);const G=(X,P,j)=>{U.fillStyle=j,U.strokeStyle="black",U.beginPath(),U.ellipse(X,P,L,L,0,0,qm),U.fill(),U.stroke()};for(const X of h){const P=Xh(S,[X.x,X.y]),j=ha(c,{x:P[0],y:P[1]}),H=l.size===0||l.has(X.unitId)?wr(Ct(X.unitId)):"rgb(220, 220, 220)";G(j.x,j.y,H)}},[S,h,l,c]),C=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:b,drawData:Vm}),[t,n,b]),A=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:E,drawData:Vm}),[t,n,E]),T=M.useCallback((U,{ctrlKey:I})=>{const L=B7(c,U),G=km(c),X=zo/Math.sqrt(G),P=[];for(const j of h){const H=Xh(S,[j.x,j.y]);Yh(Ff([H[0]-X,H[1]-X,X*2,X*2]),Ff(L))&&(Ff([H[0]-X,H[1]-X,X*2,X*2]),P.push(j.unitId))}if(I)for(const j of P)s({type:"TOGGLE_UNIT",targetUnit:j});else s({type:"SET_SELECTION",incomingSelectedUnitIds:P})},[S,s,h,c]),_=M.useCallback((U,{ctrlKey:I})=>{let L=!1;for(const G of h){const X=Xh(S,[G.x,G.y]);J5(U,Ff([X[0]-zo,X[1]-zo,zo*2,zo*2]))&&(L=!0,s(I?{type:"TOGGLE_UNIT",targetUnit:G.unitId}:{type:"SET_SELECTION",incomingSelectedUnitIds:[G.unitId]}))}L||s({type:"SET_SELECTION",incomingSelectedUnitIds:[]})},[S,s,h]),{onMouseMove:x,onMouseDown:F,onMouseUp:R,paintDragSelectLayer:z}=Hs(t,n,T,_),N=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:z,drawData:Vm}),[t,n,z]);return t>0&&n>0?B.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:x,onMouseUp:R,onMouseDown:F,onWheel:f,children:[C,A,N]}):B.jsx("div",{})},Ff=e=>({xmin:e[0],ymin:e[1],xmax:e[0]+e[2],ymax:e[1]+e[3]}),B7=(e,t)=>{const n=$m(e,{x:t[0],y:t[1]}),r=$m(e,{x:t[0]+t[2],y:t[1]+t[3]});return[n.x,n.y,r.x-n.x,r.y-n.y]},F7=e=>{const{data:t,width:n,height:r}=e,[i,a]=M.useState({...xf,onlyShowSelected:!1}),o=30,u=Object.keys(t.channelLocations),l=mN(u,t.channelLocations),s=M.useMemo(()=>({width:n-20,height:r-o,top:0,position:"absolute"}),[n,r]);return B.jsxs("div",{children:[B.jsx("div",{style:s,children:B.jsx(_7,{width:n-20,height:r-o,electrodes:l,units:t.units,disableAutoRotate:t.disableAutoRotate,onlyShowSelected:i.onlyShowSelected})}),B.jsx("div",{style:{position:"absolute",top:r-o,height:o,overflow:"hidden"},children:B.jsx(wf,{options:i,setOptions:a})})]})},N7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.disable_auto_rotate||!1,h=e.attrs.unit_ids,v=e.attrs.channel_locations,m=await e.getDatasetData("coords",{});if(!m||m.length===0)throw new Error("Empty coords data");const D=new Float32Array(m);if(D.length!==h.length*2)throw new Error(`Expected coords length ${h.length*2}, got ${D.length}`);const p=[];for(let g=0;g<h.length;g++)p.push({unitId:h[g],x:D[g*2],y:D[g*2+1]});if(c)return;a({type:"UnitLocations",channelLocations:v,units:p,disableAutoRotate:d})}catch(d){console.error("Error loading unit locations data:",d),u(`Failed to load unit locations data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit locations data..."}):i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx(F7,{data:i,width:n,height:r})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit locations data available"})},R7=({rows:e,columns:t,onDeleteRow:n=void 0,deleteRowLabel:r=void 0,onEditRow:i=void 0,editRowLabel:a=void 0,selectionMode:o="none",selectedRowKeys:u=[],onSelectedRowKeysChanged:l=void 0,selectionDisabled:s})=>{const c=M.useMemo(()=>{const p={};return u.forEach(g=>{p[g]=!0}),p},[u]),[f,d]=M.useState(null),h=M.useCallback(p=>{l&&(o==="single"?!(p in c)||!c[p]?l([p+""]):l([]):o==="multiple"&&l(Object.keys(c).filter(g=>g!=p&&c[g]).concat(c[p]?[]:[p.toString()])))},[l,o,c]),v=M.useCallback(p=>{d(p)},[]),m=M.useCallback((p,g)=>{g&&n&&n(p),d(null)},[n]),D=M.useCallback(p=>{i&&i(p)},[i]);return B.jsxs(mF,{className:"NiceTable",children:[B.jsx(MF,{children:B.jsxs(SS,{children:[B.jsx(Sf,{style:{width:0}},"_first"),t.map(p=>B.jsx(Sf,{children:p.element?p.element:B.jsx("span",{children:p.label})},p.key))]})}),B.jsx(bF,{children:e.map(p=>B.jsxs(SS,{children:[B.jsxs(Sf,{children:[n&&(f===p.key?B.jsx(z7,{title:r||"",onConfirmDeleteRow:m,rowKey:p.key}):B.jsx(O7,{title:r||"",onDeleteRow:v,rowKey:p.key})),i&&B.jsx(U7,{title:a||"",onEditRow:D,rowKey:p.key}),o!=="none"&&B.jsx(hS,{checked:c[p.key]||!1,onClick:()=>h(p.key),disabled:s})]}),t.map(g=>B.jsx(Sf,{children:B.jsx("span",{children:I7(p.columnValues[g.key])})},g.key))]},p.key))})]})},O7=({title:e,rowKey:t,onDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t)},[n,t]);return B.jsx(cl,{title:e,onClick:r,children:B.jsx(YD,{})})},z7=({title:e,rowKey:t,onConfirmDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t,!0)},[n,t]),i=M.useCallback(()=>{n&&n(t,!1)},[n,t]);return B.jsxs("span",{children:["Confirm delete?",B.jsx(cl,{title:e,onClick:r,children:B.jsx(YD,{})}),B.jsx(cl,{title:"Cancel",onClick:i,children:B.jsx(B_,{})})]})},U7=({title:e,rowKey:t,onEditRow:n})=>B.jsx(cl,{title:e,onClick:()=>n&&n(t),children:B.jsx(__,{})}),I7=e=>e==0?e:e?typeof e=="object"?e.element?e.element:e.text||"":e:"",$7=({width:e,height:t})=>{const{selectedUnitMetrics:n,allUnitMetrics:r,unitMetricSelectionDispatch:i}=ch(),a=M.useMemo(()=>[{key:"metric",label:"Metric"}],[]),o=M.useMemo(()=>(r||[]).map(l=>({key:l,columnValues:{metric:l}})),[r]),u=M.useCallback(l=>{i({type:"selectUnitMetrics",unitMetrics:l})},[i]);return B.jsx("div",{style:{position:"absolute",width:e,height:t},children:B.jsx(R7,{rows:o,columns:a,selectedRowKeys:n,onSelectedRowKeysChanged:u,selectionMode:"multiple"})})},k7=(e,t)=>{e.clearRect(0,0,t.width,t.height);for(const n of t.pixelVerticalLines||[])e.strokeStyle=n.color,e.beginPath(),e.moveTo(n.x,t.margins.top-20),e.lineTo(n.x,t.height-t.margins.bottom),e.stroke();t.barBoxes.forEach(n=>{e.fillStyle=n.color,e.fillRect(n.x1,n.y1,n.x2-n.x1,n.y2-n.y1)}),t.xLabel&&(e.textBaseline="bottom",e.textAlign="center",e.fillStyle="black",e.fillText(t.xLabel,t.width/2,t.height-3));for(const n of t.pixelTicks||[])e.strokeStyle="black",e.beginPath(),e.moveTo(n.x,t.height-t.margins.bottom),e.lineTo(n.x,t.height-t.margins.bottom+6),e.stroke(),e.textBaseline="top",e.textAlign="center",e.fillStyle="black",e.fillText(n.label,n.x,t.height-t.margins.bottom+8)},L7=e=>B.jsx(ir,{width:e.width,height:e.height,draw:k7,drawData:e}),j7={},H7=({bars:e,range:t,ticks:n,verticalLines:r,xLabel:i,onSelectRect:a,width:o,height:u})=>{const{xMin:l,xMax:s}=M.useMemo(()=>t?{xMin:t.min,xMax:t.max}:e.length>0?{xMin:e[0].xStart,xMax:e[e.length-1].xEnd}:{xMin:0,xMax:1},[e,t]),c=M.useMemo(()=>Math.max(...e.map(E=>E.height)),[e]),{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v}=M.useMemo(()=>{const E={left:3,right:3,top:5,bottom:3+(i?18:0)+(n?18:0)},C=o-E.left-E.right,A=u-E.top-E.bottom,T=e.map(F=>({key:F.key,x1:E.left+(F.xStart-l)/(s-l)*C,x2:E.left+(F.xEnd-l)/(s-l)*C,y1:E.top+A*(1-F.height/c),y2:E.top+A,tooltip:F.tooltip,color:F.color})),_=n?n.map(F=>({x:E.left+(F.x-l)/(s-l)*C,label:`${F.label}`})):void 0,x=r?r.map(F=>({x:E.left+(F.x-l)/(s-l)*C,color:F.color})):void 0;return{barBoxes:T,margins:E,pixelTicks:_,pixelVerticalLines:x}},[e,n,r,l,s,c,o,u,i]),m=M.useCallback((E,{ctrlKey:C,shiftKey:A})=>{const T=[],_={x:E[0],y:E[1],width:E[2],height:E[3]};for(const z of f)z.x1<=_.x+_.width&&z.x2>=_.x&&T.push(z.key);const x=o-d.left-d.right,F=(_.x-d.left)/x*(s-l)+l,R=(_.x+_.width-d.left)/x*(s-l)+l;a&&a(_,T,{ctrlKey:C,shiftKey:A,xMin:F,xMax:R})},[f,a,d.left,d.right,o,l,s]),D=M.useCallback(()=>{},[]),{onMouseMove:p,onMouseDown:g,onMouseUp:y,onMouseLeave:S,paintDragSelectLayer:w}=Hs(o,u,m,D),b=M.useMemo(()=>B.jsx(ir,{width:o,height:u,draw:w,drawData:j7}),[o,u,w]);return B.jsxs("div",{style:{width:o,height:u,position:"relative"},onMouseDown:g,onMouseMove:p,onMouseUp:y,onMouseLeave:S,children:[B.jsx(L7,{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v,xLabel:i,width:o,height:u}),b]})},P7=(e,t)=>{const n=t-e;let r;n<=30?r=10:n<=120?r=20:n<=300?r=50:n<=600?r=100:n<=1e3?r=150:r=100;const i=[];let a=Math.ceil(e/r);for(;a*r<=t;)i.push(a*r),a++;return i},q7=({metric:e,metricRange:t,units:n,selectedUnitIds:r,setSelectedUnitIds:i,numBins:a,onZoomToRect:o,width:u,height:l})=>{const{bars:s,ticks:c,verticalLines:f}=M.useMemo(()=>{const h=n.map(p=>p.values[e.key]).filter(p=>p!==void 0).map(p=>p),v=n.filter(p=>r.has(p.unitId)).map(p=>p.values[e.key]).filter(p=>p!==void 0).map(p=>p),D=n.filter(p=>r.has(p.unitId)).map(p=>({unitId:p.unitId,value:p.values[e.key]})).filter(p=>p.value!==void 0).map(p=>p.unitId).map(p=>wr(Ct(p)));return V7(h,v,D,a||10)},[n,e,r,a]),d=M.useCallback((h,v,{ctrlKey:m,shiftKey:D,xMin:p,xMax:g})=>{if(D){o&&o({x:p,y:h.y,width:g-p,height:h.height});return}if(v.length===0)return;const y=[];for(const E of v){const C=s[E];y.push(C)}const S=Math.min(...y.map(E=>E.xStart)),w=Math.max(...y.map(E=>E.xEnd)),b=[];for(const E of n){const C=E.values[e.key];C!==void 0&&S<=C&&C<=w&&b.push(E.unitId)}i(m||D?[...new Set([...r,...b])]:b)},[s,e,r,i,n,o]);return B.jsx(H7,{width:u,height:l,bars:s,range:t,ticks:c,verticalLines:f,onSelectRect:d})},V7=(e,t,n,r)=>{if(e.length===0)return{bars:[],ticks:[],verticalLines:[]};let i=Math.min(...e),a=Math.max(...e);if(a<=i)return{bars:[],ticks:[],verticalLines:[]};i-=(a-i)/r/2,a+=(a-i)/r/2;const o=[];for(let f=0;f<r;f++)o.push(0);for(const f of e){const d=Math.min(Math.floor((f-i)/(a-i)*r),r-1);o[d]++}const u=[];for(let f=0;f<r;f++)u.push(0);for(const f of t){const d=Math.min(Math.floor((f-i)/(a-i)*r),r-1);u[d]++}const l=[];t.forEach((f,d)=>{l.push({x:f,color:n[d]})});const c=G7(i,a).map(f=>({x:f,label:`${f}`}));return{bars:[...o.map((f,d)=>({key:d,xStart:i+d*(a-i)/r,xEnd:i+(d+1)*(a-i)/r,height:f,tooltip:"",color:"gray"}))],ticks:c,verticalLines:l}},G7=(e,t)=>{const n=t-e;if(n<=0)return[];let r=1;for(;n*r<100;)r*=10;for(;n*r>=1e3;)r/=10;return P7(e*r,t*r).map(i=>i/r)},Y7=(e,t)=>{e.clearRect(0,0,t.width,t.height),t.markers.forEach(n=>{const r=t.coord2Pixel({x:n.x,y:n.y});e.fillStyle=n.color,e.strokeStyle="black",e.beginPath(),e.ellipse(r.x,r.y,n.radius,n.radius,0,0,2*Math.PI),e.fill(),e.stroke()})},X7=e=>B.jsx(ir,{width:e.width,height:e.height,draw:Y7,drawData:e}),Z7={},Q7=({markers:e,xRange:t,yRange:n,onSelectRect:r,onClickPoint:i,width:a,height:o})=>{const{margins:u}=M.useMemo(()=>({margins:{left:20,right:20,top:20,bottom:20}}),[]),{xMin:l,xMax:s,yMin:c,yMax:f}=M.useMemo(()=>{let b,E,C,A;return t?(b=t.min,E=t.max):e.length>0?(b=Math.min(...e.map(T=>T.x)),E=Math.max(...e.map(T=>T.x))):(b=0,E=1),n?(C=n.min,A=n.max):e.length>0?(C=Math.min(...e.map(T=>T.y)),A=Math.max(...e.map(T=>T.y))):(C=0,A=1),{xMin:b,xMax:E,yMin:C,yMax:A}},[e,t,n]),{coord2Pixel:d,pixel2Coord:h}=M.useMemo(()=>{const b=a-u.left-u.right,E=o-u.top-u.bottom;return{coord2Pixel:T=>({x:u.left+(T.x-l)/(s-l)*b,y:u.top+(1-(T.y-c)/(f-c))*E}),pixel2Coord:T=>({x:l+(T.x-u.left)/b*(s-l),y:c+(1-(T.y-u.top)/E)*(f-c)})}},[a,o,u,l,s,c,f]),v=M.useCallback((b,{ctrlKey:E,shiftKey:C})=>{const A={x:b[0],y:b[1],width:b[2],height:b[3]},T=[];for(const x of e){const F=d({x:x.x,y:x.y}),R={xmin:F.x-x.radius,ymin:F.y-x.radius,xmax:F.x+x.radius,ymax:F.y+x.radius};Yh({xmin:A.x,xmax:A.x+A.width,ymin:A.y,ymax:A.y+A.height},R)&&T.push(x.key)}const _=K7(h,A);r&&r(_,T,{ctrlKey:E,shiftKey:C})},[r,h,e,d]),m=M.useCallback((b,{ctrlKey:E,shiftKey:C})=>{const A={x:b[0],y:b[1]},T={x:A.x,y:A.y,width:1,height:1};let _;for(const x of e){const F=d({x:x.x,y:x.y}),R={xmin:F.x-x.radius,ymin:F.y-x.radius,xmax:F.x+x.radius,ymax:F.y+x.radius};Yh({xmin:T.x,xmax:T.x+T.width,ymin:T.y,ymax:T.y+T.height},R)&&(_=x.key)}i&&i(h(A),_,{ctrlKey:E,shiftKey:C})},[d,e,i,h]),{onMouseMove:D,onMouseDown:p,onMouseUp:g,onMouseLeave:y,paintDragSelectLayer:S}=Hs(a,o,v,m),w=M.useMemo(()=>B.jsx(ir,{width:a,height:o,draw:S,drawData:Z7}),[a,o,S]);return B.jsxs("div",{style:{width:a,height:o,position:"relative"},onMouseDown:p,onMouseMove:D,onMouseUp:g,onMouseLeave:y,children:[B.jsx(X7,{markers:e,margins:u,coord2Pixel:d,width:a,height:o}),w]})},K7=(e,t)=>{const n=e({x:t.x,y:t.y}),r=e({x:t.x+t.width,y:t.y+t.height});return{x:Math.min(n.x,r.x),y:Math.min(n.y,r.y),width:Math.abs(r.x-n.x),height:Math.abs(r.y-n.y)}},W7=({metric1:e,metric2:t,metric1Range:n,metric2Range:r,units:i,selectedUnitIds:a,setSelectedUnitIds:o,onZoomToRect:u,width:l,height:s})=>{const f=M.useMemo(()=>{const v=[];for(const m of i){const D=m.values[e.key],p=m.values[t.key];D!==void 0&&p!==void 0&&v.push({key:m.unitId,x:D,y:p,color:a.has(m.unitId)?wr(Ct(m.unitId)):"lightgray",radius:6,tooltip:`Unit ${m.unitId}`})}return v},[i,e,t,a]),d=M.useCallback((v,m,{ctrlKey:D,shiftKey:p})=>{if(p){u&&u(v);return}let g=m;D&&(g=[...new Set([...m,...a])]),o(g)},[o,a,u]),h=M.useCallback((v,m,{ctrlKey:D,shiftKey:p})=>{let g;if(D||p){const y=new Set([...a]);m!==void 0&&(y.has(m)?y.delete(m):y.add(m)),g=[...y]}else m===void 0?g=[]:g=[m];o(g)},[o,a]);return B.jsx(Q7,{width:l,height:s,markers:f,xRange:n,yRange:r,onSelectRect:d,onClickPoint:h})},J7=({type:e,metric1:t,metric2:n,metric1Range:r,metric2Range:i,units:a,selectedUnitIds:o,setSelectedUnitIds:u,numHistogramBins:l,onZoomToRect:s,width:c,height:f})=>{if(e==="histogram"){if(!t)throw Error("Unexpected: metric1 not defined");return B.jsx(q7,{metric:t,metricRange:r,units:a,selectedUnitIds:o,setSelectedUnitIds:u,numBins:l,onZoomToRect:s,width:c,height:f})}else if(e==="scatter"){if(!t)throw Error("Unexpected: metric1 not defined");if(!n)throw Error("Unexpected: metric2 not defined");return B.jsx(W7,{metric1:t,metric2:n,metric1Range:r,metric2Range:i,units:a,selectedUnitIds:o,setSelectedUnitIds:u,onZoomToRect:s,width:c,height:f})}else{if(e==="bottom-label")return B.jsx("div",{style:{width:c,textAlign:"center"},children:t?.label||B.jsx("span",{children:" "})});if(e==="left-label")return B.jsx("div",{style:{width:c,height:f,overflow:"hidden",writingMode:"vertical-lr",transform:"rotate(-180deg)",textAlign:"center"},children:t?.label||B.jsx("span",{children:" "})});throw Error(`Unexpected type: ${e}`)}},eR=({data:e,width:t,height:n})=>{const{units:r,metrics:i}=e,{selectedUnitIds:a,unitIdSelectionDispatch:o}=qr(),{selectedUnitMetrics:u}=ch(),[l,s]=M.useState(1),[c,f]=M.useState(10),[d,h]=M.useState({}),v=M.useMemo(()=>r.sort((g,y)=>a.has(g.unitId)&&!a.has(y.unitId)?1:!a.has(g.unitId)&&a.has(y.unitId)?-1:Ct(g.unitId)-Ct(y.unitId)),[r,a]);M.useEffect(()=>{o({type:oo,newUnitOrder:yr(v.map(g=>g.unitId))})},[v,o]);const m=M.useMemo(()=>{const g=u.length===0?[{type:"text",content:"Box size",title:"Set box size"},{type:"button",callback:()=>s(w=>w*1.3),title:"Increase box size",icon:B.jsx(Tc,{})},{type:"button",callback:()=>s(w=>w/1.3),title:"Decrease box size",icon:B.jsx(Cc,{})}]:[],y=[{type:"text",content:"# bins",title:""},{type:"button",callback:()=>f(w=>w+5),title:"Increase num. histogram bins",icon:B.jsx(Tc,{})},{type:"button",callback:()=>f(w=>Math.max(5,w-5)),title:"Decrease num. histogram bins",icon:B.jsx(Cc,{})}],S={type:"button",callback:()=>h({}),title:"Reset zoom",text:"reset"};return[...g,{type:"divider"},...y,{type:"divider"},S]},[u.length]),D=fl,p=M.useMemo(()=>{const g=y=>{o({type:"SET_SELECTION",incomingSelectedUnitIds:y})};if(u.length===0)return i.map(y=>{const S={type:"histogram",metric1:y,metric2:y,metric1Range:d[y.key],metric2Range:d[y.key],units:v,width:400*l,height:400*l,numHistogramBins:c,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:b=>{h({...d,[y.key]:{min:b.x,max:b.x+b.width}})}};return{key:y.key,label:y.label,unitId:"",labelColor:"black",props:S}});{const{plotWidth:w,plotHeight:b}=PS(t-D-30-10,n-30-10,u.length),E=[];for(const C of u){const A=i.filter(T=>T.key===C)[0];{const T={type:"left-label",metric1:A,metric2:A,units:v,numHistogramBins:c,width:30,height:b,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`left-label-${C}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}for(const T of u){const _=i.filter(x=>x.key===T)[0];if(A&&_){const x={type:C===T?"histogram":"scatter",metric1:_,metric2:A,metric1Range:d[_.key],metric2Range:d[A.key],units:v,numHistogramBins:c,width:w,height:b,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:F=>{h(C!==T?{...d,[_.key]:{min:F.x,max:F.x+F.width},[A.key]:{min:F.y,max:F.y+F.height}}:{...d,[A.key]:{min:F.x,max:F.x+F.width}})}};E.push({key:`${T}-${C}`,label:x.type==="histogram"?C:void 0,unitId:"",labelColor:"black",props:x})}}}{const C={type:"bottom-label",metric1:void 0,metric2:void 0,units:v,numHistogramBins:c,width:30,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:"left-bottom-label",label:void 0,unitId:"",labelColor:"black",props:C,hideBorderColor:!0})}for(const C of u){const A=i.filter(_=>_.key===C)[0],T={type:"bottom-label",metric1:A,metric2:A,units:v,numHistogramBins:c,width:w,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`bottom-label-${C}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}return E}},[i,a,v,l,u,c,t,n,o,d,D]);return B.jsxs(Ro,{width:t,height:n,initialPosition:D,adjustable:!1,children:[B.jsx(dl,{width:D,height:n,customActions:m}),B.jsx(wc,{width:0,height:0,disableScroll:u.length>0,children:B.jsx(xc,{plots:p,plotComponent:J7,numPlotsPerRow:u.length===0?void 0:u.length+1})})]})},tR=({data:e,width:t,height:n})=>{const{metrics:r}=e,{unitMetricSelectionDispatch:i}=ch();return M.useEffect(()=>{i({type:"initialize",unitMetrics:r.map(a=>a.key)})},[r,i]),B.jsxs(Ro,{width:t,height:n,initialPosition:200,adjustable:!0,children:[B.jsx($7,{width:0,height:0}),B.jsx(eR,{data:e,width:0,height:0})]})},nR=e=>js(e,{key:Ls,label:Ls,dtype:Ls}),rR=e=>js(e,{unitId:OA([RA,Ls]),values:()=>!0}),iR=e=>js(e,{type:zA("UnitMetricsGraph"),metrics:Cy(nR),units:Cy(rR)}),aR=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.metrics||[],h=await e.getDatasetData("units_data",{});if(!h||h.length===0)throw new Error("Empty units data");const v=new Uint8Array(h),m=new TextDecoder("utf-8").decode(v),D=JSON.parse(m);if(c)return;const p={type:"UnitMetricsGraph",metrics:d,units:D.map(g=>({unitId:g.unit_id,values:g.values}))};if(!iR(p))throw new Error("Invalid view data structure");a(p)}catch(d){console.error("Error loading unit metrics graph data:",d),u(`Failed to load unit metrics graph data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit metrics data..."}):i?B.jsx(oR,{context:t.unitMetricSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(tR,{data:i,width:n,height:r})})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit metrics data available"})},oR=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?B.jsx(B.Fragment,{children:"Waiting for unit metric selection context..."}):B.jsx(hy.Provider,{value:{unitMetricSelection:n,unitMetricSelectionDispatch:r},children:t})},JS=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=eA(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:JS}},ex=()=>{const e={current:Sy},t=[];return{stateRef:e,dispatch:i=>{e.current=TA(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:ex}},tx=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=Af(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:tx}},uR=({zarrGroup:e,width:t,height:n,onResize:r,onDataChange:i,contexts:a,component:o})=>{const[u,l]=M.useState(t),[s,c]=M.useState(n),[f,d]=M.useState(e);return M.useEffect(()=>{r((h,v)=>{l(h),c(v)}),i(h=>{d(h)})},[r,i]),B.jsx(o,{zarrGroup:f,width:u,height:s,contexts:a})},lR=e=>t=>{const{container:n,zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l}=t;JE.createRoot(n).render(B.jsx(uR,{zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l,component:e}))};(()=>{const e=[{name:"spike_sorting.Autocorrelograms",component:YF},{name:"spike_sorting.AverageWaveforms",component:UN},{name:"spike_sorting.CrossCorrelograms",component:kN},{name:"spike_sorting.RasterPlot",component:S7},{name:"spike_sorting.SpikeAmplitudes",component:E7},{name:"spike_sorting.UnitLocations",component:N7},{name:"spike_sorting.UnitMetricsGraph",component:aR},{name:"spike_sorting.UnitsTable",component:iN},{name:"spike_sorting.SortingCuration",component:nN}],t=window.figpack_p1.registerFPViewComponent;for(const i of e)t({name:i.name,render:lR(i.component)});const n=window.figpack_p1.registerFPViewContextCreator;n({name:"unitSelection",create:ex}),n({name:"unitMetricSelection",create:JS}),n({name:"sortingCuration",create:tx});const r=window.figpack_p1.registerFPExtension;r({name:"figpack-spike-sorting"})})()})();
191
+ Action: ${t.type}`),t.type==="SET_CURATION")return t.curation;if(t.type==="CLOSE_CURATION")return{...e,isClosed:!0};if(t.type==="REOPEN_CURATION")return{...e,isClosed:!1};if(t.type==="ADD_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId],r={...e.labelsByUnit||{}};let i=!1;for(const a of n){const o=r[a+""]||[];o.includes(t.label)||(i=!0,r[a+""]=[...o,t.label].sort())}return i?{...e,labelsByUnit:r}:e}else if(t.type==="TOGGLE_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId];let r=!0;for(const i of n)((e.labelsByUnit||{})[i+""]||[]).includes(t.label)||(r=!1);return r?Af(e,{type:"REMOVE_UNIT_LABEL",unitId:t.unitId,label:t.label}):Af(e,{type:"ADD_UNIT_LABEL",unitId:t.unitId,label:t.label})}else if(t.type==="REMOVE_UNIT_LABEL"){const n=typeof t.unitId=="object"?t.unitId:[t.unitId],r={...e.labelsByUnit||{}};let i=!1;for(const a of n){const o=r[a+""]||[];o.includes(t.label)&&(i=!0,r[a+""]=o.filter(u=>u!==t.label))}return i?{...e,labelsByUnit:r}:e}else{if(t.type==="MERGE_UNITS")return{...e,mergeGroups:AS([...e.mergeGroups||[],t.unitIds])};if(t.type==="UNMERGE_UNITS")return{...e,mergeGroups:AS((e.mergeGroups||[]).map(n=>n.filter(r=>!t.unitIds.includes(r))))};if(t.type==="SET_LABEL_CHOICES")return{...e,labelChoices:t.labelChoices}}return e},WF={sortingCuration:KF,sortingCurationDispatch:e=>{console.warn("No sortingCurationDispatch function provided.")},curating:!1},wS=Nt.createContext(WF),ES=()=>{const e=M.useContext(wS);if(!e)throw Error("useSortingCuration must be used within a SortingCurationContext.Provider");return e},JF=(e,t)=>e.filter(n=>t.includes(n)),eN=(e,t)=>[...e,...t.filter(n=>!e.includes(n))].sort(),AS=e=>{const t=e.map(r=>[...r]);let n=!0;for(;n;){n=!1;for(let r=0;r<t.length;r++){const i=t[r];for(let a=r+1;a<t.length;a++){const o=t[a];JF(i,o).length>0&&(t[r]=eN(i,o),t[a]=[],n=!0)}}}return t.filter(r=>r.length>=2)},CS=({data:e,width:t,height:n})=>{const[r,i]=M.useState({...xf,onlyShowSelected:!1}),{selectedUnitIds:a,currentUnitId:o,orderedUnitIds:u,visibleUnitIds:l,primarySortRule:s,checkboxClickHandlerGenerator:c,unitIdSelectionDispatch:f}=qr(),{sortingCuration:d}=ES(),h=M.useMemo(()=>r.onlyShowSelected?l?l.filter(w=>a.has(w)):[...a]:l,[l,a,r.onlyShowSelected]),v=M.useMemo(()=>{const w=[];return w.push({columnName:"_unitId",label:"Unit",tooltip:"Unit ID",sort:(b,E)=>Ct(b)-Ct(E),dataElement:b=>B.jsx(XF,{unitId:b.unitId,mergeGroup:b.mergeGroup}),calculating:!1}),d&&w.push({columnName:"_labels",label:"Labels",tooltip:"Curation labels",sort:(b,E)=>b<E?-1:b>E?1:0,dataElement:b=>B.jsx("span",{children:b.join(", ")}),calculating:!1}),e.similarityScores&&w.push({columnName:"_similarity",label:"Similarity",tooltip:"Similarity with current unit",sort:(b,E)=>{if(b.unitId===o)return 1;if(E.unitId===o)return-1;const C=b.score,A=E.score;return C===void 0&&A!==void 0?-1:C!==void 0&&A===void 0?1:C===void 0&&A===void 0?0:C!==void 0&&A!==void 0?C<A?-1:C>A?1:0:0},dataElement:b=>B.jsx("span",{children:b}),calculating:!1,onlyAllowDescendingSort:!0}),e.columns.filter(b=>b.key!=="unitId").forEach(b=>{w.push({columnName:b.key,label:b.label,tooltip:b.label,sort:b.dtype==="str"?(E,C)=>E<C?-1:E>C?1:0:b.dtype==="int"?(E,C)=>E-C:b.dtype=="bool"?(E,C)=>(E?1:0)-(C?1:0):b.dtype==="float"?(E,C)=>E-C:(E,C)=>E-C,dataElement:E=>B.jsx("span",{children:E}),calculating:!1})}),w},[e.columns,o,d,e.similarityScores]),m=M.useMemo(()=>{for(let b=0;b<0;b++)u.push("never-added");const w={};if(e.similarityScores&&o!==void 0)for(const b of e.similarityScores)b.unitId1===o?w[b.unitId2]=b.similarity:b.unitId2===o&&(w[b.unitId1]=b.similarity);return e.rows.map(b=>{const E=(d?.labelsByUnit||{})[`${b.unitId}`]||[],C={value:{unitId:b.unitId,mergeGroup:ZF(b.unitId,d)},sortValue:b.unitId},A=w[b.unitId],T={_unitId:C,_labels:{value:E,sortValue:E.join(", ")},_similarity:{value:A!==void 0?A.toFixed(3):void 0,sortValue:{unitId:b.unitId,score:A}}};for(const _ of e.columns){const x=`${b.values[_.key]!==void 0?b.values[_.key]:""}`;T[_.key]={value:x,sortValue:b.values[_.key]}}return{rowId:b.unitId,data:T,checkboxFn:c(b.unitId)}})},[e.rows,e.columns,o,e.similarityScores,d,c,u]);M.useEffect(()=>{f({type:oo,newUnitOrder:yr(m.map(w=>w.rowId))})},[m,f]);const D=M.useMemo(()=>{const w=new Map;return m.forEach(b=>w.set(b.rowId,b)),w},[m]),p=30,g=M.useMemo(()=>({width:t-20,height:n-p,top:0,position:"relative",overflowY:"auto"}),[t,n]),y=M.useCallback(w=>{if(w.ctrlKey)return w.key==="ArrowDown"?f({type:vy}):w.key==="ArrowUp"?f({type:yy}):w.key==="Home"?f({type:by}):w.key==="End"&&f({type:Dy}),!1},[f]),S=M.useCallback(()=>{f({type:"REDISTRIBUTE_UNIT_COLORS"})},[f]);return B.jsxs("div",{children:[B.jsx("div",{style:g,onKeyDown:y,children:B.jsx(QF,{columns:v,rows:D,orderedUnitIds:u,visibleUnitIds:h,selectedUnitIds:a,currentUnitId:o,selectionDispatch:f,primarySortRule:s})}),B.jsx("div",{style:{position:"absolute",top:n-p,height:p,overflow:"hidden"},children:B.jsx(wf,{options:r,setOptions:i,onRedistributeUnitColors:S})})]})},tN=({defaultLabelOptions:e,width:t,height:n})=>{const{selectedUnitIdsArray:r}=qr(),{sortingCuration:i,sortingCurationDispatch:a,curating:o}=ES(),{labelChoices:u=[],labelsByUnit:l={},mergeGroups:s=[],isClosed:c=!1}=i,[f,d]=M.useState(""),[h,v]=M.useState(!1),m=M.useMemo(()=>u.length===0&&e.length>0&&o?(a({type:"SET_LABEL_CHOICES",labelChoices:e}),e):u,[u,e,a,o]);M.useEffect(()=>{},[m]);const D=M.useCallback(j=>{if(r.length===0)return"none";const H=r.filter(k=>(l[k.toString()]||[]).includes(j));return H.length===0?"none":H.length===r.length?"full":"partial"},[r,l]),p=M.useCallback(j=>{o&&(r.length===0||c||a({type:"TOGGLE_UNIT_LABEL",unitId:r,label:j}))},[r,c,a,o]),g=M.useCallback(()=>{if(!o)return;const j=f.trim();j&&!m.includes(j)&&(a({type:"SET_LABEL_CHOICES",labelChoices:[...m,j]}),d(""))},[f,m,a,o]),y=M.useCallback(j=>Object.values(l).some(H=>H.includes(j)),[l]),S=M.useCallback(j=>{o&&(y(j)||a({type:"SET_LABEL_CHOICES",labelChoices:m.filter(H=>H!==j)}))},[m,a,y,o]),w=M.useCallback(j=>s.find(H=>H.includes(j)),[s]),b=M.useMemo(()=>{if(r.length===0)return{canMerge:!1,canUnmerge:!1,groupsInvolved:[],unmergedUnits:[]};const j=new Set,H=[];r.forEach(Y=>{const ee=w(Y);ee?j.add(ee):H.push(Y)});const k=r.length>=2,q=j.size>0;return{canMerge:k,canUnmerge:q,groupsInvolved:Array.from(j),unmergedUnits:H}},[r,w]),E=M.useCallback(()=>{o&&(r.length<2||c||a({type:"MERGE_UNITS",unitIds:r}))},[r,c,a,o]),C=M.useCallback(()=>{o&&(r.length===0||c||a({type:"UNMERGE_UNITS",unitIds:r}))},[r,c,a,o]),A=M.useCallback(()=>{o&&a(c?{type:"REOPEN_CURATION"}:{type:"CLOSE_CURATION"})},[c,a,o]),T=M.useMemo(()=>r.length===0?"No units selected":r.length<=5?`Units: ${r.join(", ")}`:`${r.length} units selected`,[r]),_={width:t,height:n,padding:"8px",fontSize:"12px",fontFamily:"Arial, sans-serif",border:"1px solid #ddd",borderRadius:"4px",backgroundColor:"#fafafa",overflow:"auto",display:"flex",flexDirection:"column",gap:"8px"},x={marginBottom:"6px"},F={fontWeight:"bold",marginBottom:"4px",fontSize:"11px",color:"#333"},R={display:"inline-flex",alignItems:"center",padding:"2px 6px",margin:"2px",backgroundColor:"#e0e0e0",borderRadius:"12px",fontSize:"10px",border:"1px solid #ccc"},z={marginLeft:"4px",cursor:"pointer",color:"#666",fontWeight:"bold"},N={padding:"2px 4px",fontSize:"10px",border:"1px solid #ccc",borderRadius:"2px",marginRight:"4px",flex:1},U={padding:"2px 6px",fontSize:"10px",border:"1px solid #ccc",borderRadius:"2px",backgroundColor:"#f0f0f0",cursor:"pointer"},I={display:"inline-flex",alignItems:"center",margin:"2px 8px 2px 0",cursor:r.length>0&&!c?"pointer":"default",opacity:r.length>0&&!c?1:.5},L={...x,textAlign:"center"},G={...U,backgroundColor:c?"#f8d7da":"#d4edda",borderColor:c?"#f5c6cb":"#c3e6cb",color:c?"#721c24":"#155724"},X={display:"flex",alignItems:"center",cursor:"pointer",fontSize:"11px",fontWeight:"bold",color:"#333",marginBottom:"4px"},P={marginRight:"4px",fontSize:"10px",transform:h?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.2s"};return B.jsxs("div",{style:_,children:[B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Selected Units"}),B.jsx("div",{style:{fontSize:"10px",color:"#666"},children:T})]}),B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Label Assignment"}),m.map(j=>{const H=D(j);return B.jsxs("div",{style:I,onClick:o?()=>p(j):void 0,children:[B.jsx("input",{type:"checkbox",checked:H==="full",ref:k=>{k&&(k.indeterminate=H==="partial")},onChange:()=>{},style:{marginRight:"4px"},disabled:r.length===0||c}),B.jsx("span",{style:{fontSize:"10px"},children:j})]},j)}),r.length===0&&B.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic"},children:"Select units to assign labels"})]}),B.jsxs("div",{style:x,children:[B.jsx("div",{style:F,children:"Unit Merging"}),r.length>0&&b.groupsInvolved.length>0&&B.jsxs("div",{style:{marginBottom:"6px"},children:[B.jsx("div",{style:{fontSize:"10px",color:"#666",marginBottom:"2px"},children:"Merge groups involving selected units:"}),b.groupsInvolved.map((j,H)=>{const k={...R,backgroundColor:"#e3f2fd",borderColor:"#90caf9",color:"#1565c0"};return B.jsx("span",{style:k,children:j.join(", ")},H)})]}),B.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center",flexWrap:"wrap"},children:[B.jsx("button",{onClick:o?E:void 0,style:{...U,backgroundColor:b.canMerge&&!c?"#d4edda":"#f8f9fa",borderColor:b.canMerge&&!c?"#c3e6cb":"#dee2e6",color:b.canMerge&&!c?"#155724":"#6c757d",cursor:b.canMerge&&!c?"pointer":"default"},disabled:!b.canMerge||c,title:c?"Cannot merge when curation is closed":r.length<2?"Select 2 or more units to merge":"Merge selected units",children:"Merge Selected"}),B.jsx("button",{onClick:o?C:void 0,style:{...U,backgroundColor:b.canUnmerge&&!c?"#fff3cd":"#f8f9fa",borderColor:b.canUnmerge&&!c?"#ffeaa7":"#dee2e6",color:b.canUnmerge&&!c?"#856404":"#6c757d",cursor:b.canUnmerge&&!c?"pointer":"default"},disabled:!b.canUnmerge||c,title:c?"Cannot unmerge when curation is closed":b.canUnmerge?"Unmerge selected units":"Select units that are part of merge groups to unmerge",children:"Unmerge Selected"})]}),r.length>0&&B.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"4px"},children:[b.groupsInvolved.length>0&&B.jsxs("div",{children:["Selected units in"," ",b.groupsInvolved.length," merge group(s)"]}),b.unmergedUnits.length>0&&B.jsxs("div",{children:[b.unmergedUnits.length," unmerged unit(s) selected"]})]}),r.length===0&&B.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic",marginTop:"4px"},children:"Select units to merge or unmerge"})]}),B.jsxs("div",{style:x,children:[B.jsxs("div",{style:X,onClick:()=>v(!h),children:[B.jsx("span",{style:P,children:"▶"}),"Manage Label Choices"]}),h&&B.jsxs("div",{children:[B.jsx("div",{style:{marginBottom:"4px"},children:m.map(j=>{const H=y(j);return B.jsxs("span",{style:R,children:[j,!c&&!H&&B.jsx("span",{style:z,onClick:o?()=>S(j):void 0,title:"Remove label choice",children:"×"})]},j)})}),!c&&B.jsxs("div",{style:{display:"flex",alignItems:"center"},children:[B.jsx("input",{type:"text",value:f,onChange:j=>d(j.target.value),onKeyPress:j=>j.key==="Enter"&&o&&g(),placeholder:"Add label...",style:N}),B.jsx("button",{onClick:o?g:void 0,style:U,disabled:!f.trim(),children:"Add"})]})]})]}),B.jsxs("div",{style:L,children:[B.jsx("button",{onClick:o?A:void 0,style:G,children:c?"Reopen Curation":"Finalize Curation"}),B.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"2px"},children:["Status: ",c?"Closed":"Open"]})]})]})},nN=({zarrGroup:e,contexts:t,width:n,height:r})=>B.jsx(Jr,{context:t.unitSelection,children:B.jsx(TS,{contexts:t,editable:!0,children:B.jsx(rN,{zarrGroup:e,contexts:t,width:n,height:r})})}),rN=({zarrGroup:e,width:t,height:n})=>{const r=e.attrs.default_label_options||[];return B.jsx(tN,{defaultLabelOptions:r,width:t,height:n})},TS=({contexts:e,children:t,editable:n})=>{const{annotations:r,setAnnotation:i}=GF(e,"/",n),a=M.useMemo(()=>{try{return JSON.parse(r?.sorting_curation||"{}")}catch(u){return console.error("Error parsing sorting_curation:",u),{}}},[r]),o=M.useMemo(()=>u=>{if(!i)return;const l=Af(a,u);i("sorting_curation",JSON.stringify(l))},[i,a]);return B.jsx(wS.Provider,{value:{sortingCuration:a,sortingCurationDispatch:o,curating:!!i},children:t})},iN=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.columns||[],h=await e.getDatasetData("rows_data",{});if(!h||h.length===0)throw new Error("Empty rows data");const v=new Uint8Array(h),m=new TextDecoder("utf-8").decode(v),D=JSON.parse(m);let p;try{const g=await e.getDatasetData("similarity_scores_data",{});if(g&&g.length>0){const y=new Uint8Array(g),S=new TextDecoder("utf-8").decode(y);p=JSON.parse(S)}}catch(g){console.warn("No similarity scores data found: "+g)}if(c)return;a({type:"UnitsTable",columns:d,rows:D,similarityScores:p})}catch(d){console.error("Error loading units table data:",d),u(`Failed to load units table data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading units table data..."}):i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx(TS,{contexts:t,editable:!1,children:B.jsx(CS,{data:i,width:n,height:r})})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No units table data available"})},aN=e=>{const{ampScaleFactor:t,setAmpScaleFactor:n}=e,r=()=>{n(t*1.2)},i=()=>{n(t/1.2)},a=()=>{n(1)};return[{type:"button",callback:r,title:"Scale amplitude up [shift + mouse-wheel]",icon:B.jsx(M_,{}),keyCode:38},{type:"button",callback:a,title:"Reset scale amplitude",icon:B.jsx(XD,{})},{type:"button",callback:i,title:"Scale amplitude down [shift + mouse-wheel]",icon:B.jsx(A_,{}),keyCode:40}]},MS={forward:[[1,0,0],[0,1,0]],inverse:[[1,0,0],[0,1,0]]},ha=(e,t)=>({x:t.x*e.forward[0][0]+t.y*e.forward[0][1]+e.forward[0][2],y:t.x*e.forward[1][0]+t.y*e.forward[1][1]+e.forward[1][2]}),$m=(e,t)=>({x:t.x*e.inverse[0][0]+t.y*e.inverse[0][1]+e.inverse[0][2],y:t.x*e.inverse[1][0]+t.y*e.inverse[1][1]+e.inverse[1][2]}),oN=(e,t)=>({forward:_S(e.forward,t.forward),inverse:_S(t.inverse,e.inverse)}),uN=e=>({forward:[...e.map(t=>[...t])],inverse:sN(e)}),lN=e=>({forward:e.inverse,inverse:e.forward}),km=e=>e.forward[0][0]*e.forward[1][1]-e.forward[0][1]*e.forward[1][0],_S=(e,t)=>[[e[0][0]*t[0][0]+e[0][1]*t[1][0],e[0][0]*t[0][1]+e[0][1]*t[1][1],e[0][0]*t[0][2]+e[0][1]*t[1][2]+e[0][2]],[e[1][0]*t[0][0]+e[1][1]*t[1][0],e[1][0]*t[0][1]+e[1][1]*t[1][1],e[1][0]*t[0][2]+e[1][1]*t[1][2]+e[1][2]]],sN=e=>{const t=[[e[0][0],e[0][1]],[e[1][0],e[1][1]]],n=[e[0][2],e[1][2]],r=t[0][0]*t[1][1]-t[0][1]*t[1][0],i=[[t[1][1]/r,-t[0][1]/r],[-t[1][0]/r,t[0][0]/r]],a=[i[0][0]*n[0]+i[0][1]*n[1],i[1][0]*n[0]+i[1][1]*n[1]];return[[i[0][0],i[0][1],-a[0]],[i[1][0],i[1][1],-a[1]]]},Lm=(e,t,n={})=>{const r=n.shift!==void 0?n.shift:!0,i=n.shift!==void 0?n.alt:!1,[a,o]=M.useState(MS),u=M.useCallback(l=>{if(r&&!l.shiftKey||!r&&l.shiftKey||i&&!l.altKey||!i&&l.altKey)return;const s=l.currentTarget.getBoundingClientRect(),c={x:l.clientX-s.x,y:l.clientY-s.y},f=l.deltaY,d=1.3;let h=uN([[d,0,(1-d)*c.x],[0,d,(1-d)*c.y]]);f>0&&(h=lN(h));let v=oN(h,a);const m=ha(v,{x:0,y:0}),D=ha(v,{x:e,y:t});return 0<=m.x&&m.x<e&&0<=m.y&&m.y<t&&0<=D.x&&D.x<e&&0<=D.y&&D.y<t&&(v=MS),o(v),!1},[a,t,e,r,i]);return{affineTransform:a,handleWheel:u}},hl={border:"rgb(30, 30, 30)",base:"rgb(0, 0, 255)",selected:"rgb(50, 200, 50)",hover:"rgb(128, 128, 255)",selectedHover:"rgb(200, 200, 196)",dragged:"rgb(0, 0, 196)",draggedSelected:"rgb(180, 180, 150)",dragRect:"rgba(196, 196, 196, 0.5)",textLight:"rgb(228, 228, 228)",textDark:"rgb(32, 32, 32)"},cN=2*Math.PI,fN=(e,t)=>{const{layoutMode:n,affineTransform:r}=t;if(e.save(),r){const i=r.forward;e.transform(i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2])}n==="geom"?hN(e,t):dN(e,t),e.restore()},dN=(e,t)=>{const{pixelElectrodes:n,pixelRadius:r,showLabels:i,xMargin:a}=t,o=r>5&&i,u=t.colors??hl,l=o?2*r:0;e.clearRect(0,0,e.canvas.width,e.canvas.height);const s=a+l,c=e.canvas.width-a;if(e.beginPath(),n.forEach(f=>{e.moveTo(s,f.pixelY),e.lineTo(c,f.pixelY)}),e.strokeStyle=u.border,e.stroke(),o){const f=s-.5*r;e.font=`${r-3}px Arial`,e.fillStyle=u.textDark,e.textAlign="right",e.textBaseline="middle",n.forEach(d=>{e.fillText(`${d.e.label}`,f,d.pixelY)})}},hN=(e,t)=>{const{pixelElectrodes:n,selectedElectrodeIds:r,hoveredElectrodeId:i,draggedElectrodeIds:a,pixelRadius:o,showLabels:u,offsetLabels:l}=t,s=o>5&&u,c=t.colors??hl,f=n.map(d=>{const h=r.includes(d.e.id),v=(i??-1)===d.e.id,m=a.includes(d.e.id),D=h?m?c.draggedSelected:v?c.selectedHover:c.selected:m?c.dragged:v?c.hover:c.base;return{...d,color:D,textColor:h||v&&!m?c.textDark:c.textLight}});if(e.clearRect(0,0,e.canvas.width,e.canvas.height),f.forEach(d=>{e.fillStyle=d.color,e.beginPath(),e.ellipse(d.pixelX,d.pixelY,o,o,0,0,cN),e.fill()}),s){e.font=`${o}px Arial`,e.textAlign=l?"right":"center",e.textBaseline="middle";const d=l?1.4*o:0;f.forEach(h=>{e.fillStyle=l?c.textDark:h.textColor,e.fillText(`${h.e.label}`,h.pixelX-d,h.pixelY)})}},Cf=e=>e.reduce((t,n)=>t<=n?t:n,1/0),Tf=e=>e.reduce((t,n)=>t>=n?t:n,-1/0),Oo=10,ml=10,mN=(e,t)=>{const n=t||{};return t&&(Object.keys(n).length!==e.length||e.some(i=>!n[`${i}`]))?(console.warn("Attempt to compute electrode locations with mismatched lists. Skipping..."),[]):e.map(i=>{const a=n[`${i}`]||[i,0];return{id:i,label:`${i}`,x:a[0],y:a[1]}})},BS=new Map,FS=e=>{const t=JSON.stringify(e),n=BS.get(t);if(n!==void 0)return n;let r=Number.MAX_VALUE;e.forEach(a=>{e.forEach(o=>{const u=OD([a.x-o.x,a.y-o.y]);u!==0&&(r=Math.min(r,u))})});const i=.45*r;return BS.set(t,i),i},NS=(e,t)=>({xmin:Cf(e.map(n=>n.x))-t,xmax:Tf(e.map(n=>n.x))+t,ymin:Cf(e.map(n=>n.y))-t,ymax:Tf(e.map(n=>n.y))+t}),pN=e=>{const t=FS(e),n=NS(e,t),r=Sc(n),i=zD(n),a={x:r/2+n.xmin,y:i/2+n.ymin};return{boxAspect:r/i,boxCenter:a}},gN=e=>{const t={xmin:Cf(e.map(n=>n.x)),xmax:Tf(e.map(n=>n.x)),ymin:Cf(e.map(n=>n.y)),ymax:Tf(e.map(n=>n.y))};return t.xmin===t.xmax&&t.ymin===t.ymax?e.map((n,r)=>({...n,x:r,y:0})):e},vN=(e,t)=>s_(n=>{const r=Oo+n[0]*(e-2*Oo),i=ml+n[1]*(t-2*ml);return[r,i]}),yN=(e,t)=>{const n=e.map((a,o)=>({e:a,ind:o})).sort((a,o)=>-a.e.y+o.e.y).map(a=>a.ind),r=[];for(let a=0;a<e.length;a++)r.push([0,0]);for(let a=0;a<n.length;a++){const o=n[a];r[o]=[.5,(.5+a)/(1+e.length)]}const i=Zh(t,r);return e.map((a,o)=>{const[u,l]=i[o];return{e:a,pixelX:u,pixelY:l}})},bN=(e,t,n,r,i)=>{const a=e-Oo*2,o=t-ml*2,u=Sc(i),l=zD(i);return L5(a/u,o/l,r/n)},DN=(e,t,n,r)=>{const i=Sc(r),a=(e-i*n)/2,o=[n,0,a-r.xmin*n],u=[0,-n,(t+n*(r.ymin+r.ymax))/2];return[o,u,[0,0,1]]},SN=(e,t,n,r={})=>{const i=(e-Oo*2)/(t-ml*2),a=gN(n),{boxAspect:o}=pN(a);return r.disableAutoRotate||o===1||i===1||o>1==i>1?{electrodes:n,rotated:!1}:{electrodes:n.map(u=>({...u,x:u.y,y:-u.x})),rotated:!0}},xN=(e,t)=>{const n=e.map(i=>[i.x,i.y]),r=Zh(t,n);return e.map((i,a)=>{const[o,u]=r[a];return{e:i,pixelX:o,pixelY:u}})},RS=(e,t,n)=>{for(const r of e)if(OD([r.pixelX-n[0],r.pixelY-n[1]])<t)return r.e.id},OS=(e,t,n)=>{const r=t.xmin-n,i=t.xmax+n,a=t.ymin-n,o=t.ymax+n;return e.filter(u=>u.pixelX>r&&u.pixelX<i&&u.pixelY>a&&u.pixelY<o).map(u=>u.e.id)},jm=(e,t,n,r="geom",i=IS,a)=>{if(r==="vertical"){const m=vN(e,t),D=yN(n,m),p=(t-2*ml)/(1+n.length);return{transform:m,convertedElectrodes:D,pixelRadius:p}}const{electrodes:o,rotated:u}=SN(e,t,n,{disableAutoRotate:a.disableAutoRotate}),l=FS(o),s=NS(o,l),c=bN(e,t,l,i,s),f=l*c;let d=DN(e,t,c,s);const h=(e-Sc(s)*c)/2,v=xN(o,d);return u&&(d=[[-d[0][1],d[0][0],d[0][2]],[-d[1][1],d[1][0],d[1][2]],[-d[2][1],d[2][0],d[2][2]]]),{transform:d,convertedElectrodes:v,pixelRadius:f,xMargin:h}},zS={isActive:!1},wN=(e,t)=>{if(t.type==="INITIALIZE"){const{width:n,height:r,electrodes:i,layoutMode:a,maxElectrodePixelRadius:o}=t,{convertedElectrodes:u,pixelRadius:l,xMargin:s}=jm(n,r,i,a,o,{disableAutoRotate:t.disableAutoRotate});return{...e,convertedElectrodes:u,pixelRadius:l,draggedElectrodeIds:[],hoveredElectrodeId:void 0,dragState:zS,xMarginWidth:s??Oo}}else if(t.type==="DRAGUPDATE"){const n=r_(e.dragState,t.dragAction);if(!n.isActive&&n.dragRect){const r=ID(n.dragRect),i=OS(e.convertedElectrodes,r,e.pixelRadius),a=t.dragAction.shift?[...i,...t.selectedElectrodeIds||[]]:i;return{...e,draggedElectrodeIds:[],hoveredElectrodeId:void 0,pendingSelectedElectrodeIds:a,dragState:zS}}else if(n.dragRect){const r=ID(n.dragRect),i=OS(e.convertedElectrodes,r,e.pixelRadius);return i.length===e.draggedElectrodeIds.length&&i.filter(a=>!e.draggedElectrodeIds.includes(a)).length===0?{...e,hoveredElectrodeId:void 0,dragState:n}:{...e,hoveredElectrodeId:void 0,draggedElectrodeIds:i,dragState:n}}else return{...e,dragState:n}}else if(t.type==="UPDATEHOVER"){const n=RS(e.convertedElectrodes,e.pixelRadius,t.point);return n===e.hoveredElectrodeId?e:{...e,hoveredElectrodeId:n}}else if(t.type==="UPDATECLICK"){const n=RS(e.convertedElectrodes,e.pixelRadius,t.point);if(n===void 0)return!(t.shift||t.ctrl)&&t.selectedElectrodeIds.length>0?{...e,pendingSelectedElectrodeIds:[]}:e;const r=t.ctrl?t.selectedElectrodeIds.includes(n)?t.selectedElectrodeIds.filter(i=>i!==n):[...t.selectedElectrodeIds,n]:t.shift?[...t.selectedElectrodeIds,n]:[n];return{...e,hoveredElectrodeId:void 0,pendingSelectedElectrodeIds:r}}else return console.log("Error: unrecognized verb in electrode geometry reducer."),e},US=!1,IS=25,$S={showLabels:!0,maxElectrodePixelRadius:IS},EN=e=>{const t=e.currentTarget.getBoundingClientRect();return[e.clientX-t.x,e.clientY-t.y]},AN=()=>({selectedElectrodeIds:[],setSelectedElectrodeIds:e=>{}}),kS=e=>{const{width:t,height:n,electrodes:r,disableAutoRotate:i,affineTransform:a}=e,{selectedElectrodeIds:o,setSelectedElectrodeIds:u}=AN(),l=e.disableSelection??!1,s=e.offsetLabels??!1,c=e.colors??hl,f=e.layoutMode??"geom",d=e.maxElectrodePixelRadius||$S.maxElectrodePixelRadius,[h,v]=M.useReducer(wN,{convertedElectrodes:[],pixelRadius:-1,draggedElectrodeIds:[],pendingSelectedElectrodeIds:o||[],dragState:{isActive:!1},xMarginWidth:-1}),{affineTransform:m,handleWheel:D}=Lm(t,n,{shift:!0,alt:!1}),p=M.useMemo(()=>{const T=h.convertedElectrodes.map(_=>{const x=ha(m,{x:_.pixelX,y:_.pixelY});return{..._,pixelX:x.x,pixelY:x.y}});return{...h,convertedElectrodes:T,pixelRadius:h.pixelRadius*Math.sqrt(km(m))}},[m,h]),g=M.useMemo(()=>T=>{const _=EN(T),x=$m(m,{x:_[0],y:_[1]});return[x.x,x.y]},[m]);M.useEffect(()=>{v({type:"INITIALIZE",electrodes:r,width:t,height:n,maxElectrodePixelRadius:d,layoutMode:f,disableAutoRotate:i})},[t,n,r,f,d,i]),M.useEffect(()=>{u(h.pendingSelectedElectrodeIds)},[u,h.pendingSelectedElectrodeIds]);const y=M.useRef(null),S=M.useRef(0),w=l||B.jsx(l_,{width:t,height:n,newState:h.dragState}),b=M.useCallback(T=>{if(!a_(T,{nextDragStateUpdate:y,nextFrame:S,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})){const x=g(T);v({type:"UPDATEHOVER",point:x})}},[g]),E=M.useCallback(T=>{o_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})},[]),C=M.useCallback(T=>{if(h.dragState.isActive)u_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE",selectedElectrodeIds:o}});else{const _=g(T);v({type:"UPDATECLICK",point:_,shift:T.shiftKey,ctrl:T.ctrlKey,selectedElectrodeIds:o||[]})}},[h.dragState.isActive,o,g]),A=M.useMemo(()=>{const T={pixelElectrodes:p.convertedElectrodes,selectedElectrodeIds:o||[],hoveredElectrodeId:h.hoveredElectrodeId,draggedElectrodeIds:h.draggedElectrodeIds,pixelRadius:p.pixelRadius,showLabels:e.showLabels??$S.showLabels,offsetLabels:s,layoutMode:e.layoutMode??"geom",xMargin:h.xMarginWidth,colors:c,affineTransform:a};return B.jsx(ir,{width:t,height:n,draw:fN,drawData:T})},[t,n,p.convertedElectrodes,o,h.hoveredElectrodeId,h.draggedElectrodeIds,p.pixelRadius,e.showLabels,s,e.layoutMode,h.xMarginWidth,c,a]);return M.useMemo(()=>US,[h.convertedElectrodes,o,h.hoveredElectrodeId,h.draggedElectrodeIds,h.pixelRadius,e.showLabels,s,e.layoutMode,h.xMarginWidth,t,n,c]),B.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:b,onMouseUp:C,onMouseDown:E,onWheel:D,children:[w,US,A]})},CN=e=>1/e,ma=(e,t,n,r,i)=>{const a=[];return n.forEach((o,u)=>{for(const l of t){const s=l.electrodeIndices.indexOf(u);if(s>=0){let c;const f=l.waveformStdDev,d=l.waveformPercentiles;if(r==="normal"?c=l.waveform[s]:r==="lower"?c=f?l.waveform[s].map((h,v)=>l.waveform[s][v]-f[s][v]):void 0:r==="upper"?c=f?l.waveform[s].map((h,v)=>l.waveform[s][v]+f[s][v]):void 0:r==="percentile1"?c=d?l.waveform[s].map((h,v)=>d[0][s][v]):void 0:r==="percentile2"?c=d?l.waveform[s].map((h,v)=>d[1][s][v]):void 0:r==="percentile3"?c=d&&2<d.length?l.waveform[s].map((h,v)=>d[2][s][v]):void 0:r==="percentile4"&&(c=d&&3<d.length?l.waveform[s].map((h,v)=>d[3][s][v]):void 0),c){const h=c.map((m,D)=>[(c?.length||0)/2+(D-(c?.length||0)/2)*i,m]),v=Zh(e,h);a.push({pointsInPaintBox:v,offsetFromParentCenter:[o.pixelX,o.pixelY],color:l.waveformColors.base})}}}}),a},TN=(e,t)=>{const{pixelSpacePaths:n,pixelSpacePathsLower:r,pixelSpacePathsUpper:i,pixelSpacePathsPercentile1:a,pixelSpacePathsPercentile2:o,pixelSpacePathsPercentile3:u,pixelSpacePathsPercentile4:l,xMargin:s,waveformWidth:c,affineTransform:f,useUnitColors:d}=t;if(!n||n.length===0)return;if(e.resetTransform(),e.clearRect(0,0,e.canvas.width,e.canvas.height),e.save(),f){const g=f.forward;e.transform(g[0][0],g[1][0],g[0][1],g[1][1],g[0][2],g[1][2])}e.translate(s,0);const h=e.getTransform();r&&i&&r.forEach((g,y)=>{const S=r[y],w=i[y];e.fillStyle="#dddddd",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)});let v,m,D,p;a&&o&&u&&l?(v=a,m=o,D=u,p=l):a&&o&&!u&&!l?(v=void 0,m=a,D=o,p=void 0):(v=void 0,m=void 0,D=void 0,p=void 0),v&&v.length>0&&p&&p.length>0&&v.forEach((g,y)=>{if(!v||!p)throw Error("unexpected");const S=v[y],w=p[y];e.fillStyle="#dddddd",e.strokeStyle="#dddddd",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)}),m&&m.length>0&&m.length>0&&D&&D.length>0&&m.forEach((g,y)=>{if(!m||!D)throw Error("unexpected");const S=m[y],w=D[y];e.fillStyle="#bbbbbb",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(S.offsetFromParentCenter[0],S.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(S.pointsInPaintBox[0][0],S.pointsInPaintBox[0][1]);for(let b=0;b<S.pointsInPaintBox.length;b++)e.lineTo(S.pointsInPaintBox[b][0],S.pointsInPaintBox[b][1]);for(let b=w.pointsInPaintBox.length-1;b>=0;b--)e.lineTo(w.pointsInPaintBox[b][0],w.pointsInPaintBox[b][1]);e.fill(),e.stroke(),e.setTransform(h)}),n.forEach(g=>{e.strokeStyle=d?g.color:"black",e.lineWidth=c,e.translate(g.offsetFromParentCenter[0],g.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(g.pointsInPaintBox[0][0],g.pointsInPaintBox[0][1]),g.pointsInPaintBox.forEach(y=>{e.lineTo(y[0],y[1])}),e.stroke(),e.setTransform(h)}),e.restore()},MN=e=>{const{electrodes:t,waveforms:n,oneElectrodeHeight:r,oneElectrodeWidth:i,yScale:a,horizontalStretchFactor:o,width:u,height:l,layoutMode:s,waveformWidth:c,affineTransform:f,useUnitColors:d}=e;return M.useMemo(()=>{const v=n.length>0&&n[0].waveform.length>0?n[0].waveform[0].length:0,m=i/v,D=-i*(.5+1/v),p=a*r/2,g=ze([[m,0,D],[0,-p,0],[0,0,1]]).toArray(),y=ma(g,n,t,"normal",o),S=ma(g,n,t,"lower",o),w=ma(g,n,t,"upper",o);let b=ma(g,n,t,"percentile1",o),E=ma(g,n,t,"percentile2",o),C=ma(g,n,t,"percentile3",o),A=ma(g,n,t,"percentile4",o);b.length===0&&(b=void 0),E.length===0&&(E=void 0),C.length===0&&(C=void 0),A.length===0&&(A=void 0);const T=s==="vertical"?(u-i)/2:0,_={pixelSpacePaths:y,pixelSpacePathsLower:S,pixelSpacePathsUpper:w,pixelSpacePathsPercentile1:b,pixelSpacePathsPercentile2:E,pixelSpacePathsPercentile3:C,pixelSpacePathsPercentile4:A,xMargin:T,waveformWidth:c,affineTransform:f,useUnitColors:d};return B.jsx(ir,{width:u,height:l,draw:TN,drawData:_})},[n,t,a,u,l,i,r,s,c,f,o,d])},_N={colors:{border:"rgb(120, 100, 120)",base:"rgb(240, 240, 240)",selected:"rgb(196, 196, 128)",hover:"rgb(128, 128, 255)",selectedHover:"rgb(200, 200, 196)",dragged:"rgb(0, 0, 196)",draggedSelected:"rgb(180, 180, 150)",dragRect:"rgba(196, 196, 196, 0.5)",textLight:"rgb(162, 162, 162)",textDark:"rgb(32, 150, 150)"}},BN=e=>{const t=e.colors??_N.colors,{electrodes:n,waveforms:r,ampScaleFactor:i,horizontalStretchFactor:a,layoutMode:o,hideElectrodes:u,width:l,height:s,showChannelIds:c,useUnitColors:f,waveformWidth:d,disableAutoRotate:h}=e,v=1e3,{handleWheel:m,affineTransform:D}=Lm(l,s,{shift:!0,alt:!0}),p=M.useMemo(()=>B.jsx(kS,{electrodes:n,width:l,height:s,layoutMode:o,colors:t,showLabels:c,maxElectrodePixelRadius:v,disableSelection:!0,disableAutoRotate:h,affineTransform:D}),[n,l,s,o,t,c,h,D]),{convertedElectrodes:g,pixelRadius:y,xMargin:S}=jm(l,s,n,o,v,{disableAutoRotate:h}),w=S||Oo,b=M.useMemo(()=>CN(e.peakAmplitude),[e.peakAmplitude]),E=M.useMemo(()=>i*b,[i,b]),C=o==="geom"?y*2:s/n.length,A=o==="geom"?y*2:l-w-(c?2*y:0),T=B.jsx(MN,{electrodes:g,waveforms:r,oneElectrodeHeight:C,oneElectrodeWidth:A,horizontalStretchFactor:a,yScale:E,width:l,height:s,layoutMode:o,waveformWidth:d,affineTransform:D,useUnitColors:f});return B.jsxs("div",{style:{width:l,height:s,position:"relative"},onWheel:m,children:[!u&&p,T]})},FN=({allChannelIds:e,channelIds:t,units:n,layoutMode:r,hideElectrodes:i,channelLocations:a,samplingFrequency:o,peakAmplitude:u,ampScaleFactor:l,horizontalStretchFactor:s,showChannelIds:c,useUnitColors:f,showReferenceProbe:d,disableAutoRotate:h,width:v,height:m})=>{const D=M.useMemo(()=>{const w=a||{};return t.map(b=>({id:b,label:`${b}`,x:w[`${b}`]!==void 0?w[`${b}`][0]:Ct(b),y:w[`${b}`]!==void 0?w[`${b}`][1]:0}))},[t,a]),p=M.useMemo(()=>{const w=a||{};return e.map(b=>({id:b,label:`${b}`,x:w[`${b}`]!==void 0?w[`${b}`][0]:Ct(b),y:w[`${b}`]!==void 0?w[`${b}`][1]:0}))},[e,a]),g=v/4,y=M.useMemo(()=>n.map(w=>{const b={base:w.waveformColor},E=[];for(const C of w.channelIds)E.push(D.map(A=>A.id).indexOf(C));return{electrodeIndices:E,waveform:w.waveform,waveformStdDev:w.waveformStdDev,waveformPercentiles:w.waveformPercentiles,waveformColors:b}}),[D,n]),S=B.jsx(BN,{waveforms:y,electrodes:D,ampScaleFactor:l,horizontalStretchFactor:s,layoutMode:a?r:"vertical",hideElectrodes:i,width:d?v-g:v,height:m,showLabels:!0,peakAmplitude:u,samplingFrequency:o,showChannelIds:c,useUnitColors:f,waveformWidth:2,disableAutoRotate:h});return d?B.jsxs("div",{style:{position:"relative",width:v,height:m},children:[B.jsx("div",{style:{position:"absolute",left:0,top:0,width:g,height:m},children:B.jsx(kS,{electrodes:p,disableSelection:!1,width:g,height:m})}),B.jsx("div",{style:{position:"absolute",left:g,top:0,width:v-g,height:m},children:S})]}):S},NN=({data:e,width:t,height:n})=>{const r=M.useMemo(()=>{const k=[];for(const q of e.averageWaveforms)for(const Y of q.channelIds)k.includes(Y)||k.push(Y);return yr(k)},[e.averageWaveforms]),[i,a]=M.useState({...xf,onlyShowSelected:!1}),{selectedUnitIds:o,currentUnitId:u,orderedUnitIds:l,plotClickHandlerGenerator:s,unitIdSelectionDispatch:c}=qr(),[f,d]=M.useState(1),[h,v]=M.useState("geom"),[m,D]=M.useState(!0),[p,g]=M.useState(!1),[y,S]=M.useState(e.showReferenceProbe||!1),[w,b]=M.useState(!1),[E,C]=M.useState(1),[A,T]=M.useState(!0),[_,x]=M.useState(!0);M.useEffect(()=>{c({type:oo,newUnitOrder:yr(e.averageWaveforms.map(k=>k.unitId))})},[e.averageWaveforms,c]);const[F,R]=M.useState(2),z=M.useMemo(()=>{let k=0;return e.averageWaveforms.forEach(q=>{q.waveform.forEach(Y=>{Y.forEach(ee=>{const te=Math.abs(ee);te>k&&(k=te)})})}),k},[e.averageWaveforms]),N=M.useMemo(()=>e.averageWaveforms.filter(k=>i.onlyShowSelected?o.has(k.unitId):!0).map(k=>{const q=[{channelIds:k.channelIds,waveform:ON(k.waveform),waveformStdDev:m&&!w?k.waveformStdDev:void 0,waveformPercentiles:m&&!w&&k.waveformPercentiles?zN(k.waveformPercentiles,k.waveform):void 0,waveformColor:wr(Ct(k.unitId))}],Y={allChannelIds:r,channelIds:k.channelIds,units:q,layoutMode:h,hideElectrodes:A,channelLocations:e.channelLocations,samplingFrequency:e.samplingFrequency,peakAmplitude:z,ampScaleFactor:f,horizontalStretchFactor:E,showChannelIds:p,useUnitColors:_,width:120*F+(y?120*F/4:0),height:120*F,showReferenceProbe:y,disableAutoRotate:!0};return{unitId:k.unitId,key:k.unitId,label:`Unit ${k.unitId}`,labelColor:wr(Ct(k.unitId)),clickHandler:i.onlyShowSelected?void 0:s(k.unitId),props:Y}}),[e.averageWaveforms,e.channelLocations,e.samplingFrequency,r,z,h,f,s,i.onlyShowSelected,o,F,m,p,y,w,E,A,_]),U=M.useMemo(()=>l?l.map(k=>N.filter(q=>q.unitId===k)[0]).filter(k=>k!==void 0):N,[N,l]),I=M.useMemo(()=>w?RN(U):U,[U,w]),L=M.useMemo(()=>[{type:"button",callback:()=>{C(k=>k*1.1)},title:"Increase horizontal stretch [alt + mouse-wheel]",icon:B.jsx(T_,{})},{type:"button",callback:()=>{C(1)},title:"Reset scale amplitude",icon:B.jsx(XD,{})},{type:"button",callback:()=>{C(k=>k/1.1)},title:"Decrease horizontal stretch [alt + mouse-wheel]",icon:B.jsx(C_,{})}],[]),G=M.useMemo(()=>{const k=aN({ampScaleFactor:f,setAmpScaleFactor:d}),q={type:"toggle",subtype:"checkbox",callback:()=>v(de=>de==="geom"?"vertical":"geom"),title:"Show electrode geometry",selected:h==="geom"},Y={type:"toggle",subtype:"checkbox",callback:()=>T(de=>!de),title:"Show electrodes",selected:!A},ee=[{type:"button",callback:()=>R(de=>de*1.3),title:"Increase box size",icon:B.jsx(Tc,{})},{type:"button",callback:()=>R(de=>de/1.3),title:"Decrease box size",icon:B.jsx(Cc,{})}],te={type:"toggle",subtype:"checkbox",callback:()=>D(de=>!de),title:"Show waveform stdev",selected:m===!0},ne={type:"toggle",subtype:"checkbox",callback:()=>g(de=>!de),title:"Show channel IDs",selected:p===!0},oe={type:"toggle",subtype:"checkbox",callback:()=>S(de=>!de),title:"Show reference probes",selected:y===!0},W={type:"toggle",subtype:"checkbox",callback:()=>b(de=>!de),title:"Show overlapping",selected:w===!0},ce={type:"toggle",subtype:"checkbox",callback:()=>x(de=>!de),title:"Use unit colors",selected:_===!0};return[{type:"divider"},...ee,{type:"divider"},...k,{type:"divider"},...L,{type:"divider"},q,Y,{type:"divider"},te,{type:"divider"},ne,{type:"divider"},oe,{type:"divider"},W,{type:"divider"},ce]},[h,f,m,p,w,y,L,A,_]),X=M.useCallback(k=>{k.shiftKey&&!k.altKey?k.deltaY<0?d(q=>q*1.3):d(q=>q/1.3):k.altKey&&!k.shiftKey&&(k.deltaY<0?C(q=>q*1.1):C(q=>q/1.1))},[]),P=30,j=M.useCallback(k=>{k&&k.addEventListener("wheel",q=>{(q.shiftKey||q.altKey)&&q.preventDefault()})},[]),H=fl;return B.jsxs("div",{ref:k=>j(k),onWheel:X,children:[B.jsxs(Ro,{width:t,height:n-P,initialPosition:H,adjustable:!1,children:[B.jsx(dl,{width:H,height:n,customActions:G}),B.jsx(wc,{width:0,height:0,children:B.jsx(xc,{plots:I,plotComponent:FN,selectedPlotKeys:i.onlyShowSelected?void 0:o,currentPlotKey:u})})]}),B.jsx("div",{style:{position:"absolute",top:n-P,height:P,overflow:"hidden"},children:B.jsx(wf,{options:i,setOptions:a})})]})},RN=e=>{if(e.length===0)return e;const t={...e[0],props:{...e[0].props}},n=t.props;t.key="overlapping",t.label="Overlapping",t.labelColor="black",t.unitId="overlapping",n.height*=3;const r=new Set;for(const a of e)for(const o of a.props.channelIds)r.add(o);const i=yr([...r]);return n.channelIds=i,n.units=e.map(a=>a.props.units[0]),[t]},ON=e=>e.map(t=>{const n=LS(t);return t.map(r=>r-n)}),zN=(e,t)=>{const n=[];for(let r=0;r<e.length;r++)n.push(e[r].map((i,a)=>{const o=LS(t[a]);return i.map(u=>u-o)}));return n},LS=e=>e.length>0?W5(e):0,UN=e=>B.jsx(Jr,{context:e.contexts.unitSelection,children:B.jsx(IN,{...e})}),IN=({zarrGroup:e,width:t,height:n})=>{const[r,i]=M.useState(null);return M.useEffect(()=>{let a=!1;return(async()=>{const u=[],l=e.attrs.num_average_waveforms||0,s=e.attrs.average_waveforms,c=s.length;c!==l&&console.warn(`numUnits (${c}) !== numAverageWaveforms (${l})`);for(let f=0;f<l;f++){const d=`waveform_${f}`,h=await e.getGroup(d);if(!h){console.warn(`No group for ${d}`);continue}if(h.datasets.find(g=>g.name==="waveform")===void 0){console.warn(`No waveform dataset for ${d}`);continue}const v=await e.getDataset(`${d}/waveform`);if(!v){console.warn(`Could not load waveform dataset for ${d}`);continue}const m=v.shape,D=await e.getDatasetData(`${d}/waveform`,{});let p;if(h.datasets.find(g=>g.name==="waveform_std_dev")===void 0?p=void 0:p=await e.getDatasetData(`${d}/waveform_std_dev`,{}),D){const g=s.find(y=>y.name===d);g&&u.push({unitId:g.unit_id,channelIds:g.channel_ids,waveform:jS(D,m),waveformStdDev:p?jS(p,m):void 0})}}a||i({type:"AverageWaveforms",averageWaveforms:u})})(),()=>{a=!0}},[e]),r?B.jsx(NN,{data:r,width:t,height:n}):B.jsx("div",{children:"Loading..."})},jS=(e,t)=>{if(t.length!==2)throw Error("shape.length should be 2");const[n,r]=t;if(e.length!==n*r)throw Error(`data.length does not match shape. Expected ${n*r}, got ${e.length}`);const i=[];for(let a=0;a<r;a++){const o=[];for(let u=0;u<n;u++)o.push(e[u*r+a]);i.push(o)}return i},HS=20,$N=({data:e,width:t,height:n})=>{const[r,i]=M.useState(!1),{selectedUnitIds:a}=qr(),o=M.useMemo(()=>yr([...a]),[a]),u=e.hideUnitSelector,l=M.useMemo(()=>{const p=e.crossCorrelograms.filter(y=>o.includes(y.unitId1)&&o.includes(y.unitId2)),g=[];for(const y of o)for(const S of o){const w=p.filter(b=>b.unitId1===y&&b.unitId2===S)[0];w?g.push(w):g.push(void 0)}return g},[e.crossCorrelograms,o]),s=u?0:100,c=fl,f=t-s-c,d=n,h=M.useMemo(()=>{const p=o.length,{plotWidth:g,plotHeight:y}=PS(f,d,p);return l.map((S,w)=>({key:`${w}`,unitId:S?S.unitId1:0,label:S?g>80?`Unit ${S.unitId1}/${S.unitId2}`:`${S.unitId1}/${S.unitId2}`:"",labelColor:"black",clickHandler:void 0,props:{binEdgesSec:S?S.binEdgesSec:void 0,binCounts:S?S.binCounts:void 0,color:S?.unitId1===S?.unitId2?wr(Ct(S?.unitId1)):"gray",width:g,height:y,hideXAxis:!r}}))},[l,f,d,o,r]),v=M.useMemo(()=>[{type:"toggle",subtype:"checkbox",callback:()=>i(g=>!g),title:"Show X Axis",selected:r===!0}],[r]),m=M.useMemo(()=>{const p=new Set;e.crossCorrelograms.forEach(y=>{p.add(y.unitId1),p.add(y.unitId2)});const g=yr(Array.from(p));return{type:"UnitsTable",columns:[],rows:g.map(y=>({unitId:y,values:{}}))}},[e.crossCorrelograms]),D=B.jsxs(Ro,{width:t-s,height:n,initialPosition:c,adjustable:!1,children:[B.jsx(dl,{width:c,height:n,customActions:v}),B.jsx(wc,{width:0,height:0,disableScroll:!0,children:o.length>HS?B.jsxs("div",{children:["Not showing cross-correlogram matrix. Too many units selected (max ="," ",HS,")."]}):o.length===0?B.jsx("div",{children:"Select one or more units to view cross-correlograms."}):B.jsx(xc,{plots:h,plotComponent:xS,selectedPlotKeys:void 0,numPlotsPerRow:o.length})})]});return u?D:B.jsxs("div",{style:{position:"relative",width:t,height:n},children:[B.jsx("div",{style:{position:"absolute",left:0,top:0,width:s,height:n,borderRight:"1px solid #ccc",boxSizing:"border-box",padding:10,backgroundColor:"#f9f9f9"},children:B.jsx(CS,{data:m,width:s,height:n})}),B.jsx("div",{style:{position:"absolute",left:s,top:0,width:t-s,height:n},children:D})]})},PS=(e,t,n)=>{const r=Math.min((e-30-(n-1)*7)/n,(t-30-(n-1)*7)/n);return{plotWidth:r,plotHeight:r}},kN=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null);return M.useEffect(()=>{let o=!1;return(async()=>{const l=[],s=e.attrs.num_cross_correlograms||0;if(s===0){o||a({type:"CrossCorrelograms",crossCorrelograms:[],hideUnitSelector:e.attrs.hide_unit_selector||!1});return}const c=await e.getDatasetData("bin_edges_sec",{}),f=await e.getDatasetData("bin_counts",{});if(!c||!f){console.error("Failed to load cross-correlograms data");return}const d=Array.from(c),h=new Int32Array(f),v=d.length-1,m=e.attrs.cross_correlograms;for(let p=0;p<s;p++){const g=m[p],y=p*v,S=Array.from(h.slice(y,y+v));l.push({unitId1:g.unit_id1,unitId2:g.unit_id2,binEdgesSec:d,binCounts:S})}const D=e.attrs.hide_unit_selector||!1;o||a({type:"CrossCorrelograms",crossCorrelograms:l,hideUnitSelector:D})})(),()=>{o=!0}},[e]),i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx($N,{data:i,width:n,height:r})}):B.jsx("div",{children:"Loading..."})},LN=1.4,jN=(e,t,n,r)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: * Attempt to call zoomTime() with uninitialized state ${e}.`),{visibleStartTimeSec:e.visibleStartTimeSec,visibleEndTimeSec:e.visibleEndTimeSec};const i=e.endTimeSec-e.startTimeSec,a=e.visibleEndTimeSec-e.visibleStartTimeSec;if(a===i&&t==="out")return{visibleStartTimeSec:e.startTimeSec,visibleEndTimeSec:e.endTimeSec};let o=n??LN;o=t==="in"?1/o:o;const u=Math.min(a*o,i);if(u>=i)return{...e,visibleStartTimeSec:e.startTimeSec,visibleEndTimeSec:e.endTimeSec};const l=r!==void 0?r:e.currentTime??e.visibleStartTimeSec+a/2,s=(l-e.visibleStartTimeSec)/a;let c=Math.max(l-s*u,e.startTimeSec);const f=Math.min(c+u,e.endTimeSec);return c=f-u,{visibleStartTimeSec:c,visibleEndTimeSec:f}},qS=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: Attempt to call panTime() with uninitialized state ${e}.`),e;const n=e.visibleEndTimeSec-e.visibleStartTimeSec;let r=e.visibleStartTimeSec,i=e.visibleEndTimeSec;if(t>0)i=Math.min(e.visibleEndTimeSec+t,e.endTimeSec),r=Math.max(i-n,e.startTimeSec);else if(t<0)r=Math.max(e.visibleStartTimeSec+t,e.startTimeSec),i=Math.min(r+n,e.endTimeSec);else return e;const o=!0?e.currentTime:void 0;return r===e.visibleStartTimeSec&&i===e.visibleEndTimeSec?e:{...e,visibleStartTimeSec:r,visibleEndTimeSec:i,currentTimeSec:o}},HN=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: * Attempt to call panTime() with uninitialized state ${e}.`),{visibleStartTimeSec:e.visibleStartTimeSec,visibleEndTimeSec:e.visibleEndTimeSec};const n=e.visibleEndTimeSec-e.visibleStartTimeSec,r=t.panAmountPct/100*n*(t.type==="back"?-1:1);return qS(e,r)},PN=(e,t)=>{if(e.visibleStartTimeSec===void 0||e.visibleEndTimeSec===void 0||e.startTimeSec===void 0||e.endTimeSec===void 0)return console.warn(`WARNING: Attempt to call panTime() with uninitialized state ${e}.`),e;const n=t.deltaT;return qS(e,n)},VS=Nt.createContext(void 0),Mf=()=>{const e=M.useContext(VS);if(!e)throw new Error("useTimeseriesSelection must be used within a TimeseriesSelectionContext");const t=e.dispatch,n=M.useCallback(u=>{t({type:"initializeTimeseries",startTimeSec:u.startTimeSec,endTimeSec:u.endTimeSec,initialVisibleStartTimeSec:u.initialVisibleStartTimeSec,initialVisibleEndTimeSec:u.initialVisibleEndTimeSec})},[t]),r=M.useCallback((u,l)=>{t({type:"setVisibleTimeRange",visibleStartTimeSec:u,visibleEndTimeSec:l})},[t]),i=M.useCallback(u=>{t({type:"setCurrentTime",currentTime:u})},[t]),a=M.useCallback(u=>{t({type:"zoomVisibleTimeRange",factor:u})},[t]),o=M.useCallback(u=>{t({type:"translateVisibleTimeRangeFrac",frac:u})},[t]);if(e===void 0)throw new Error("useTimeseriesSelection must be used within a TimeseriesSelectionContext.Provider");return{initializeTimeseriesSelection:n,setVisibleTimeRange:r,setCurrentTime:i,zoomVisibleTimeRange:a,translateVisibleTimeRangeFrac:o,timeseriesSelection:e.timeseriesSelection,startTimeSec:e.timeseriesSelection.startTimeSec,endTimeSec:e.timeseriesSelection.endTimeSec,visibleStartTimeSec:e.timeseriesSelection.visibleStartTimeSec,visibleEndTimeSec:e.timeseriesSelection.visibleEndTimeSec,currentTime:e.timeseriesSelection.currentTime}},_f=()=>{const{visibleStartTimeSec:e,visibleEndTimeSec:t,currentTime:n,setCurrentTime:r,startTimeSec:i,endTimeSec:a,setVisibleTimeRange:o}=Mf(),u=M.useCallback((d,h,v)=>{const m=jN({visibleStartTimeSec:e,visibleEndTimeSec:t,currentTime:n,startTimeSec:i,endTimeSec:a},d,h,v);m.visibleStartTimeSec!==void 0&&m.visibleEndTimeSec!==void 0&&o(m.visibleStartTimeSec,m.visibleEndTimeSec)},[e,t,n,i,a,o]),l=M.useCallback((d,h)=>{const v=HN({visibleStartTimeSec:e,visibleEndTimeSec:t,startTimeSec:i,endTimeSec:a,currentTime:n},{type:d,panAmountPct:h??10});v.visibleStartTimeSec!==void 0&&v.visibleEndTimeSec!==void 0&&o(v.visibleStartTimeSec,v.visibleEndTimeSec)},[e,t,i,a,n,o]),s=M.useCallback(d=>{const h=PN({visibleStartTimeSec:e,visibleEndTimeSec:t,startTimeSec:i,endTimeSec:a,currentTime:n},{deltaT:d});h.visibleStartTimeSec!==void 0&&h.visibleEndTimeSec!==void 0&&o(h.visibleStartTimeSec,h.visibleEndTimeSec)},[e,t,i,a,n,o]),c=M.useCallback(d=>{if(e===void 0||t===void 0)return;const h=t-e,v=d,m=v+h;o(v,m)},[e,t,o]),f=M.useCallback((d,h)=>{if(e===void 0||t===void 0)return;const v=e+d*(t-e);r(v)},[e,t,r]);return{visibleStartTimeSec:e,visibleEndTimeSec:t,setVisibleTimeRange:o,zoomTimeseriesSelection:u,panTimeseriesSelection:l,panTimeseriesSelectionDeltaT:s,panTimeseriesSelectionVisibleStartTimeSec:c,setCurrentTimeFraction:f}},GS=()=>{const[e,t]=M.useState(!1),n=M.useMemo(()=>[{id:"only-show-selected",label:"Only Show Selected",tooltip:"Toggle visibility of only selected units",icon:e?"👁️":"👁️‍🗨️",isActive:e,onClick:()=>t(r=>!r)}],[e]);return{onlyShowSelected:e,customToolbarActions:n}},qN=[{name:"1ms",secondsPerTick:.001,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%1e3} ms`},{name:"10ms",secondsPerTick:.01,countPerLargerUnit:10,scale_appropriate_label:e=>`${e*10%1e3} ms`},{name:"100ms",secondsPerTick:.1,countPerLargerUnit:10,scale_appropriate_label:e=>`${e*100%1e3} ms`},{name:"1s",secondsPerTick:1,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%60} s`},{name:"10s",secondsPerTick:10,countPerLargerUnit:6,scale_appropriate_label:e=>`${e*10%60} s`},{name:"1min",secondsPerTick:60,countPerLargerUnit:10,scale_appropriate_label:e=>`${e%60} min`},{name:"10min",secondsPerTick:60*10,countPerLargerUnit:6,scale_appropriate_label:e=>`${e*10%60} min`},{name:"1hr",secondsPerTick:60*60,countPerLargerUnit:6,scale_appropriate_label:e=>`${e%24} hr`},{name:"6hr",secondsPerTick:60*60*6,countPerLargerUnit:4,scale_appropriate_label:e=>`${e*6%24} hr`},{name:"1day",secondsPerTick:60*60*24,countPerLargerUnit:10,scale_appropriate_label:e=>`${e} day`},{name:"10day",secondsPerTick:60*60*24*10,countPerLargerUnit:1e4,scale_appropriate_label:e=>`${10*e} day`}],VN=(e,t,n,r)=>M.useMemo(()=>{if(t===void 0||n===void 0)return[];if(n<=t)return[];const i=[],a=e/(n-t);for(const o of qN){const u=a*o.secondsPerTick;if(u<=50)continue;const l=Math.ceil(t/o.secondsPerTick),s=Math.floor(n/o.secondsPerTick),c=u>200||s-l<5;for(let f=l;f<=s;f++){if(f%o.countPerLargerUnit===0)continue;const d=f*o.secondsPerTick;i.push({value:d,label:o.scale_appropriate_label(f),major:c,xPixelPosition:r(d)})}}return i},[t,n,r,e]),GN=e=>{if(!e||typeof e=="function")return;const t=e.current,n=t&&t.getContext("2d");if(n)return n},YN={position:"absolute",left:0,top:0},YS=e=>{const{width:t,height:n,draw:r,drawData:i}=e,a=M.useRef(null);return M.useEffect(()=>{const o=GN(a);o&&o.canvas&&r(o,i)},[r,a,i]),B.jsx("canvas",{ref:a,width:t,height:n,style:YN})},XN=(e,t)=>{const{width:n,height:r,margins:i,timeTicks:a,gridlineOpts:o,yTickSet:u,yLabel:l}=t;e.clearRect(0,0,e.canvas.width,e.canvas.height);const s=r-i.bottom;ZN(e,a,s,i.top,{hideGridlines:o?.hideX},t.hideTimeAxisLabels),e.strokeStyle="lightgray",Hm(e,i.left,s,n-i.right,s),u&&QN(e,u,s,i.left,n-i.right,i.top,{hideGridlines:o?.hideY}),l&&KN(e,l,i.left,i.bottom,i.top,e.canvas.height)},ZN=(e,t,n,r,i,a)=>{const o=a||!1;if(!t||t.length===0)return;const u=2,l=n+(o?0:5);e.textAlign="center",e.textBaseline="top",t.forEach(s=>{e.strokeStyle=s.major?"gray":"lightgray";const c=i.hideGridlines?n:r;Hm(e,s.xPixelPosition,l,s.xPixelPosition,c),o||(e.fillStyle=s.major?"black":"gray",e.fillText(s.label,s.xPixelPosition,l+u))})},QN=(e,t,n,r,i,a,o)=>{const l=r-5,s=l-2,{ticks:c}=t;e.fillStyle="black",e.textAlign="right",e.textBaseline="middle",c.forEach(f=>{if(!f.pixelValue)return;const d=f.pixelValue;e.strokeStyle=f.isMajor?"gray":"lightgray",e.fillStyle=f.isMajor?"black":"gray";const h=o.hideGridlines?r:i;Hm(e,l,d,h,d),e.fillText(f.label,s,d)})},KN=(e,t,n,r,i,a)=>{e.textAlign="center",e.textBaseline="middle",e.save(),e.translate(15,(a-r-i)/2+i),e.fillStyle="black",e.font="13px sans-serif",e.rotate(-Math.PI/2),e.fillText(t,0,0),e.restore()},Hm=(e,t,n,r,i)=>{e.beginPath(),e.moveTo(t,n),e.lineTo(r,i),e.stroke()},WN={},JN=e=>{const{width:t,height:n}=e,r=M.useCallback(i=>{XN(i,e)},[e]);return B.jsx("span",{className:"TSV2AxesLayer",children:B.jsx(YS,{width:t,height:n,draw:r,drawData:WN})})},e7=(e,t)=>{const{margins:n,currentTimePixels:r,currentTimeIntervalPixels:i}=t;if(e.clearRect(0,0,e.canvas.width,e.canvas.height),i!==void 0){e.fillStyle="rgba(255, 225, 225, 0.4)",e.strokeStyle="rgba(150, 50, 50, 0.9)";const a=i[0],o=n.top,u=i[1]-i[0],l=e.canvas.height-n.bottom-n.top;e.fillRect(a,o,u,l),e.strokeRect(a,o,u,l)}if(r!==void 0&&i===void 0){e.fillStyle="rgba(255, 255, 0, 0.1)";const a=4;e.fillRect(r-a/2,n.top,a,e.canvas.height-n.bottom-n.top),e.strokeStyle="rgba(200, 200, 0, 0.4)",e.lineWidth=1,e.beginPath(),e.moveTo(r,n.top),e.lineTo(r,e.canvas.height-n.bottom),e.stroke()}},t7=e=>{const{width:t,height:n,timeRange:r,currentTimePixels:i,currentTimeIntervalPixels:a,margins:o}=e,u=M.useMemo(()=>({width:t,height:n,timeRange:r,currentTimePixels:i,currentTimeIntervalPixels:a,margins:o}),[t,n,r,i,a,o]);return B.jsx(YS,{width:t,height:n,draw:e7,drawData:u})},n7=({width:e,height:t,selectionRect:n})=>{if(!n)return null;const{startX:r,endX:i}=n,a=Math.abs(i-r),o=Math.min(r,i);return B.jsx("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none",zIndex:10},children:B.jsx("div",{style:{position:"absolute",left:o,top:0,width:a,height:t,backgroundColor:"rgba(0, 123, 255, 0.2)",border:"1px solid rgba(0, 123, 255, 0.6)",borderRadius:"2px"}})})},r7=e=>{const{pixelToTime:t,visibleStartTimeSec:n,setCurrentTime:r,onMouseDown:i,onMouseUp:a,onMouseMove:o,onMouseOut:u,onCanvasClick:l,interactionMode:s}=e,{panTimeseriesSelectionVisibleStartTimeSec:c,setVisibleTimeRange:f}=_f(),[d,h]=M.useState(!1),[v,m]=M.useState(void 0),[D,p]=M.useState(null),g=M.useRef({mouseDownAchorX:null,mouseDownAnchorTime:null,mouseDownAnchorVisibleStartTime:null,mouseDownAnchorPixelToTime:null,moved:!1,selectionStartX:null,selectionEndX:null}),y=M.useCallback(E=>{if(h(!0),!E.shiftKey&&!E.ctrlKey&&!E.altKey){const C=E.clientX-E.currentTarget.getBoundingClientRect().x;s==="select-zoom"?(g.current.selectionStartX=C,g.current.selectionEndX=C,p({startX:C,endX:C})):(g.current.mouseDownAchorX=C,g.current.mouseDownAnchorTime=t(C),g.current.mouseDownAnchorVisibleStartTime=n||null,g.current.mouseDownAnchorPixelToTime=t),g.current.moved=!1}else i&&i(E)},[t,i,n,s]),S=M.useCallback(E=>{if(!E.shiftKey&&!E.ctrlKey&&!E.altKey){const C=E.clientX-E.currentTarget.getBoundingClientRect().x;if(s==="select-zoom"&&g.current.selectionStartX!==null){const A=Math.min(g.current.selectionStartX,C),T=Math.max(g.current.selectionStartX,C);if(Math.abs(T-A)>5){const _=t(A),x=t(T);f(_,x)}else if(!g.current.moved){const _=t(C);if(r(_),l){const x=E.clientY-E.currentTarget.getBoundingClientRect().y;l(C,x)}}p(null),g.current.selectionStartX=null,g.current.selectionEndX=null}else if(g.current.mouseDownAchorX=null,g.current.mouseDownAnchorTime=null,g.current.mouseDownAnchorPixelToTime=null,!g.current.moved){const A=t(C);if(r(A),l){const T=E.clientY-E.currentTarget.getBoundingClientRect().y;l(C,T)}}}else a&&a(E)},[a,t,r,s,f,l]),w=M.useCallback(E=>{const C=E.clientX-E.currentTarget.getBoundingClientRect().x,A=t(C);if(m(A),!E.shiftKey&&!E.ctrlKey&&!E.altKey){if(s==="select-zoom"&&g.current.selectionStartX!==null)g.current.selectionEndX=C,p({startX:Math.min(g.current.selectionStartX,C),endX:Math.max(g.current.selectionStartX,C)}),g.current.moved=!0;else if(s==="pan"&&g.current.mouseDownAchorX!==null&&g.current.mouseDownAnchorPixelToTime!==null){const T=g.current.mouseDownAnchorPixelToTime(C),_=g.current.mouseDownAnchorTime,x=g.current.mouseDownAnchorVisibleStartTime;if(_!==null&&x!==null){const F=T-_,R=C-g.current.mouseDownAchorX;if(Math.abs(R)>2||Math.abs(F)>.01){const z=x-F;c(z),E.preventDefault(),E.stopPropagation(),g.current.moved=!0}}}}o&&o(E)},[t,o,s,c]),b=M.useCallback(E=>{m(void 0),h(!1),p(null),g.current.selectionStartX=null,g.current.selectionEndX=null,u&&u(E)},[u]);return{isViewClicked:d,hoverTime:v,selectionRect:D,handleMouseDown:y,handleMouseUp:S,handleMouseMove:w,handleMouseOut:b}},i7=({width:e,height:t,leftMargin:n,customToolbarActions:r,hideTimeAxisLabels:i,hideNavToolbar:a})=>{const o=r&&r.length>0,u=M.useMemo(()=>({left:n||60,right:20,top:10,bottom:i?10:30}),[n,i]);let l=0;a||(l+=40),o&&(l+=40);const s=e,c=t-l;return{margins:u,canvasWidth:s,canvasHeight:c}},a7=23,o7=60,u7=(e,t,n,r)=>{const i=Math.ceil((t-r)/n);return isNaN(i)||i<1?[]:Array(i).fill(0).map((a,o)=>r+o*n).filter(a=>a>e)},l7=(e,t)=>{let n=0;const r=Math.trunc(Math.log10(t));if(Math.trunc(Math.log10(e))!==r)return n;const i=Math.trunc(Math.log10(t-e));if(r<=i)return n;const a=i+1,o=Math.pow(10,-a),u=Math.trunc(t*o).toString(),l=Math.trunc(e*o).toString();for(const[s,c]of[...u].entries()){if(c!==l[s]){n=n*Math.pow(10,s-a);break}n=n*10+parseInt(c)}return n*Math.pow(10,a)},s7=(e,t)=>Math.floor(e*Math.pow(10,-(t+1)))*Math.pow(10,t+1),c7=(e,t,n)=>{const r=e-0,i=Math.trunc(r*Math.pow(10,-n)),a=i%10===0;return{label:Math.abs(n)>3?`${(i/10).toFixed(1)}e${n+1}`:`${Math.round(i*Math.pow(10,n)*1e9)/1e9}`,isMajor:a,dataValue:e}},f7=(e,t,n,r,i)=>{const a=u7(t,n,r,e).map(l=>Math.round(l*1e9)/1e9),o=l7(t,n);return a.map(l=>c7(l,o,i))},XS={ticks:[],datamin:0,datamax:0},d7=(e,t)=>{const n=Math.floor(Math.log10(e/t)),r=Math.pow(10,n),i=[1,2,5,10],o=i.map(u=>e/(r*u)).findIndex(u=>u<t);return o===3?{step:1,scale:n+1}:{step:i[o],scale:n}},h7=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;i<=1&&(i=1);const a=r??1;return M.useMemo(()=>{if(t===void 0||n===void 0||t===n)return XS;const o=t/a,u=n/a,l=u-o,s=i/o7,c=i/a7,f=d7(l,c),d=f.step*Math.pow(10,f.scale);if(l/d<s)return console.warn("Error: Unable to compute valid y-axis step size. Suppressing display."),XS;const h=s7(o,f.scale);return{ticks:f7(h,o,u,d,f.scale),datamin:o,datamax:u}},[n,t,a,i])},m7=e=>{const t=Math.round(e*1e3),n=Math.floor(t/(1e3*60*60)),r=Math.floor(t%(1e3*60*60)/(1e3*60)),i=Math.floor(t%(1e3*60)/1e3),a=t%1e3;return`${n.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}.${a.toString().padStart(3,"0")}`},p7=({width:e,height:t,interactionMode:n,onInteractionModeChange:r,currentTime:i,onZoomToFit:a})=>{const{zoomTimeseriesSelection:o,panTimeseriesSelection:u}=_f(),l=M.useCallback(()=>{o("in",1.2)},[o]),s=M.useCallback(()=>{o("out",1.2)},[o]),c=M.useCallback(()=>{u("back",10)},[u]),f=M.useCallback(()=>{u("forward",10)},[u]),d=M.useCallback(h=>{r(h)},[r]);return B.jsxs("div",{style:{width:e,height:t,backgroundColor:"#f8f9fa",borderTop:"1px solid #dee2e6",display:"flex",alignItems:"center",justifyContent:"space-between",padding:"0 12px",fontSize:"13px",fontFamily:"system-ui, -apple-system, sans-serif"},children:[B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[B.jsx("button",{onClick:()=>d("pan"),style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:n==="pan"?"#007bff":"#ffffff",color:n==="pan"?"#ffffff":"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease"},title:"Pan mode: Drag to pan, wheel to zoom",children:"🖱️ Pan"}),B.jsx("button",{onClick:()=>d("select-zoom"),style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:n==="select-zoom"?"#007bff":"#ffffff",color:n==="select-zoom"?"#ffffff":"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease"},title:"Select zoom mode: Drag to select region and zoom in",children:"🔍 Select"})]}),B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[B.jsx("button",{onClick:c,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Pan left",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"⬅️"}),B.jsx("button",{onClick:s,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Zoom out",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🔍➖"}),B.jsx("button",{onClick:l,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Zoom in",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🔍➕"}),B.jsx("button",{onClick:f,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Pan right",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"➡️"}),B.jsx("div",{style:{width:"1px",height:"20px",backgroundColor:"#dee2e6",margin:"0 4px"}}),B.jsx("button",{onClick:a,style:{padding:"6px 10px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:"#ffffff",color:"#495057",cursor:"pointer",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:"Reset zoom to show all data",onMouseEnter:h=>{h.currentTarget.style.backgroundColor="#e9ecef"},onMouseLeave:h=>{h.currentTarget.style.backgroundColor="#ffffff"},children:"🏠"})]}),B.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[B.jsx("span",{style:{color:"#6c757d",fontWeight:"500"},children:"Time:"}),B.jsx("span",{style:{padding:"4px 8px",backgroundColor:"#e9ecef",borderRadius:"4px",fontFamily:"Monaco, Consolas, monospace",fontSize:"12px",fontWeight:"600",color:"#495057",minWidth:"120px",textAlign:"center"},children:i!==void 0?m7(i):"--:--:--.---"})]})]})},g7=({width:e,height:t,customActions:n})=>!n||n.length===0?null:B.jsx("div",{style:{width:e,height:t,backgroundColor:"#f8f9fa",borderTop:"1px solid #dee2e6",display:"flex",alignItems:"center",justifyContent:"flex-start",padding:"0 12px",fontSize:"13px",fontFamily:"system-ui, -apple-system, sans-serif"},children:B.jsx("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:n.map(r=>r.component?B.jsx("div",{style:{display:"flex",alignItems:"center"},children:r.component},r.id):B.jsxs("button",{onClick:r.onClick,style:{padding:"4px 8px",border:"1px solid #ced4da",borderRadius:"4px",backgroundColor:r.isActive?"#007bff":"#ffffff",color:r.isActive?"#ffffff":"#495057",cursor:r.onClick?"pointer":"default",fontSize:"12px",fontWeight:"500",transition:"all 0.15s ease",display:"flex",alignItems:"center",gap:"4px"},title:r.tooltip||r.label,onMouseEnter:i=>{!r.isActive&&r.onClick&&(i.currentTarget.style.backgroundColor="#e9ecef")},onMouseLeave:i=>{!r.isActive&&r.onClick&&(i.currentTarget.style.backgroundColor="#ffffff")},children:[r.icon&&B.jsx("span",{children:r.icon}),r.label]},r.id))})}),v7=e=>{if(!e||!e.current)return;e.current.querySelectorAll("canvas").forEach(n=>{n.addEventListener("wheel",r=>{r.preventDefault()})})},ZS=({width:e,height:t,onCanvasElement:n,gridlineOpts:r,onKeyDown:i,onMouseDown:a,onMouseMove:o,onMouseOut:u,onMouseUp:l,yAxisInfo:s,shiftZoom:c,requireClickToZoom:f,leftMargin:d,customToolbarActions:h,onCanvasClick:v,hideNavToolbar:m=!1,hideTimeAxisLabels:D=!1})=>{const{visibleStartTimeSec:p,visibleEndTimeSec:g,zoomTimeseriesSelection:y,panTimeseriesSelection:S,setVisibleTimeRange:w}=_f(),{currentTime:b,setCurrentTime:E,startTimeSec:C,endTimeSec:A}=Mf(),T=M.useMemo(()=>[p,g],[p,g]),{margins:_,canvasWidth:x,canvasHeight:F}=i7({width:e,height:t,leftMargin:d,customToolbarActions:h,hideNavToolbar:m}),R=M.useMemo(()=>p===void 0||g===void 0?()=>0:g<=p?()=>0:O=>_.left+(O-p)/(g-p)*(x-_.left-_.right),[x,p,g,_]),z=M.useMemo(()=>p===void 0||g===void 0?()=>0:g<=p?()=>0:O=>p+(O-_.left)/(x-_.left-_.right)*(g-p),[x,p,g,_]),N=M.useMemo(()=>{const O=s?.yMin||0,$=s?.yMax||0;return $<=O?()=>0:V=>F-_.bottom-(V-O)/($-O)*(F-_.top-_.bottom)},[s,F,_]),U=VN(x,p,g,R),I=h7({datamin:s?.yMin||0,datamax:s?.yMax||0,pixelHeight:F-_.left-_.right}),L=M.useMemo(()=>({datamin:I.datamin,datamax:I.datamax,ticks:I.ticks.map(O=>({...O,pixelValue:N(O.dataValue)}))}),[I,N]),G=F,X=M.useMemo(()=>B.jsx(JN,{width:x,height:G,timeRange:T,margins:_,timeTicks:U,yTickSet:s?.showTicks?L:void 0,yLabel:s?.yLabel,gridlineOpts:r,hideTimeAxisLabels:D}),[x,G,T,_,U,s,L,D,r]),P=M.useMemo(()=>b!==void 0?R(b):void 0,[b,R]),j=M.useMemo(()=>B.jsx(t7,{width:x,height:G,timeRange:T,margins:_,currentTimePixels:P}),[x,G,T,_,P]),H=M.useRef(null),[k,q]=M.useState("pan"),{isViewClicked:Y,hoverTime:ee,selectionRect:te,handleMouseDown:ne,handleMouseUp:oe,handleMouseMove:W,handleMouseOut:ce}=r7({pixelToTime:z,visibleStartTimeSec:p,setCurrentTime:E,onMouseDown:a,onMouseUp:l,onMouseMove:o,onMouseOut:u,onCanvasClick:v,interactionMode:k});M.useEffect(()=>{(f===!1||Y)&&v7(H)},[f,Y]);const de=M.useCallback(O=>{if(c&&!O.shiftKey||O.deltaY===0||f!==!1&&!Y)return;const $=-O.deltaY/100;y($>0?"in":"out",1.2,ee)},[c,y,ee,f,Y]),ve=M.useCallback(O=>{O.key==="="?y("in"):O.key==="-"?y("out"):O.key==="ArrowRight"?S("forward"):O.key==="ArrowLeft"&&S("back"),i&&i(O)},[i,y,S]),De=M.useCallback(()=>{C!==void 0&&A!==void 0&&w(C,A)},[C,A,w]),Se=M.useMemo(()=>B.jsx(n7,{width:x,height:G,selectionRect:te}),[x,G,te]),[Ee,Re]=M.useState(null);M.useEffect(()=>{Ee&&n(Ee,x,F,_)},[Ee,x,F,_,n]);const Ce=M.useMemo(()=>B.jsxs("div",{style:{position:"relative",overflow:"hidden",width:x,height:G},onWheel:!f||Y?de:void 0,onMouseDown:ne,onMouseUp:oe,onMouseMove:W,onMouseOut:ce,tabIndex:0,onKeyDown:ve,children:[X,B.jsx("canvas",{style:{position:"absolute",width:x,height:G},ref:O=>Re(O),width:x,height:G}),j,Se]}),[x,G,ve,de,ne,oe,W,ce,f,Y,X,j,Se]),Ne=M.useMemo(()=>B.jsx(p7,{width:e,height:40,interactionMode:k,onInteractionModeChange:q,currentTime:b,onZoomToFit:De}),[e,k,q,b,De]),pe=M.useMemo(()=>B.jsx(g7,{width:e,height:40,customActions:h}),[e,h]);return B.jsxs("div",{className:"time-scroll-view-3",ref:H,style:{position:"absolute",width:e,height:t,background:"white"},children:[Ce,!m&&B.jsxs("div",{style:{position:"absolute",bottom:0,left:0,right:0},children:[Ne,pe]})]})},QS=15,y7={hideX:!1,hideY:!0},b7={showTicks:!1,yMin:void 0,yMax:void 0},D7=({dataClient:e,width:t,height:n})=>{const{visibleStartTimeSec:r,visibleEndTimeSec:i}=_f(),{initializeTimeseriesSelection:a}=Mf(),{selectedUnitIds:o,unitIdSelectionDispatch:u}=qr(),[l,s]=M.useState(void 0),c=M.useRef(null),[f,d]=M.useState(null),[h,v]=M.useState(null),[m,D]=M.useState(!1),[p,g]=M.useState(null),[y,S]=M.useState(null),w=M.useMemo(()=>r===void 0||i===void 0?"raster":i-r>120?"heatmap":"raster",[r,i]),b=e.metadata.unitIds;M.useEffect(()=>{e.metadata&&a({startTimeSec:e.metadata.startTimeSec,endTimeSec:e.metadata.endTimeSec,initialVisibleStartTimeSec:e.metadata.startTimeSec,initialVisibleEndTimeSec:e.metadata.endTimeSec})},[a,e.metadata]),M.useEffect(()=>{let H=!1;const k=async()=>{if(!(r===void 0||i===void 0))try{if(w==="raster"){const q=await e.getDataForRange({startTimeSec:r,endTimeSec:i});if(H)return;v(q),S(null)}else{const q=e.getSpikeCountsForRange({startTimeSec:r,endTimeSec:i});if(H)return;S(q),v(null)}g(null)}catch(q){if(H)return;console.error("Error loading data:",q),g(`Error loading data: ${q}`)}};return D(!0),k().finally(()=>{H||D(!1)}),()=>{H=!0}},[e,r,i,w]);const{onlyShowSelected:E,customToolbarActions:C}=GS(),[A,T]=M.useState(t),[_,x]=M.useState(n),[F,R]=M.useState(null),z=M.useMemo(()=>{const H=[];return E&&b.forEach((k,q)=>{o.has(k)&&H.push(q)}),H},[E,o,b]),N=M.useMemo(()=>z.map(H=>b[H]),[z,b]),U=M.useCallback(()=>{if(!F||!c.current||!f||!y||!e.metadata||r===void 0||i===void 0)return;if(f.clearRect(0,0,A,_),m&&(f.fillStyle="rgba(0, 0, 0, 0.02)",f.fillRect(0,0,A,_),f.fillStyle="black",f.font="16px Arial",f.textAlign="center",f.fillText("Loading...",A/2,_/2)),p){f.fillStyle="rgba(255, 0, 0, 0.1)",f.fillRect(0,0,A,_),f.fillStyle="red",f.font="14px Arial",f.textAlign="center",f.fillText(p,A/2,_/2);return}const k=_-F.top-F.bottom,q=A-F.left-F.right,Y=i-r;let ee;if(E){let oe=0;b.forEach((W,ce)=>{o.has(W)&&oe++}),ee=oe}else b.forEach((oe,W)=>{}),ee=b.length;const te=k/(ee||1);f.save(),f.beginPath(),f.rect(F.left,F.top,q,k),f.clip();let ne=1;if(y.counts.forEach(oe=>{E?z.forEach(W=>{const ce=oe[W];ce>ne&&(ne=ce)}):oe.forEach(W=>{W>ne&&(ne=W)})}),y.counts.forEach((oe,W)=>{const ce=y.binEdges[W],de=y.binEdges[W+1],ve=F.left+(ce-r)/Y*q,De=F.left+(de-r)/Y*q;if(E)for(let Se=0;Se<z.length;Se++){const Ee=z[Se],Ce=oe[Ee]/ne,Ne=F.top+(z.length-1-Se)*te,pe=KS(Ce);f.fillStyle=pe,f.fillRect(ve,Ne,De-ve+.5,te)}else oe.forEach((Se,Ee)=>{const Re=Se/ne,Ce=F.top+(b.length-1-Ee)*te,Ne=KS(Re);f.fillStyle=Ne,f.fillRect(ve,Ce,De-ve+.5,te)})}),f.restore(),te>=QS){f.globalAlpha=1;const oe=E?N:b;oe.forEach((W,ce)=>{const ve=F.top+(oe.length-1-ce)*te+te/2,De=mh(Ct(W));f.fillStyle=De,f.font="12px Arial",f.textAlign="right",f.fillText(`Unit ${W}`,F.left-5,ve)})}},[A,_,F,y,r,i,e.metadata,m,p,f,o,E,b,z,N]);console.log(o,z,N);const I=M.useCallback(()=>{if(!F||!c.current||!f||!h||!e.metadata||r===void 0||i===void 0)return;if(f.clearRect(0,0,A,_),m&&(f.fillStyle="rgba(0, 0, 0, 0.02)",f.fillRect(0,0,A,_),f.fillStyle="black",f.font="16px Arial",f.textAlign="center",f.fillText("Loading...",A/2,_/2)),p){f.fillStyle="rgba(255, 0, 0, 0.1)",f.fillRect(0,0,A,_),f.fillStyle="red",f.font="14px Arial",f.textAlign="center",f.fillText(p,A/2,_/2);return}const k=_-F.top-F.bottom,q=A-F.left-F.right,Y=i-r,ee=e.metadata.unitIds,te={};let ne;if(E){for(let W=0;W<z.length;W++){const ce=z[W];te[ce]=W}ne=z.length}else ee.forEach((W,ce)=>{te[ce]=ce}),ne=ee.length;const oe=k/(ne||1);f.save(),f.beginPath(),f.rect(F.left,F.top,q,k),f.clip();for(let W=0;W<h.timestamps.length;W++){const ce=h.timestamps[W],de=te[h.unitIndices[W]];if(de===void 0)continue;const ve=ee[h.unitIndices[W]],De=F.top+(ne-1-de)*oe+oe/2,Se=mh(Ct(ve)),Ee=l===ve,Re=o.has(ve);f.strokeStyle=Se,f.lineWidth=Ee||Re?2:1,f.globalAlpha=Re?1:Ee?.8:.6;const Ce=F.left+(ce-r)/Y*q;f.beginPath(),f.moveTo(Ce,De-oe*.4),f.lineTo(Ce,De+oe*.4),f.stroke()}if(f.restore(),oe>=QS){f.globalAlpha=1;const W=E?N:ee;W.forEach((ce,de)=>{const De=F.top+(W.length-1-de)*oe+oe/2,Se=mh(Ct(ce));f.fillStyle=Se,f.font="12px Arial",f.textAlign="right",f.fillText(`Unit ${ce}`,F.left-5,De)})}},[A,_,F,h,e.metadata,r,i,m,p,l,o,E,f,N,z]);M.useEffect(()=>{w==="heatmap"&&y?U():I()},[I,U,w,y]);const L=M.useCallback(()=>{},[]),G=M.useCallback(H=>{if(!F||!e.metadata)return;const k=e.metadata.unitIds,q=k.length,Y=1-(H.y-F.top)/(_-F.top-F.bottom),ee=Math.round(Y*q-.5);if(0<=ee&&ee<q)return k[ee]},[_,F,e.metadata]),X=M.useCallback(H=>{const k=H.currentTarget.getBoundingClientRect(),q={x:H.clientX-k.x,y:H.clientY-k.y},Y=G(q);H.shiftKey||H.ctrlKey?u({type:"TOGGLE_UNIT",targetUnit:Y}):u({type:"UNIQUE_SELECT",targetUnit:Y})},[G,u]),P=M.useCallback(H=>{const k=H.currentTarget.getBoundingClientRect(),q={x:H.clientX-k.x,y:H.clientY-k.y},Y=G(q);Y!==void 0&&s(Y)},[G]),j=M.useCallback(()=>{s(void 0)},[]);return e.metadata?B.jsx(ZS,{width:t,height:n,customToolbarActions:C,onCanvasElement:(H,k,q,Y)=>{c.current=H;const ee=H?.getContext("2d");d(ee),T(k),x(q),R(Y)},gridlineOpts:y7,onKeyDown:L,onMouseDown:X,onMouseMove:P,onMouseOut:j,yAxisInfo:b7}):B.jsx("div",{children:"Loading metadata..."})},KS=e=>{if(e===0)return"rgb(255,255,255)";const t=Math.max(0,Math.min(1,.7*(1-e))),n=Math.round(t*255);return`rgb(${n}, ${n}, ${n})`};class Pm{constructor(t,n,r,i,a,o){this.zarrGroup=t,this.metadata=n,this.referenceTimes=r,this.referenceIndices=i,this.counts2dArray=a,this.binEdges=o,this.zarrGroup=t}static async create(t){const n={startTimeSec:t.attrs.start_time_sec,endTimeSec:t.attrs.end_time_sec,unitIds:t.attrs.unit_ids||[],totalSpikes:t.attrs.total_spikes||0},r=await t.getDatasetData("reference_times",{}),i=await t.getDatasetData("reference_indices",{});if(!r||!i)throw new Error(`Reference arrays not found in Zarr group: ${t.path}`);const a=await t.getDatasetData("spike_counts_1sec",{}).catch(()=>{});if(!a)throw new Error(`Spike counts data not found in Zarr group: ${t.path}`);const o=Math.ceil(n.endTimeSec-n.startTimeSec),u=n.unitIds.length,l=Array(o);for(let f=0;f<o;f++){l[f]=Array(u);for(let d=0;d<u;d++){const h=f*u+d;l[f][d]=h<a.length?a[h]:0}}const s=Array(o+1);for(let f=0;f<=o;f++)s[f]=n.startTimeSec+f;return new Pm(t,n,r,i,l,s)}async getDataForRange(t){const n=this.findStartIndex(this.referenceTimes,this.referenceIndices,t.startTimeSec),r=this.findEndIndex(this.referenceTimes,this.referenceIndices,t.endTimeSec);if(n>=r)return{timestamps:[],unitIndices:[]};const i=await this.zarrGroup.getDatasetData("timestamps",{slice:[[n,r]]}),a=await this.zarrGroup.getDatasetData("unit_indices",{slice:[[n,r]]});return{timestamps:Array.from(i),unitIndices:Array.from(a)}}findStartIndex(t,n,r){let i=0;for(;i+1<t.length&&t[i+1]<r;)i++;return n[i]}getSpikeCountsForRange(t){const{startTimeSec:n,endTimeSec:r}=t,i=Math.floor(n-this.metadata.startTimeSec),a=Math.ceil(r-this.metadata.startTimeSec);let o=1;for(;(a-i)/o>500;)o+=1;const u=this.counts2dArray.slice(i,a),l=this.binEdges.slice(i,a+1);if(o===1)return{binEdges:l,counts:u};{const s=[],c=[];for(let f=0;f<u.length;f+=o){const d=Array(this.metadata.unitIds.length).fill(0);for(let h=0;h<o;h++)if(f+h<u.length)for(let v=0;v<d.length;v++)d[v]+=u[f+h][v];s.push(d),c.push(l[f])}return l.length>0&&c.push(l[Math.min(l.length-1,c.length*o)]),{binEdges:c,counts:s}}}findEndIndex(t,n,r){let i=t.length-1;for(;i-1>=0&&t[i-1]>r;)i--;return n[i]}}const S7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=x7(e);return i?B.jsx(WS,{context:t.timeseriesSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(D7,{dataClient:i,width:n,height:r})})}):null},WS=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?B.jsx(B.Fragment,{children:"Waiting for context..."}):B.jsx(VS.Provider,{value:{timeseriesSelection:n,dispatch:r},children:t})},x7=e=>{const[t,n]=M.useState(null);return M.useEffect(()=>{let r=!0;return Pm.create(e).then(i=>{r&&n(i)}),()=>{r=!1}},[e]),t},w7=({dataClient:e,width:t,height:n})=>{const{selectedUnitIds:r,unitIdSelectionDispatch:i}=qr(),{initializeTimeseriesSelection:a,visibleStartTimeSec:o,visibleEndTimeSec:u}=Mf(),[l,s]=M.useState(null),[c,f]=M.useState(null),[d,h]=M.useState(!1),[v,m]=M.useState(null),D=fl,{onlyShowSelected:p,customToolbarActions:g}=GS(),[y,S]=M.useState(t),[w,b]=M.useState(n),[E,C]=M.useState(null),A=e.metadata;M.useEffect(()=>{A&&i({type:oo,newUnitOrder:yr(A.unitIds)})},[A,i]),M.useEffect(()=>{A&&a({startTimeSec:A.startTimeSec,endTimeSec:A.endTimeSec,initialVisibleStartTimeSec:A.startTimeSec,initialVisibleEndTimeSec:A.endTimeSec})},[a,A]),M.useEffect(()=>{let x=!1;const F=async()=>{if(o!==void 0&&u!==void 0){let R=1e4;for(;;){const z=await e.getDataForRange({startTimeSec:o,endTimeSec:u},{maxNumEvents:R});if(x)return;if(z&&f(z),z.subsampleFactor>1){if(R===1e6)break;R=Math.max(R*3,z.timestamps.length*3),R>1e6&&(R=1e6)}else break}}};return h(!0),m(null),F().catch(R=>{x||m(`Failed to load data: ${R}`),m(`Failed to load data: ${R}`)}).finally(()=>{h(!1)}),()=>{x=!0}},[o,u,e]);const T=M.useMemo(()=>{if(!c||!A||c.amplitudes.length===0)return{yMin:0,yMax:10};let x=1/0,F=-1/0;for(let z=0;z<c.amplitudes.length;z++){const N=A.unitIds[c.unitIndices[z]];if(p?r.has(N):!0){const I=c.amplitudes[z];I<x&&(x=I),I>F&&(F=I)}}if(x===1/0)return{yMin:0,yMax:10};const R=(F-x)*.1;return{yMin:x-R,yMax:F+R}},[c,A,p,r]);M.useEffect(()=>{if(!l||!c||!A||!E||u===void 0||o===void 0)return;let x=!1;return(async()=>{if(x)return;if(l.clearRect(0,0,y,w),d&&(l.fillStyle="rgba(0, 0, 0, 0.1)",l.fillRect(0,0,y,w),l.fillStyle="black",l.font="16px Arial",l.textAlign="center",l.fillText("Loading...",y/2,w/2)),v){l.fillStyle="rgba(255, 0, 0, 0.1)",l.fillRect(0,0,y,w),l.fillStyle="red",l.font="14px Arial",l.textAlign="center",l.fillText(v,y/2,w/2);return}l.save(),l.beginPath(),l.rect(E.left,E.top,y-E.left-E.right,w-E.top-E.bottom),l.clip();const R=N=>E.left+(N-o)/(u-o)*(y-E.left-E.right),z=N=>w-E.bottom-(N-T.yMin)/(T.yMax-T.yMin)*(w-E.top-E.bottom);for(let N=0;N<c.timestamps.length;N++){const U=c.timestamps[N],I=c.amplitudes[N],L=A.unitIds[c.unitIndices[N]];if(U<o||U>u||!(p?r.has(L):!0))continue;const X=wr(Ct(L)),j=r.has(L)?1:.3;l.fillStyle=X,l.globalAlpha=j;const H=R(U),k=z(I);l.beginPath(),l.arc(H,k,2,0,Math.PI*2),l.fill()}l.globalAlpha=1,c.subsampleFactor>1&&(l.fillStyle="#2196F3",l.font="12px Arial",l.textAlign="left",l.fillText(`Subsampled ${c.subsampleFactor}x`,E.left+10,E.top+20)),l.restore()})(),()=>{x=!0}},[l,c,A,o,u,y,w,E,T,r,p,d,v]);const _=M.useMemo(()=>({showTicks:!0,yMin:T.yMin,yMax:T.yMax,yLabel:"Amplitude"}),[T]);return A?B.jsx("div",{children:B.jsxs(Ro,{width:t,height:n,initialPosition:D,adjustable:!1,children:[B.jsx(dl,{width:D,height:n}),B.jsx(ZS,{width:t-D,height:n,onCanvasElement:(x,F,R,z)=>{if(!x)return;const N=x.getContext("2d");s(N),S(F),b(R),C(z)},yAxisInfo:_,customToolbarActions:g})]})}):B.jsx("div",{children:"Loading metadata..."})};class Bf{constructor(t,n,r={},i,a){this.zarrGroup=t,this.metadata=n,this.subsampleClients=r,this.referenceTimes=i,this.referenceIndices=a,this.zarrGroup=t}static async create(t){const n={startTimeSec:t.attrs.start_time_sec,endTimeSec:t.attrs.end_time_sec,unitIds:t.attrs.unit_ids||[],totalSpikes:t.attrs.total_spikes||0},r={},i=t.subgroups.find(u=>u.name==="subsampled_data"),a=await t.getDatasetData("reference_times",{}),o=await t.getDatasetData("reference_indices",{});if(!a||!o)throw new Error(`Reference arrays not found in Zarr group: ${t.path}`);if(i){const u=await t.getGroup(i.name);if(!u)throw new Error(`Failed to load subsampled_data group at ${i.name} in ${t.path}`);let l=4;for(;;){const s=u.subgroups.find(d=>d.name===`factor_${l}`);if(!s)break;const c=await u.getGroup(s.name);if(!c)throw console.warn(u.subgroups),new Error(`Failed to load subsampled group at ${s.name} in ${t.path}`);const f=await Bf.create(c);r[l]=f,l*=4}}return new Bf(t,n,r,a,o)}async getDataForRange(t,n){const r=this.findStartIndex(this.referenceTimes,this.referenceIndices,t.startTimeSec),i=this.findEndIndex(this.referenceTimes,this.referenceIndices,t.endTimeSec);if(r>=i)return{timestamps:[],unitIndices:[],amplitudes:[],subsampleFactor:1};if(n.maxNumEvents>0&&i-r>n.maxNumEvents){let s=4;for(;s*4 in this.subsampleClients&&(i-r)/s>n.maxNumEvents;)s*=4;if(s in this.subsampleClients){const f=await this.subsampleClients[s].getDataForRange(t,{maxNumEvents:0});return f.subsampleFactor=s,f}}const a=await this.zarrGroup.getDatasetData("timestamps",{slice:[[r,i]]}),o=await this.zarrGroup.getDatasetData("unit_indices",{slice:[[r,i]]}),u=await this.zarrGroup.getDatasetData("amplitudes",{slice:[[r,i]]});return{timestamps:Array.from(a),unitIndices:Array.from(o),amplitudes:Array.from(u),subsampleFactor:1}}findStartIndex(t,n,r){let i=0;for(;i+1<t.length&&t[i+1]<r;)i++;return n[i]}findEndIndex(t,n,r){let i=t.length-1;for(;i-1>=0&&t[i-1]>r;)i--;return n[i]}}const E7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=A7(e);return i?B.jsx(WS,{context:t.timeseriesSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(w7,{dataClient:i,width:n,height:r})})}):null},A7=e=>{const[t,n]=M.useState(null);return M.useEffect(()=>{let r=!0;return Bf.create(e).then(i=>{r&&n(i)}),()=>{r=!1}},[e]),t},C7=25,qm=2*Math.PI,T7={maxElectrodePixelRadius:C7},Vm={},zo=8,M7=()=>({selectedElectrodeIds:[]}),_7=e=>{const{width:t,height:n,electrodes:r,units:i,disableAutoRotate:a,onlyShowSelected:o}=e,{selectedElectrodeIds:u}=M7(),{selectedUnitIds:l,unitIdSelectionDispatch:s}=qr(),{affineTransform:c,handleWheel:f}=Lm(t,n,{shift:!0,alt:!1}),d=M.useMemo(()=>new Set([...l]),[l]),h=i.filter(U=>o?d.has(U.unitId):!0).sort((U,I)=>d.has(U.unitId)&&!d.has(I.unitId)?1:!d.has(U.unitId)&&d.has(I.unitId)?-1:Ct(U.unitId)-Ct(I.unitId)),v=e.maxElectrodePixelRadius||T7.maxElectrodePixelRadius,m=e.colors??hl,D=e.showLabels??!1,p=e.offsetLabels??!1,{convertedElectrodes:g,pixelRadius:y,transform:S}=M.useMemo(()=>jm(t,n,r,"geom",v,{disableAutoRotate:a}),[r,n,v,t,a]),w=Math.sqrt(km(c)),b=M.useCallback((U,I)=>{const L=y*w,G=g.map(X=>{const P=(u||[]).includes(X.e.id),j=!1,H=!1,k=P?H?m.draggedSelected:j?m.selectedHover:m.selected:H?m.dragged:j?m.hover:m.base;return{...X,color:k,textColor:P||j&&!H?m.textDark:m.textLight}});if(U.clearRect(0,0,U.canvas.width,U.canvas.height),G.forEach(X=>{const P=ha(c,{x:X.pixelX,y:X.pixelY});U.fillStyle=X.color,U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.fill()}),U.strokeStyle=hl.border,g.forEach(X=>{const P=ha(c,{x:X.pixelX,y:X.pixelY});U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.stroke()}),D){U.font=`${L}px Arial`,U.textAlign=p?"right":"center",U.textBaseline="middle";const X=p?1.4*L:0;G.forEach(P=>{const j=ha(c,{x:P.pixelX,y:P.pixelY});U.fillStyle=p?m.textDark:P.textColor,U.fillText(`${P.e.label}`,j.x-X,j.y)})}},[m,p,g,y,u,D,c,w]),E=M.useCallback((U,I)=>{const L=zo;U.clearRect(0,0,U.canvas.width,U.canvas.height);const G=(X,P,j)=>{U.fillStyle=j,U.strokeStyle="black",U.beginPath(),U.ellipse(X,P,L,L,0,0,qm),U.fill(),U.stroke()};for(const X of h){const P=Xh(S,[X.x,X.y]),j=ha(c,{x:P[0],y:P[1]}),H=l.size===0||l.has(X.unitId)?wr(Ct(X.unitId)):"rgb(220, 220, 220)";G(j.x,j.y,H)}},[S,h,l,c]),C=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:b,drawData:Vm}),[t,n,b]),A=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:E,drawData:Vm}),[t,n,E]),T=M.useCallback((U,{ctrlKey:I})=>{const L=B7(c,U),G=km(c),X=zo/Math.sqrt(G),P=[];for(const j of h){const H=Xh(S,[j.x,j.y]);Yh(Ff([H[0]-X,H[1]-X,X*2,X*2]),Ff(L))&&(Ff([H[0]-X,H[1]-X,X*2,X*2]),P.push(j.unitId))}if(I)for(const j of P)s({type:"TOGGLE_UNIT",targetUnit:j});else s({type:"SET_SELECTION",incomingSelectedUnitIds:P})},[S,s,h,c]),_=M.useCallback((U,{ctrlKey:I})=>{let L=!1;for(const G of h){const X=Xh(S,[G.x,G.y]);J5(U,Ff([X[0]-zo,X[1]-zo,zo*2,zo*2]))&&(L=!0,s(I?{type:"TOGGLE_UNIT",targetUnit:G.unitId}:{type:"SET_SELECTION",incomingSelectedUnitIds:[G.unitId]}))}L||s({type:"SET_SELECTION",incomingSelectedUnitIds:[]})},[S,s,h]),{onMouseMove:x,onMouseDown:F,onMouseUp:R,paintDragSelectLayer:z}=Hs(t,n,T,_),N=M.useMemo(()=>B.jsx(ir,{width:t,height:n,draw:z,drawData:Vm}),[t,n,z]);return t>0&&n>0?B.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:x,onMouseUp:R,onMouseDown:F,onWheel:f,children:[C,A,N]}):B.jsx("div",{})},Ff=e=>({xmin:e[0],ymin:e[1],xmax:e[0]+e[2],ymax:e[1]+e[3]}),B7=(e,t)=>{const n=$m(e,{x:t[0],y:t[1]}),r=$m(e,{x:t[0]+t[2],y:t[1]+t[3]});return[n.x,n.y,r.x-n.x,r.y-n.y]},F7=e=>{const{data:t,width:n,height:r}=e,[i,a]=M.useState({...xf,onlyShowSelected:!1}),o=30,u=Object.keys(t.channelLocations),l=mN(u,t.channelLocations),s=M.useMemo(()=>({width:n-20,height:r-o,top:0,position:"absolute"}),[n,r]);return B.jsxs("div",{children:[B.jsx("div",{style:s,children:B.jsx(_7,{width:n-20,height:r-o,electrodes:l,units:t.units,disableAutoRotate:t.disableAutoRotate,onlyShowSelected:i.onlyShowSelected})}),B.jsx("div",{style:{position:"absolute",top:r-o,height:o,overflow:"hidden"},children:B.jsx(wf,{options:i,setOptions:a})})]})},N7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.disable_auto_rotate||!1,h=e.attrs.unit_ids,v=e.attrs.channel_locations,m=await e.getDatasetData("coords",{});if(!m||m.length===0)throw new Error("Empty coords data");const D=new Float32Array(m);if(D.length!==h.length*2)throw new Error(`Expected coords length ${h.length*2}, got ${D.length}`);const p=[];for(let g=0;g<h.length;g++)p.push({unitId:h[g],x:D[g*2],y:D[g*2+1]});if(c)return;a({type:"UnitLocations",channelLocations:v,units:p,disableAutoRotate:d})}catch(d){console.error("Error loading unit locations data:",d),u(`Failed to load unit locations data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit locations data..."}):i?B.jsx(Jr,{context:t.unitSelection,children:B.jsx(F7,{data:i,width:n,height:r})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit locations data available"})},R7=({rows:e,columns:t,onDeleteRow:n=void 0,deleteRowLabel:r=void 0,onEditRow:i=void 0,editRowLabel:a=void 0,selectionMode:o="none",selectedRowKeys:u=[],onSelectedRowKeysChanged:l=void 0,selectionDisabled:s})=>{const c=M.useMemo(()=>{const p={};return u.forEach(g=>{p[g]=!0}),p},[u]),[f,d]=M.useState(null),h=M.useCallback(p=>{l&&(o==="single"?!(p in c)||!c[p]?l([p+""]):l([]):o==="multiple"&&l(Object.keys(c).filter(g=>g!=p&&c[g]).concat(c[p]?[]:[p.toString()])))},[l,o,c]),v=M.useCallback(p=>{d(p)},[]),m=M.useCallback((p,g)=>{g&&n&&n(p),d(null)},[n]),D=M.useCallback(p=>{i&&i(p)},[i]);return B.jsxs(mF,{className:"NiceTable",children:[B.jsx(MF,{children:B.jsxs(SS,{children:[B.jsx(Sf,{style:{width:0}},"_first"),t.map(p=>B.jsx(Sf,{children:p.element?p.element:B.jsx("span",{children:p.label})},p.key))]})}),B.jsx(bF,{children:e.map(p=>B.jsxs(SS,{children:[B.jsxs(Sf,{children:[n&&(f===p.key?B.jsx(z7,{title:r||"",onConfirmDeleteRow:m,rowKey:p.key}):B.jsx(O7,{title:r||"",onDeleteRow:v,rowKey:p.key})),i&&B.jsx(U7,{title:a||"",onEditRow:D,rowKey:p.key}),o!=="none"&&B.jsx(hS,{checked:c[p.key]||!1,onClick:()=>h(p.key),disabled:s})]}),t.map(g=>B.jsx(Sf,{children:B.jsx("span",{children:I7(p.columnValues[g.key])})},g.key))]},p.key))})]})},O7=({title:e,rowKey:t,onDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t)},[n,t]);return B.jsx(cl,{title:e,onClick:r,children:B.jsx(YD,{})})},z7=({title:e,rowKey:t,onConfirmDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t,!0)},[n,t]),i=M.useCallback(()=>{n&&n(t,!1)},[n,t]);return B.jsxs("span",{children:["Confirm delete?",B.jsx(cl,{title:e,onClick:r,children:B.jsx(YD,{})}),B.jsx(cl,{title:"Cancel",onClick:i,children:B.jsx(B_,{})})]})},U7=({title:e,rowKey:t,onEditRow:n})=>B.jsx(cl,{title:e,onClick:()=>n&&n(t),children:B.jsx(__,{})}),I7=e=>e==0?e:e?typeof e=="object"?e.element?e.element:e.text||"":e:"",$7=({width:e,height:t})=>{const{selectedUnitMetrics:n,allUnitMetrics:r,unitMetricSelectionDispatch:i}=ch(),a=M.useMemo(()=>[{key:"metric",label:"Metric"}],[]),o=M.useMemo(()=>(r||[]).map(l=>({key:l,columnValues:{metric:l}})),[r]),u=M.useCallback(l=>{i({type:"selectUnitMetrics",unitMetrics:l})},[i]);return B.jsx("div",{style:{position:"absolute",width:e,height:t},children:B.jsx(R7,{rows:o,columns:a,selectedRowKeys:n,onSelectedRowKeysChanged:u,selectionMode:"multiple"})})},k7=(e,t)=>{e.clearRect(0,0,t.width,t.height);for(const n of t.pixelVerticalLines||[])e.strokeStyle=n.color,e.beginPath(),e.moveTo(n.x,t.margins.top-20),e.lineTo(n.x,t.height-t.margins.bottom),e.stroke();t.barBoxes.forEach(n=>{e.fillStyle=n.color,e.fillRect(n.x1,n.y1,n.x2-n.x1,n.y2-n.y1)}),t.xLabel&&(e.textBaseline="bottom",e.textAlign="center",e.fillStyle="black",e.fillText(t.xLabel,t.width/2,t.height-3));for(const n of t.pixelTicks||[])e.strokeStyle="black",e.beginPath(),e.moveTo(n.x,t.height-t.margins.bottom),e.lineTo(n.x,t.height-t.margins.bottom+6),e.stroke(),e.textBaseline="top",e.textAlign="center",e.fillStyle="black",e.fillText(n.label,n.x,t.height-t.margins.bottom+8)},L7=e=>B.jsx(ir,{width:e.width,height:e.height,draw:k7,drawData:e}),j7={},H7=({bars:e,range:t,ticks:n,verticalLines:r,xLabel:i,onSelectRect:a,width:o,height:u})=>{const{xMin:l,xMax:s}=M.useMemo(()=>t?{xMin:t.min,xMax:t.max}:e.length>0?{xMin:e[0].xStart,xMax:e[e.length-1].xEnd}:{xMin:0,xMax:1},[e,t]),c=M.useMemo(()=>Math.max(...e.map(E=>E.height)),[e]),{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v}=M.useMemo(()=>{const E={left:3,right:3,top:5,bottom:3+(i?18:0)+(n?18:0)},C=o-E.left-E.right,A=u-E.top-E.bottom,T=e.map(F=>({key:F.key,x1:E.left+(F.xStart-l)/(s-l)*C,x2:E.left+(F.xEnd-l)/(s-l)*C,y1:E.top+A*(1-F.height/c),y2:E.top+A,tooltip:F.tooltip,color:F.color})),_=n?n.map(F=>({x:E.left+(F.x-l)/(s-l)*C,label:`${F.label}`})):void 0,x=r?r.map(F=>({x:E.left+(F.x-l)/(s-l)*C,color:F.color})):void 0;return{barBoxes:T,margins:E,pixelTicks:_,pixelVerticalLines:x}},[e,n,r,l,s,c,o,u,i]),m=M.useCallback((E,{ctrlKey:C,shiftKey:A})=>{const T=[],_={x:E[0],y:E[1],width:E[2],height:E[3]};for(const z of f)z.x1<=_.x+_.width&&z.x2>=_.x&&T.push(z.key);const x=o-d.left-d.right,F=(_.x-d.left)/x*(s-l)+l,R=(_.x+_.width-d.left)/x*(s-l)+l;a&&a(_,T,{ctrlKey:C,shiftKey:A,xMin:F,xMax:R})},[f,a,d.left,d.right,o,l,s]),D=M.useCallback(()=>{},[]),{onMouseMove:p,onMouseDown:g,onMouseUp:y,onMouseLeave:S,paintDragSelectLayer:w}=Hs(o,u,m,D),b=M.useMemo(()=>B.jsx(ir,{width:o,height:u,draw:w,drawData:j7}),[o,u,w]);return B.jsxs("div",{style:{width:o,height:u,position:"relative"},onMouseDown:g,onMouseMove:p,onMouseUp:y,onMouseLeave:S,children:[B.jsx(L7,{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v,xLabel:i,width:o,height:u}),b]})},P7=(e,t)=>{const n=t-e;let r;n<=30?r=10:n<=120?r=20:n<=300?r=50:n<=600?r=100:n<=1e3?r=150:r=100;const i=[];let a=Math.ceil(e/r);for(;a*r<=t;)i.push(a*r),a++;return i},q7=({metric:e,metricRange:t,units:n,selectedUnitIds:r,setSelectedUnitIds:i,numBins:a,onZoomToRect:o,width:u,height:l})=>{const{bars:s,ticks:c,verticalLines:f}=M.useMemo(()=>{const h=n.map(p=>p.values[e.key]).filter(p=>p!==void 0).map(p=>p),v=n.filter(p=>r.has(p.unitId)).map(p=>p.values[e.key]).filter(p=>p!==void 0).map(p=>p),D=n.filter(p=>r.has(p.unitId)).map(p=>({unitId:p.unitId,value:p.values[e.key]})).filter(p=>p.value!==void 0).map(p=>p.unitId).map(p=>wr(Ct(p)));return V7(h,v,D,a||10)},[n,e,r,a]),d=M.useCallback((h,v,{ctrlKey:m,shiftKey:D,xMin:p,xMax:g})=>{if(D){o&&o({x:p,y:h.y,width:g-p,height:h.height});return}if(v.length===0)return;const y=[];for(const E of v){const C=s[E];y.push(C)}const S=Math.min(...y.map(E=>E.xStart)),w=Math.max(...y.map(E=>E.xEnd)),b=[];for(const E of n){const C=E.values[e.key];C!==void 0&&S<=C&&C<=w&&b.push(E.unitId)}i(m||D?[...new Set([...r,...b])]:b)},[s,e,r,i,n,o]);return B.jsx(H7,{width:u,height:l,bars:s,range:t,ticks:c,verticalLines:f,onSelectRect:d})},V7=(e,t,n,r)=>{if(e.length===0)return{bars:[],ticks:[],verticalLines:[]};let i=Math.min(...e),a=Math.max(...e);if(a<=i)return{bars:[],ticks:[],verticalLines:[]};i-=(a-i)/r/2,a+=(a-i)/r/2;const o=[];for(let f=0;f<r;f++)o.push(0);for(const f of e){const d=Math.min(Math.floor((f-i)/(a-i)*r),r-1);o[d]++}const u=[];for(let f=0;f<r;f++)u.push(0);for(const f of t){const d=Math.min(Math.floor((f-i)/(a-i)*r),r-1);u[d]++}const l=[];t.forEach((f,d)=>{l.push({x:f,color:n[d]})});const c=G7(i,a).map(f=>({x:f,label:`${f}`}));return{bars:[...o.map((f,d)=>({key:d,xStart:i+d*(a-i)/r,xEnd:i+(d+1)*(a-i)/r,height:f,tooltip:"",color:"gray"}))],ticks:c,verticalLines:l}},G7=(e,t)=>{const n=t-e;if(n<=0)return[];let r=1;for(;n*r<100;)r*=10;for(;n*r>=1e3;)r/=10;return P7(e*r,t*r).map(i=>i/r)},Y7=(e,t)=>{e.clearRect(0,0,t.width,t.height),t.markers.forEach(n=>{const r=t.coord2Pixel({x:n.x,y:n.y});e.fillStyle=n.color,e.strokeStyle="black",e.beginPath(),e.ellipse(r.x,r.y,n.radius,n.radius,0,0,2*Math.PI),e.fill(),e.stroke()})},X7=e=>B.jsx(ir,{width:e.width,height:e.height,draw:Y7,drawData:e}),Z7={},Q7=({markers:e,xRange:t,yRange:n,onSelectRect:r,onClickPoint:i,width:a,height:o})=>{const{margins:u}=M.useMemo(()=>({margins:{left:20,right:20,top:20,bottom:20}}),[]),{xMin:l,xMax:s,yMin:c,yMax:f}=M.useMemo(()=>{let b,E,C,A;return t?(b=t.min,E=t.max):e.length>0?(b=Math.min(...e.map(T=>T.x)),E=Math.max(...e.map(T=>T.x))):(b=0,E=1),n?(C=n.min,A=n.max):e.length>0?(C=Math.min(...e.map(T=>T.y)),A=Math.max(...e.map(T=>T.y))):(C=0,A=1),{xMin:b,xMax:E,yMin:C,yMax:A}},[e,t,n]),{coord2Pixel:d,pixel2Coord:h}=M.useMemo(()=>{const b=a-u.left-u.right,E=o-u.top-u.bottom;return{coord2Pixel:T=>({x:u.left+(T.x-l)/(s-l)*b,y:u.top+(1-(T.y-c)/(f-c))*E}),pixel2Coord:T=>({x:l+(T.x-u.left)/b*(s-l),y:c+(1-(T.y-u.top)/E)*(f-c)})}},[a,o,u,l,s,c,f]),v=M.useCallback((b,{ctrlKey:E,shiftKey:C})=>{const A={x:b[0],y:b[1],width:b[2],height:b[3]},T=[];for(const x of e){const F=d({x:x.x,y:x.y}),R={xmin:F.x-x.radius,ymin:F.y-x.radius,xmax:F.x+x.radius,ymax:F.y+x.radius};Yh({xmin:A.x,xmax:A.x+A.width,ymin:A.y,ymax:A.y+A.height},R)&&T.push(x.key)}const _=K7(h,A);r&&r(_,T,{ctrlKey:E,shiftKey:C})},[r,h,e,d]),m=M.useCallback((b,{ctrlKey:E,shiftKey:C})=>{const A={x:b[0],y:b[1]},T={x:A.x,y:A.y,width:1,height:1};let _;for(const x of e){const F=d({x:x.x,y:x.y}),R={xmin:F.x-x.radius,ymin:F.y-x.radius,xmax:F.x+x.radius,ymax:F.y+x.radius};Yh({xmin:T.x,xmax:T.x+T.width,ymin:T.y,ymax:T.y+T.height},R)&&(_=x.key)}i&&i(h(A),_,{ctrlKey:E,shiftKey:C})},[d,e,i,h]),{onMouseMove:D,onMouseDown:p,onMouseUp:g,onMouseLeave:y,paintDragSelectLayer:S}=Hs(a,o,v,m),w=M.useMemo(()=>B.jsx(ir,{width:a,height:o,draw:S,drawData:Z7}),[a,o,S]);return B.jsxs("div",{style:{width:a,height:o,position:"relative"},onMouseDown:p,onMouseMove:D,onMouseUp:g,onMouseLeave:y,children:[B.jsx(X7,{markers:e,margins:u,coord2Pixel:d,width:a,height:o}),w]})},K7=(e,t)=>{const n=e({x:t.x,y:t.y}),r=e({x:t.x+t.width,y:t.y+t.height});return{x:Math.min(n.x,r.x),y:Math.min(n.y,r.y),width:Math.abs(r.x-n.x),height:Math.abs(r.y-n.y)}},W7=({metric1:e,metric2:t,metric1Range:n,metric2Range:r,units:i,selectedUnitIds:a,setSelectedUnitIds:o,onZoomToRect:u,width:l,height:s})=>{const f=M.useMemo(()=>{const v=[];for(const m of i){const D=m.values[e.key],p=m.values[t.key];D!==void 0&&p!==void 0&&v.push({key:m.unitId,x:D,y:p,color:a.has(m.unitId)?wr(Ct(m.unitId)):"lightgray",radius:6,tooltip:`Unit ${m.unitId}`})}return v},[i,e,t,a]),d=M.useCallback((v,m,{ctrlKey:D,shiftKey:p})=>{if(p){u&&u(v);return}let g=m;D&&(g=[...new Set([...m,...a])]),o(g)},[o,a,u]),h=M.useCallback((v,m,{ctrlKey:D,shiftKey:p})=>{let g;if(D||p){const y=new Set([...a]);m!==void 0&&(y.has(m)?y.delete(m):y.add(m)),g=[...y]}else m===void 0?g=[]:g=[m];o(g)},[o,a]);return B.jsx(Q7,{width:l,height:s,markers:f,xRange:n,yRange:r,onSelectRect:d,onClickPoint:h})},J7=({type:e,metric1:t,metric2:n,metric1Range:r,metric2Range:i,units:a,selectedUnitIds:o,setSelectedUnitIds:u,numHistogramBins:l,onZoomToRect:s,width:c,height:f})=>{if(e==="histogram"){if(!t)throw Error("Unexpected: metric1 not defined");return B.jsx(q7,{metric:t,metricRange:r,units:a,selectedUnitIds:o,setSelectedUnitIds:u,numBins:l,onZoomToRect:s,width:c,height:f})}else if(e==="scatter"){if(!t)throw Error("Unexpected: metric1 not defined");if(!n)throw Error("Unexpected: metric2 not defined");return B.jsx(W7,{metric1:t,metric2:n,metric1Range:r,metric2Range:i,units:a,selectedUnitIds:o,setSelectedUnitIds:u,onZoomToRect:s,width:c,height:f})}else{if(e==="bottom-label")return B.jsx("div",{style:{width:c,textAlign:"center"},children:t?.label||B.jsx("span",{children:" "})});if(e==="left-label")return B.jsx("div",{style:{width:c,height:f,overflow:"hidden",writingMode:"vertical-lr",transform:"rotate(-180deg)",textAlign:"center"},children:t?.label||B.jsx("span",{children:" "})});throw Error(`Unexpected type: ${e}`)}},eR=({data:e,width:t,height:n})=>{const{units:r,metrics:i}=e,{selectedUnitIds:a,unitIdSelectionDispatch:o}=qr(),{selectedUnitMetrics:u}=ch(),[l,s]=M.useState(1),[c,f]=M.useState(10),[d,h]=M.useState({}),v=M.useMemo(()=>r.sort((g,y)=>a.has(g.unitId)&&!a.has(y.unitId)?1:!a.has(g.unitId)&&a.has(y.unitId)?-1:Ct(g.unitId)-Ct(y.unitId)),[r,a]);M.useEffect(()=>{o({type:oo,newUnitOrder:yr(v.map(g=>g.unitId))})},[v,o]);const m=M.useMemo(()=>{const g=u.length===0?[{type:"text",content:"Box size",title:"Set box size"},{type:"button",callback:()=>s(w=>w*1.3),title:"Increase box size",icon:B.jsx(Tc,{})},{type:"button",callback:()=>s(w=>w/1.3),title:"Decrease box size",icon:B.jsx(Cc,{})}]:[],y=[{type:"text",content:"# bins",title:""},{type:"button",callback:()=>f(w=>w+5),title:"Increase num. histogram bins",icon:B.jsx(Tc,{})},{type:"button",callback:()=>f(w=>Math.max(5,w-5)),title:"Decrease num. histogram bins",icon:B.jsx(Cc,{})}],S={type:"button",callback:()=>h({}),title:"Reset zoom",text:"reset"};return[...g,{type:"divider"},...y,{type:"divider"},S]},[u.length]),D=fl,p=M.useMemo(()=>{const g=y=>{o({type:"SET_SELECTION",incomingSelectedUnitIds:y})};if(u.length===0)return i.map(y=>{const S={type:"histogram",metric1:y,metric2:y,metric1Range:d[y.key],metric2Range:d[y.key],units:v,width:400*l,height:400*l,numHistogramBins:c,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:b=>{h({...d,[y.key]:{min:b.x,max:b.x+b.width}})}};return{key:y.key,label:y.label,unitId:"",labelColor:"black",props:S}});{const{plotWidth:w,plotHeight:b}=PS(t-D-30-10,n-30-10,u.length),E=[];for(const C of u){const A=i.filter(T=>T.key===C)[0];{const T={type:"left-label",metric1:A,metric2:A,units:v,numHistogramBins:c,width:30,height:b,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`left-label-${C}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}for(const T of u){const _=i.filter(x=>x.key===T)[0];if(A&&_){const x={type:C===T?"histogram":"scatter",metric1:_,metric2:A,metric1Range:d[_.key],metric2Range:d[A.key],units:v,numHistogramBins:c,width:w,height:b,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:F=>{h(C!==T?{...d,[_.key]:{min:F.x,max:F.x+F.width},[A.key]:{min:F.y,max:F.y+F.height}}:{...d,[A.key]:{min:F.x,max:F.x+F.width}})}};E.push({key:`${T}-${C}`,label:x.type==="histogram"?C:void 0,unitId:"",labelColor:"black",props:x})}}}{const C={type:"bottom-label",metric1:void 0,metric2:void 0,units:v,numHistogramBins:c,width:30,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:"left-bottom-label",label:void 0,unitId:"",labelColor:"black",props:C,hideBorderColor:!0})}for(const C of u){const A=i.filter(_=>_.key===C)[0],T={type:"bottom-label",metric1:A,metric2:A,units:v,numHistogramBins:c,width:w,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`bottom-label-${C}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}return E}},[i,a,v,l,u,c,t,n,o,d,D]);return B.jsxs(Ro,{width:t,height:n,initialPosition:D,adjustable:!1,children:[B.jsx(dl,{width:D,height:n,customActions:m}),B.jsx(wc,{width:0,height:0,disableScroll:u.length>0,children:B.jsx(xc,{plots:p,plotComponent:J7,numPlotsPerRow:u.length===0?void 0:u.length+1})})]})},tR=({data:e,width:t,height:n})=>{const{metrics:r}=e,{unitMetricSelectionDispatch:i}=ch();return M.useEffect(()=>{i({type:"initialize",unitMetrics:r.map(a=>a.key)})},[r,i]),B.jsxs(Ro,{width:t,height:n,initialPosition:200,adjustable:!0,children:[B.jsx($7,{width:0,height:0}),B.jsx(eR,{data:e,width:0,height:0})]})},nR=e=>js(e,{key:Ls,label:Ls,dtype:Ls}),rR=e=>js(e,{unitId:OA([RA,Ls]),values:()=>!0}),iR=e=>js(e,{type:zA("UnitMetricsGraph"),metrics:Cy(nR),units:Cy(rR)}),aR=({zarrGroup:e,contexts:t,width:n,height:r})=>{const[i,a]=M.useState(null),[o,u]=M.useState(null),[l,s]=M.useState(!0);return M.useEffect(()=>{let c=!1;return(async()=>{try{s(!0),u(null);const d=e.attrs.metrics||[],h=await e.getDatasetData("units_data",{});if(!h||h.length===0)throw new Error("Empty units data");const v=new Uint8Array(h),m=new TextDecoder("utf-8").decode(v),D=JSON.parse(m);if(c)return;const p={type:"UnitMetricsGraph",metrics:d,units:D.map(g=>({unitId:g.unit_id,values:g.values}))};if(!iR(p))throw new Error("Invalid view data structure");a(p)}catch(d){console.error("Error loading unit metrics graph data:",d),u(`Failed to load unit metrics graph data: ${d instanceof Error?d.message:String(d)}`)}finally{s(!1)}})(),()=>{c=!0}},[e]),o?B.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit metrics data..."}):i?B.jsx(oR,{context:t.unitMetricSelection,children:B.jsx(Jr,{context:t.unitSelection,children:B.jsx(tR,{data:i,width:n,height:r})})}):B.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit metrics data available"})},oR=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?B.jsx(B.Fragment,{children:"Waiting for unit metric selection context..."}):B.jsx(hy.Provider,{value:{unitMetricSelection:n,unitMetricSelectionDispatch:r},children:t})},JS=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=eA(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:JS}},ex=()=>{const e={current:Sy},t=[];return{stateRef:e,dispatch:i=>{e.current=TA(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:ex}},tx=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=Af(e.current,i),t.forEach(a=>{a(e.current)})},onChange:i=>(t.push(i),()=>{const a=t.indexOf(i);a>=0&&t.splice(a,1)}),createNew:tx}},uR=({zarrGroup:e,width:t,height:n,onResize:r,onDataChange:i,contexts:a,component:o})=>{const[u,l]=M.useState(t),[s,c]=M.useState(n),[f,d]=M.useState(e);return M.useEffect(()=>{r((h,v)=>{l(h),c(v)}),i(h=>{d(h)})},[r,i]),B.jsx(o,{zarrGroup:f,width:u,height:s,contexts:a})},lR=e=>t=>{const{container:n,zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l}=t;JE.createRoot(n).render(B.jsx(uR,{zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l,component:e}))};(()=>{const e=[{name:"spike_sorting.Autocorrelograms",component:YF},{name:"spike_sorting.AverageWaveforms",component:UN},{name:"spike_sorting.CrossCorrelograms",component:kN},{name:"spike_sorting.RasterPlot",component:S7},{name:"spike_sorting.SpikeAmplitudes",component:E7},{name:"spike_sorting.UnitLocations",component:N7},{name:"spike_sorting.UnitMetricsGraph",component:aR},{name:"spike_sorting.UnitsTable",component:iN},{name:"spike_sorting.SortingCuration",component:nN}],t=window.figpack_p1.registerFPViewComponent;for(const i of e)t({name:i.name,render:lR(i.component)});const n=window.figpack_p1.registerFPViewContextCreator;n({name:"unitSelection",create:ex}),n({name:"unitMetricSelection",create:JS}),n({name:"sortingCuration",create:tx});const r=window.figpack_p1.registerFPExtension;r({name:"figpack-spike-sorting"})})()})();
@@ -71,14 +71,14 @@ class Autocorrelograms(figpack.ExtensionView):
71
71
  view = Autocorrelograms(autocorrelograms=ac_items)
72
72
  return view
73
73
 
74
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
74
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
75
75
  """
76
76
  Write the Autocorrelograms data to a Zarr group
77
77
 
78
78
  Args:
79
79
  group: Zarr group to write data into
80
80
  """
81
- super()._write_to_zarr_group(group)
81
+ super().write_to_zarr_group(group)
82
82
 
83
83
  # Store the number of autocorrelograms
84
84
  num_autocorrelograms = len(self.autocorrelograms)
@@ -100,14 +100,14 @@ class AverageWaveforms(figpack.ExtensionView):
100
100
  view = AverageWaveforms(average_waveforms=average_waveform_items)
101
101
  return view
102
102
 
103
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
103
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
104
104
  """
105
105
  Write the AverageWaveforms data to a Zarr group
106
106
 
107
107
  Args:
108
108
  group: Zarr group to write data into
109
109
  """
110
- super()._write_to_zarr_group(group)
110
+ super().write_to_zarr_group(group)
111
111
 
112
112
  # Store the number of average waveforms
113
113
  group.attrs["num_average_waveforms"] = len(self.average_waveforms)
@@ -80,14 +80,14 @@ class CrossCorrelograms(figpack.ExtensionView):
80
80
  view = CrossCorrelograms(cross_correlograms=cc_items, hide_unit_selector=False)
81
81
  return view
82
82
 
83
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
83
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
84
84
  """
85
85
  Write the CrossCorrelograms data to a Zarr group
86
86
 
87
87
  Args:
88
88
  group: Zarr group to write data into
89
89
  """
90
- super()._write_to_zarr_group(group)
90
+ super().write_to_zarr_group(group)
91
91
 
92
92
  # Set view properties
93
93
  if self.hide_unit_selector is not None:
@@ -109,12 +109,12 @@ class RasterPlot(figpack.ExtensionView):
109
109
  else:
110
110
  return view
111
111
 
112
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
112
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
113
113
  """
114
114
  Args:
115
115
  group: Zarr group to write data into
116
116
  """
117
- super()._write_to_zarr_group(group)
117
+ super().write_to_zarr_group(group)
118
118
 
119
119
  # Store view parameters
120
120
  group.attrs["start_time_sec"] = self.start_time_sec
@@ -26,12 +26,12 @@ class SortingCuration(figpack.ExtensionView):
26
26
  self.default_label_options = default_label_options
27
27
  self.curation = curation
28
28
 
29
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
29
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
30
30
  """
31
31
  Args:
32
32
  group: Zarr group to write data into
33
33
  """
34
- super()._write_to_zarr_group(group)
34
+ super().write_to_zarr_group(group)
35
35
 
36
36
  # Store view parameters
37
37
  group.attrs["default_label_options"] = self.default_label_options
@@ -116,14 +116,14 @@ class SpikeAmplitudes(figpack.ExtensionView):
116
116
  else:
117
117
  return view
118
118
 
119
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
119
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
120
120
  """
121
121
  Write the SpikeAmplitudes data to a Zarr group using unified storage format
122
122
 
123
123
  Args:
124
124
  group: Zarr group to write data into
125
125
  """
126
- super()._write_to_zarr_group(group)
126
+ super().write_to_zarr_group(group)
127
127
 
128
128
  # Store view parameters
129
129
  group.attrs["start_time_sec"] = self.start_time_sec
@@ -51,14 +51,14 @@ class UnitLocations(figpack.ExtensionView):
51
51
  self.channel_locations = channel_locations
52
52
  self.disable_auto_rotate = disable_auto_rotate
53
53
 
54
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
54
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
55
55
  """
56
56
  Write the UnitLocations data to a Zarr group
57
57
 
58
58
  Args:
59
59
  group: Zarr group to write data into
60
60
  """
61
- super()._write_to_zarr_group(group)
61
+ super().write_to_zarr_group(group)
62
62
 
63
63
  channel_locations = {}
64
64
  for channel_id, loc in self.channel_locations.items():
@@ -101,14 +101,14 @@ class UnitMetricsGraph(figpack.ExtensionView):
101
101
  self.metrics = metrics
102
102
  self.height = height
103
103
 
104
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
104
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
105
105
  """
106
106
  Write the UnitMetricsGraph data to a Zarr group
107
107
 
108
108
  Args:
109
109
  group: Zarr group to write data into
110
110
  """
111
- super()._write_to_zarr_group(group)
111
+ super().write_to_zarr_group(group)
112
112
 
113
113
  # Set view properties
114
114
  if self.height is not None:
@@ -44,14 +44,14 @@ class UnitsTable(figpack.ExtensionView):
44
44
  self.similarity_scores = similarity_scores or []
45
45
  self.height = height
46
46
 
47
- def _write_to_zarr_group(self, group: figpack.Group) -> None:
47
+ def write_to_zarr_group(self, group: figpack.Group) -> None:
48
48
  """
49
49
  Write the UnitsTable data to a Zarr group
50
50
 
51
51
  Args:
52
52
  group: Zarr group to write data into
53
53
  """
54
- super()._write_to_zarr_group(group)
54
+ super().write_to_zarr_group(group)
55
55
 
56
56
  # Set view properties
57
57
  if self.height is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: figpack_spike_sorting
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Spike Sorting specific extension for figpack
5
5
  Home-page: https://github.com/flatironinstitute/figpack
6
6
  Author: figpack contributors
@@ -17,7 +17,7 @@ def read_readme():
17
17
 
18
18
  setup(
19
19
  name="figpack_spike_sorting",
20
- version="0.1.3",
20
+ version="0.1.5",
21
21
  description="Spike Sorting specific extension for figpack",
22
22
  long_description=read_readme(),
23
23
  long_description_content_type="text/markdown",