figpack-spike-sorting 0.1.6__tar.gz → 0.1.7__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.
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/PKG-INFO +1 -1
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/__init__.py +1 -1
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/figpack_spike_sorting.js +1 -1
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting.egg-info/PKG-INFO +1 -1
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/setup.py +1 -1
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/README.md +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/spike_sorting_extension.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/style.css +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/AutocorrelogramItem.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/Autocorrelograms.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/AverageWaveforms.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/CrossCorrelogramItem.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/CrossCorrelograms.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/RasterPlot.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/RasterPlotItem.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/SortingCuration.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/SpikeAmplitudes.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/SpikeAmplitudesItem.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitLocations.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitMetricsGraph.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitSimilarityScore.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitsTable.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitsTableColumn.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/UnitsTableRow.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/__init__.py +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting.egg-info/SOURCES.txt +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting.egg-info/dependency_links.txt +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting.egg-info/requires.txt +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting.egg-info/top_level.txt +0 -0
- {figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/setup.cfg +0 -0
|
@@ -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,OB=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,FB,t)},zB=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:NB||{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}}))]}))),UB=wt("svg",{name:"MuiCircularProgress",slot:"Svg"})({display:"block"}),IB=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:RB||{animation:`${Um} 1.4s ease-in-out infinite`}}]}))),$B=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=OB(h),m={},S={},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`,S.transform="rotate(-90deg)"}return _.jsx(zB,{className:at(v.root,i),style:{width:u,height:u,...S,...l},ownerState:h,ref:n,role:"progressbar",...p,...d,children:_.jsx(UB,{className:v.svg,ownerState:h,viewBox:`${Ui/2} ${Ui/2} ${Ui} ${Ui}`,children:_.jsx(IB,{className:v.circle,style:m,ownerState:h,cx:Ui,cy:Ui,r:(Ui-s)/2,fill:"none",strokeWidth:s})})})});function kB(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"]),LB=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,kB,t)},jB=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"}}))),HB=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=i9(f),S=h??_.jsx($B,{"aria-labelledby":m,color:"inherit",size:16}),p={...r,edge:i,color:u,disabled:l,disableFocusRipple:s,loading:d,loadingIndicator:S,size:c},g=LB(p);return _.jsxs(jB,{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"&&_.jsx("span",{className:g.loadingWrapper,style:{display:"contents"},children:_.jsx(HB,{className:g.loadingIndicator,ownerState:p,children:d&&S})}),a]})});function PB({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 qB=M.createContext(void 0);function fS(){return M.useContext(qB)}function VB(e){return yn("PrivateSwitchBase",e)}bn("PrivateSwitchBase",["root","checked","disabled","input","edgeStart","edgeEnd"]);const GB=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,VB,t)},YB=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}}]}),XB=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:S,onFocus:p,readOnly:g,required:y=!1,tabIndex:D,type:w,value:b,slots:E={},slotProps:A={},...C}=t,[T,B]=Q9({controlled:i,default:!!o}),x=fS(),R=$=>{p&&p($),x&&x.onFocus&&x.onFocus($)},F=$=>{m&&m($),x&&x.onBlur&&x.onBlur($)},z=$=>{if($.nativeEvent.defaultPrevented)return;const q=$.target.checked;B(q),S&&S($,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=GB(I),X={slots:E,slotProps:{input:d,...A}},[Z,P]=Fo("root",{ref:n,elementType:YB,className:L.root,shouldForwardComponentProp:!0,externalForwardedProps:{...X,component:"span",...C},getSlotProps:$=>({...$,onFocus:q=>{$.onFocus?.(q),R(q)},onBlur:q=>{$.onBlur?.(q),F(q)}}),ownerState:I,additionalProps:{centerRipple:!0,focusRipple:!l,disabled:N,role:void 0,tabIndex:null}}),[j,Y]=Fo("input",{ref:h,elementType:XB,className:L.input,externalForwardedProps:X,getSlotProps:$=>({...$,onChange:q=>{$.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:D,type:w,...w==="checkbox"&&b===void 0?{}:{value:b}}});return _.jsxs(Z,{...P,children:[_.jsx(j,{...Y}),T?a:c]})}),ZB=Mm(_.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"})),QB=Mm(_.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"})),KB=Mm(_.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 WB(e){return yn("MuiCheckbox",e)}const Im=bn("MuiCheckbox",["root","checked","disabled","indeterminate","colorPrimary","colorSecondary","sizeSmall","sizeMedium"]),JB=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,WB,t);return{...t,...o}},eF=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"}}}}]}))),tF=_.jsx(QB,{}),nF=_.jsx(ZB,{}),rF=_.jsx(KB,{}),hS=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiCheckbox"}),{checkedIcon:i=tF,color:a="primary",icon:o=nF,indeterminate:u=!1,indeterminateIcon:l=rF,inputProps:s,size:c="medium",disableRipple:f=!1,className:d,slots:h={},slotProps:v={},...m}=r,S=u?l:o,p=u?l:i,g={...r,disableRipple:f,color:a,indeterminate:u,size:c},y=JB(g),D=v.input??s,[w,b]=Fo("root",{ref:n,elementType:eF,className:at(y.root,d),shouldForwardComponentProp:!0,externalForwardedProps:{slots:h,slotProps:v,...m},ownerState:g,additionalProps:{type:"checkbox",icon:M.cloneElement(S,{fontSize:S.props.fontSize??c}),checkedIcon:M.cloneElement(p,{fontSize:p.props.fontSize??c}),disableRipple:f,slots:h,slotProps:{input:W9(typeof D=="function"?D(g):D,{"data-indeterminate":u})}}});return _.jsx(w,{...b,classes:y})});function iF(e){return yn("MuiFormGroup",e)}bn("MuiFormGroup",["root","row","error"]);const aF=e=>{const{classes:t,row:n,error:r}=e;return Un({root:["root",n&&"row",r&&"error"]},iF,t)},oF=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"}}]}),uF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiFormGroup"}),{className:i,row:a=!1,...o}=r,u=fS(),l=PB({props:r,muiFormControl:u,states:["error"]}),s={...r,row:a,error:l.error},c=aF(s);return _.jsx(oF,{className:at(c.root,i),ownerState:s,ref:n,...o})});function lF(e){return yn("MuiSwitch",e)}const on=bn("MuiSwitch",["root","edgeStart","edgeEnd","switchBase","colorPrimary","colorSecondary","sizeSmall","sizeMedium","checked","disabled","input","thumb","track"]),sF=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,lF,t);return{...t,...l}},cF=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)"}}}}]}),fF=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}}}))]}))),dF=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}`}))),hF=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=sF(d),v={slots:s,slotProps:c},[m,S]=Fo("root",{className:at(h.root,i),elementType:cF,externalForwardedProps:v,ownerState:d,additionalProps:{sx:l}}),[p,g]=Fo("thumb",{className:h.thumb,elementType:hF,externalForwardedProps:v,ownerState:d}),y=_.jsx(p,{...g}),[D,w]=Fo("track",{className:h.track,elementType:dF,externalForwardedProps:v,ownerState:d});return _.jsxs(m,{...S,children:[_.jsx(fF,{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}}}),_.jsx(D,{...w})]})}),pS=M.createContext();function mF(e){return yn("MuiTable",e)}bn("MuiTable",["root","stickyHeader"]);const pF=e=>{const{classes:t,stickyHeader:n}=e;return Un({root:["root",n&&"stickyHeader"]},mF,t)},gF=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",vF=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=pF(c),d=M.useMemo(()=>({padding:o,size:u,stickyHeader:l}),[o,u,l]);return _.jsx(pS.Provider,{value:d,children:_.jsx(gF,{as:a,role:a===gS?null:"table",ref:n,className:at(f.root,i),ownerState:c,...s})})}),Df=M.createContext();function yF(e){return yn("MuiTableBody",e)}bn("MuiTableBody",["root"]);const bF=e=>{const{classes:t}=e;return Un({root:["root"]},yF,t)},DF=wt("tbody",{name:"MuiTableBody",slot:"Root"})({display:"table-row-group"}),SF={variant:"body"},vS="tbody",xF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableBody"}),{className:i,component:a=vS,...o}=r,u={...r,component:a},l=bF(u);return _.jsx(Df.Provider,{value:SF,children:_.jsx(DF,{className:at(l.root,i),as:a,ref:n,role:a===vS?null:"rowgroup",ownerState:u,...o})})});function wF(e){return yn("MuiTableCell",e)}const EF=bn("MuiTableCell",["root","head","body","footer","sizeSmall","sizeMedium","paddingCheckbox","paddingNone","alignLeft","alignCenter","alignRight","alignJustify","stickyHeader"]),AF=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,wF,t)},CF=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",[`&.${EF.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 S;o?S=o:S=m?"th":"td";let p=l;S==="td"?p=void 0:!p&&m&&(p="col");const g=f||v&&v.variant,y={...r,align:i,component:S,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},D=AF(y);let w=null;return c&&(w=c==="asc"?"ascending":"descending"),_.jsx(CF,{as:S,ref:n,className:at(D.root,a),"aria-sort":w,scope:p,ownerState:y,...d})});function TF(e){return yn("MuiTableHead",e)}bn("MuiTableHead",["root"]);const MF=e=>{const{classes:t}=e;return Un({root:["root"]},TF,t)},_F=wt("thead",{name:"MuiTableHead",slot:"Root"})({display:"table-header-group"}),BF={variant:"head"},yS="thead",FF=M.forwardRef(function(t,n){const r=$n({props:t,name:"MuiTableHead"}),{className:i,component:a=yS,...o}=r,u={...r,component:a},l=MF(u);return _.jsx(Df.Provider,{value:BF,children:_.jsx(_F,{as:a,className:at(l.root,i),ref:n,role:a===yS?null:"rowgroup",ownerState:u,...o})})});function NF(e){return yn("MuiTableRow",e)}const bS=bn("MuiTableRow",["root","selected","hover","head","footer"]),RF=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"]},NF,t)},OF=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=RF(c);return _.jsx(OF,{as:a,ref:n,className:at(f.root,i),role:a===DS?null:"row",ownerState:c,...l})}),zF={paddingLeft:0,paddingRight:0,paddingTop:1,paddingBottom:1},fl=35,UF=e=>{const t=e.selected?"secondary":"inherit";return _.jsx("span",{title:e.title,children:e.icon?_.jsx(cl,{title:e.title,onClick:e.onClick,color:t,style:zF,disabled:!!e.disabled,sx:{fontSize:18},children:e.icon},e.elementIndex):_.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")},IF=e=>e.useHorizontalLayout?_.jsx(_.Fragment,{}):_.jsx("hr",{},e.elementIndex),$F=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)},kF=e=>{switch(e.subtype){case"checkbox":return _.jsx(LF,{...e});case"slider":return _.jsx(jF,{...e});default:return _.jsxs("span",{children:["ERROR: Bad toggle subtype ",e.subtype]},e.elementIndex)}},LF=e=>_.jsx(hS,{checked:e.selected,onClick:e.onClick,style:{padding:0,paddingLeft:0},title:e.title,disabled:e.disabled},e.elementIndex),jF=e=>_.jsx(uF,{children:_.jsx(mS,{checked:e.selected,size:"small",style:{left:-3},onChange:e.onClick,disabled:e.disabled,title:e.title})},e.elementIndex),HF=e=>{switch(e.type){case"button":return _.jsx(UF,{...e});case"divider":return _.jsx(IF,{...e});case"text":return _.jsx($F,{...e});case"toggle":return _.jsx(kF,{...e});default:return _.jsx("span",{},e.elementIndex)}},PF=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(()=>PF(e.customActions),[e.customActions]),n=M.useMemo(()=>t.map((a,o)=>_.jsx(HF,{...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 _.jsx("div",{className:i,style:{...r},children:n})},xf={onlyShowSelected:!1},wf=({options:e,setOptions:t,onRedistributeUnitColors:n})=>_.jsxs("div",{children:[_.jsx(mS,{checked:e.onlyShowSelected,onClick:()=>{t({...e,onlyShowSelected:!e.onlyShowSelected})}}),_.jsx("span",{style:{position:"relative",top:2,overflow:"hidden"},children:"only show selected"})," ",n&&_.jsx("button",{onClick:n,title:"Redistribute unit colors",children:"rc"})]}),qF=(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(()=>qF(u,l).map(f=>({x:f,label:`${f}`})),[u,l]);return t?_.jsx(g_,{bars:o,ticks:a?void 0:s,width:r,height:i,xLabel:a?void 0:"dt (msec)"}):_.jsx("div",{style:{position:"relative",width:r,height:i,color:"orange"}})},VF=10,GF=4,YF=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}),[S,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,D;if(!Array.isArray(e.children))y=e.children,D=null;else{const X=e.children.filter(Z=>Z!==void 0);y=X[0]||null,D=X[1]||null}if(y||(y=D,D=null),!y)throw Error("Splitter must have at least one child.");const w=u?s-c:c,b=o?e.gripThickness??VF:0,E=o?e.gripInnerThickness??GF:0,A=o?e.gripMargin??YF:0,C=w-b/2-A,T=s-C-b-2*A,B={top:0,left:0,width:n,height:r,overflow:"hidden"},x={left:0,top:0,width:l==="horizontal"?C:n,height:l==="horizontal"?r:C,zIndex:0,overflowY:l==="horizontal"?"auto":"hidden",overflowX:l==="horizontal"?"hidden":"auto"},R={left:l==="horizontal"?C+b+2*A:0,top:l==="horizontal"?0:C+b+2*A,width:l==="horizontal"?T:n,height:l==="horizontal"?r:T,zIndex:0,overflowY:l==="horizontal"?"auto":"hidden",overflowX:l==="horizontal"?"hidden":"auto"},F={left:0,top:0,width:l==="horizontal"?b+2*A:n,height:l==="horizontal"?r:b+2*A,backgroundColor:"transparent",cursor:l==="horizontal"?"col-resize":"row-resize",zIndex:9998},z={left:l==="horizontal"?A:0,top:l==="horizontal"?0:A,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(X=>{X.preventDefault(),h(!0),m({x:X.clientX,y:X.clientY}),p(w)},[w]),I=M.useCallback(X=>{if(!d)return;const Z=X.clientX-v.x,P=X.clientY-v.y;let Y=S+(l==="horizontal"?Z:P);const $=4,q=s-4;Y=Math.max($,Math.min(q,Y));const V=u?s-Y:Y;f(V),a&&a(V)},[d,v,S,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]),D?_.jsxs("div",{className:"splitter",style:{...B,position:"relative"},children:[_.jsx("div",{style:{...x,position:"absolute"},className:"SplitterChild",children:_.jsx(y.type,{...y.props,width:l==="horizontal"?C:n,height:l==="horizontal"?r:C})},"child1"),o&&_.jsx("div",{ref:g,style:{...F,position:"absolute",left:l==="horizontal"?w-b/2-A:0,top:l==="horizontal"?0:w-b/2-A},onMouseDown:U,children:_.jsx("div",{style:{...z,position:"absolute"},children:_.jsx("div",{style:{...N,position:"absolute"}})})},"drag"),_.jsx("div",{style:{...R,position:"absolute"},className:"SplitterChild",children:_.jsx(D.type,{ref:t,...D.props,width:l==="horizontal"?T:n,height:l==="horizontal"?r:T})},"child2")]}):_.jsx(y.type,{...y.props,width:n,height:r})}),XF=({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(D=>D*1.3),title:"Increase box size",icon:_.jsx(Tc,{})},{type:"button",callback:()=>c(D=>D/1.3),title:"Decrease box size",icon:_.jsx(Cc,{})}],y={type:"toggle",subtype:"checkbox",callback:()=>d(D=>!D),title:"Show X Axis",selected:f===!0};return[...g,{type:"divider"},y]},[f]),S=30,p=fl;return _.jsxs("div",{children:[_.jsxs(Ro,{width:t,height:n-S,initialPosition:p,adjustable:!1,children:[_.jsx(dl,{width:p,height:n,customActions:m}),_.jsx(wc,{width:0,height:0,children:_.jsx(xc,{plots:v,plotComponent:xS,selectedPlotKeys:r.onlyShowSelected?void 0:a})})]}),_.jsx("div",{style:{position:"absolute",top:n-S,height:S,overflow:"hidden"},children:_.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}},ZF=(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}},QF=({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 S=0;S<s;S++){const p=m[S],g=S*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?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(XF,{data:i,width:n,height:r})}):_.jsx("div",{children:"Loading..."})},Jr=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?_.jsx(_.Fragment,{children:"Waiting for context..."}):_.jsx(xy.Provider,{value:{unitSelection:n,unitSelectionDispatch:r},children:t})},KF=e=>{const{unitId:t,mergeGroup:n}=e,r=wr(Ct(t)),i=n?n.map(a=>`${a}`).join(", "):"";return _.jsxs("span",{children:[_.jsx("div",{className:"unitLabel",style:{backgroundColor:r}})," ",`${t}`,n&&n.length>0&&_.jsx("span",{children:` (${i})`},"mergeGroup")]})},WF=(e,t)=>((t||{}).mergeGroups||[]).filter(r=>r.includes(e))[0]||null,JF=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]),S=M.useCallback((D,w)=>{const b=d?.columnName===D?!d?.sortAscending:!0;h({columnName:D,sortAscending:b}),r&&r({type:"UPDATE_SORT_FIELDS",newSortField:D,ascending:b})},[d,r]),p=M.useCallback(()=>{r&&r(m==="all"?{type:"DESELECT_ALL"}:{type:"TOGGLE_SELECT_ALL"})},[m,r]),g=M.useMemo(()=>{const D=v.map(b=>i.get(b)).filter(b=>b!==void 0);if(!d)return D;const w=a.find(b=>b.columnName===d.columnName);return w?[...D].sort((b,E)=>{const A=b.data[d.columnName]?.sortValue,C=E.data[d.columnName]?.sortValue,T=w.sort(A,C);return d.sortAscending?T:-T}):D},[v,i,d,a]),y=D=>d?.columnName!==D?"":d.sortAscending?"↑":"↓";return _.jsx("div",{className:"compact-table-container",style:{height:s?`${s}px`:"100%",overflow:"auto"},children:_.jsxs("table",{className:"compact-table",children:[_.jsx("thead",{children:_.jsxs("tr",{children:[!f&&_.jsx("th",{className:"compact-table-header",children:_.jsx("input",{type:"checkbox",checked:m==="all",ref:D=>{D&&(D.indeterminate=m==="partial")},onChange:p,disabled:c})}),a.map(D=>_.jsxs("th",{className:"compact-table-header",onClick:()=>S(D.columnName,D),title:D.tooltip,style:{cursor:"pointer"},children:[D.label,_.jsx("span",{className:"sort-indicator",children:y(D.columnName)})]},D.columnName))]})}),_.jsx("tbody",{children:g.map(D=>_.jsxs("tr",{className:`compact-table-row ${t.has(D.rowId)?"selected":""} ${n===D.rowId?"current":""}`,children:[!f&&_.jsx("td",{className:"compact-table-cell",children:_.jsx("input",{type:"checkbox",checked:t.has(D.rowId),onChange:w=>{D.checkboxFn&&D.checkboxFn(w)},disabled:c})}),a.map(w=>_.jsx("td",{className:"compact-table-cell",children:w.dataElement(D.data[w.columnName]?.value)},w.columnName))]},D.rowId))})]})})},eN={},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},tN={sortingCuration:eN,sortingCurationDispatch:e=>{console.warn("No sortingCurationDispatch function provided.")},curating:!1},wS=Nt.createContext(tN),ES=()=>{const e=M.useContext(wS);if(!e)throw Error("useSortingCuration must be used within a SortingCurationContext.Provider");return e},nN=(e,t)=>e.filter(n=>t.includes(n)),rN=(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];nN(i,o).length>0&&(t[r]=rN(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=>_.jsx(KF,{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=>_.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 A=b.score,C=E.score;return A===void 0&&C!==void 0?-1:A!==void 0&&C===void 0?1:A===void 0&&C===void 0?0:A!==void 0&&C!==void 0?A<C?-1:A>C?1:0:0},dataElement: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,A)=>E<A?-1:E>A?1:0:b.dtype==="int"?(E,A)=>E-A:b.dtype=="bool"?(E,A)=>(E?1:0)-(A?1:0):b.dtype==="float"?(E,A)=>E-A:(E,A)=>E-A,dataElement:E=>_.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}`]||[],A={value:{unitId:b.unitId,mergeGroup:WF(b.unitId,d)},sortValue:b.unitId},C=w[b.unitId],T={_unitId:A,_labels:{value:E,sortValue:E.join(", ")},_similarity:{value:C!==void 0?C.toFixed(3):void 0,sortValue:{unitId:b.unitId,score:C}}};for(const B of e.columns){const x=`${b.values[B.key]!==void 0?b.values[B.key]:""}`;T[B.key]={value:x,sortValue:b.values[B.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 S=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]),D=M.useCallback(()=>{f({type:"REDISTRIBUTE_UNIT_COLORS"})},[f]);return _.jsxs("div",{children:[_.jsx("div",{style:g,onKeyDown:y,children:_.jsx(JF,{columns:v,rows:S,orderedUnitIds:u,visibleUnitIds:h,selectedUnitIds:a,currentUnitId:o,selectionDispatch:f,primarySortRule:s})}),_.jsx("div",{style:{position:"absolute",top:n-p,height:p,overflow:"hidden"},children:_.jsx(wf,{options:r,setOptions:i,onRedistributeUnitColors:D})})]})},iN=({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 S=M.useCallback(j=>{if(r.length===0)return"none";const Y=r.filter($=>(l[$.toString()]||[]).includes(j));return Y.length===0?"none":Y.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(Y=>Y.includes(j)),[l]),D=M.useCallback(j=>{o&&(y(j)||a({type:"SET_LABEL_CHOICES",labelChoices:m.filter(Y=>Y!==j)}))},[m,a,y,o]),w=M.useCallback(j=>s.find(Y=>Y.includes(j)),[s]),b=M.useMemo(()=>{if(r.length===0)return{canMerge:!1,canUnmerge:!1,groupsInvolved:[],unmergedUnits:[]};const j=new Set,Y=[];r.forEach(V=>{const te=w(V);te?j.add(te):Y.push(V)});const $=r.length>=2,q=j.size>0;return{canMerge:$,canUnmerge:q,groupsInvolved:Array.from(j),unmergedUnits:Y}},[r,w]),E=M.useCallback(()=>{o&&(r.length<2||c||a({type:"MERGE_UNITS",unitIds:r}))},[r,c,a,o]),A=M.useCallback(()=>{o&&(r.length===0||c||a({type:"UNMERGE_UNITS",unitIds:r}))},[r,c,a,o]),C=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]),B={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"},R={fontWeight:"bold",marginBottom:"4px",fontSize:"11px",color:"#333"},F={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"},X={...U,backgroundColor:c?"#f8d7da":"#d4edda",borderColor:c?"#f5c6cb":"#c3e6cb",color:c?"#721c24":"#155724"},Z={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 _.jsxs("div",{style:B,children:[_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Selected Units"}),_.jsx("div",{style:{fontSize:"10px",color:"#666"},children:T})]}),_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Label Assignment"}),m.map(j=>{const Y=S(j);return _.jsxs("div",{style:I,onClick:o?()=>p(j):void 0,children:[_.jsx("input",{type:"checkbox",checked:Y==="full",ref:$=>{$&&($.indeterminate=Y==="partial")},onChange:()=>{},style:{marginRight:"4px"},disabled:r.length===0||c}),_.jsx("span",{style:{fontSize:"10px"},children:j})]},j)}),r.length===0&&_.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic"},children:"Select units to assign labels"})]}),_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Unit Merging"}),r.length>0&&b.groupsInvolved.length>0&&_.jsxs("div",{style:{marginBottom:"6px"},children:[_.jsx("div",{style:{fontSize:"10px",color:"#666",marginBottom:"2px"},children:"Merge groups involving selected units:"}),b.groupsInvolved.map((j,Y)=>{const $={...F,backgroundColor:"#e3f2fd",borderColor:"#90caf9",color:"#1565c0"};return _.jsx("span",{style:$,children:j.join(", ")},Y)})]}),_.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center",flexWrap:"wrap"},children:[_.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"}),_.jsx("button",{onClick:o?A: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&&_.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"4px"},children:[b.groupsInvolved.length>0&&_.jsxs("div",{children:["Selected units in"," ",b.groupsInvolved.length," merge group(s)"]}),b.unmergedUnits.length>0&&_.jsxs("div",{children:[b.unmergedUnits.length," unmerged unit(s) selected"]})]}),r.length===0&&_.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic",marginTop:"4px"},children:"Select units to merge or unmerge"})]}),_.jsxs("div",{style:x,children:[_.jsxs("div",{style:Z,onClick:()=>v(!h),children:[_.jsx("span",{style:P,children:"▶"}),"Manage Label Choices"]}),h&&_.jsxs("div",{children:[_.jsx("div",{style:{marginBottom:"4px"},children:m.map(j=>{const Y=y(j);return _.jsxs("span",{style:F,children:[j,!c&&!Y&&_.jsx("span",{style:z,onClick:o?()=>D(j):void 0,title:"Remove label choice",children:"×"})]},j)})}),!c&&_.jsxs("div",{style:{display:"flex",alignItems:"center"},children:[_.jsx("input",{type:"text",value:f,onChange:j=>d(j.target.value),onKeyPress:j=>j.key==="Enter"&&o&&g(),placeholder:"Add label...",style:N}),_.jsx("button",{onClick:o?g:void 0,style:U,disabled:!f.trim(),children:"Add"})]})]})]}),_.jsxs("div",{style:L,children:[_.jsx("button",{onClick:o?C:void 0,style:X,children:c?"Reopen Curation":"Finalize Curation"}),_.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"2px"},children:["Status: ",c?"Closed":"Open"]})]})]})},aN=({zarrGroup:e,contexts:t,width:n,height:r})=>_.jsx(Jr,{context:t.unitSelection,children:_.jsx(TS,{contexts:t,editable:!0,children:_.jsx(oN,{zarrGroup:e,contexts:t,width:n,height:r})})}),oN=({zarrGroup:e,width:t,height:n})=>{const r=e.attrs.default_label_options||[];return _.jsx(iN,{defaultLabelOptions:r,width:t,height:n})},TS=({contexts:e,children:t,editable:n})=>{const{annotations:r,setAnnotation:i}=ZF(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 _.jsx(wS.Provider,{value:{sortingCuration:a,sortingCurationDispatch:o,curating:!!i},children:t})},uN=({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),S=JSON.parse(m);let p;try{const g=await e.getDatasetData("similarity_scores_data",{});if(g&&g.length>0){const y=new Uint8Array(g),D=new TextDecoder("utf-8").decode(y);p=JSON.parse(D)}}catch(g){console.warn("No similarity scores data found: "+g)}if(c)return;a({type:"UnitsTable",columns:d,rows:S,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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading units table data..."}):i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(TS,{contexts:t,editable:!1,children:_.jsx(CS,{data:i,width:n,height:r})})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No units table data available"})},lN=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:_.jsx(F_,{}),keyCode:38},{type:"button",callback:a,title:"Reset scale amplitude",icon:_.jsx(XD,{})},{type:"button",callback:i,title:"Scale amplitude down [shift + mouse-wheel]",icon:_.jsx(M_,{}),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]}),sN=(e,t)=>({forward:_S(e.forward,t.forward),inverse:_S(t.inverse,e.inverse)}),cN=e=>({forward:[...e.map(t=>[...t])],inverse:dN(e)}),fN=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]]],dN=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=cN([[d,0,(1-d)*c.x],[0,d,(1-d)*c.y]]);f>0&&(h=fN(h));let v=sN(h,a);const m=ha(v,{x:0,y:0}),S=ha(v,{x:e,y:t});return 0<=m.x&&m.x<e&&0<=m.y&&m.y<t&&0<=S.x&&S.x<e&&0<=S.y&&S.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)"},hN=2*Math.PI,mN=(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"?gN(e,t):pN(e,t),e.restore()},pN=(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)})}},gN=(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),S=h?m?c.draggedSelected:v?c.selectedHover:c.selected:m?c.dragged:v?c.hover:c.base;return{...d,color:S,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,hN),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,vN=(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}),yN=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}},bN=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},DN=(e,t)=>d_(n=>{const r=Oo+n[0]*(e-2*Oo),i=ml+n[1]*(t-2*ml);return[r,i]}),SN=(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}})},xN=(e,t,n,r,i)=>{const a=e-Oo*2,o=t-ml*2,u=Sc(i),l=zD(i);return P5(a/u,o/l,r/n)},wN=(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]]},EN=(e,t,n,r={})=>{const i=(e-Oo*2)/(t-ml*2),a=bN(n),{boxAspect:o}=yN(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}},AN=(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=DN(e,t),S=SN(n,m),p=(t-2*ml)/(1+n.length);return{transform:m,convertedElectrodes:S,pixelRadius:p}}const{electrodes:o,rotated:u}=EN(e,t,n,{disableAutoRotate:a.disableAutoRotate}),l=FS(o),s=NS(o,l),c=xN(e,t,l,i,s),f=l*c;let d=wN(e,t,c,s);const h=(e-Sc(s)*c)/2,v=AN(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},CN=(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=o_(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},TN=e=>{const t=e.currentTarget.getBoundingClientRect();return[e.clientX-t.x,e.clientY-t.y]},MN=()=>({selectedElectrodeIds:[],setSelectedElectrodeIds:e=>{}}),kS=e=>{const{width:t,height:n,electrodes:r,disableAutoRotate:i,affineTransform:a}=e,{selectedElectrodeIds:o,setSelectedElectrodeIds:u}=MN(),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(CN,{convertedElectrodes:[],pixelRadius:-1,draggedElectrodeIds:[],pendingSelectedElectrodeIds:o||[],dragState:{isActive:!1},xMarginWidth:-1}),{affineTransform:m,handleWheel:S}=Lm(t,n,{shift:!0,alt:!1}),p=M.useMemo(()=>{const T=h.convertedElectrodes.map(B=>{const x=ha(m,{x:B.pixelX,y:B.pixelY});return{...B,pixelX:x.x,pixelY:x.y}});return{...h,convertedElectrodes:T,pixelRadius:h.pixelRadius*Math.sqrt(km(m))}},[m,h]),g=M.useMemo(()=>T=>{const B=TN(T),x=$m(m,{x:B[0],y:B[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),D=M.useRef(0),w=l||_.jsx(f_,{width:t,height:n,newState:h.dragState}),b=M.useCallback(T=>{if(!l_(T,{nextDragStateUpdate:y,nextFrame:D,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})){const x=g(T);v({type:"UPDATEHOVER",point:x})}},[g]),E=M.useCallback(T=>{s_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})},[]),A=M.useCallback(T=>{if(h.dragState.isActive)c_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE",selectedElectrodeIds:o}});else{const B=g(T);v({type:"UPDATECLICK",point:B,shift:T.shiftKey,ctrl:T.ctrlKey,selectedElectrodeIds:o||[]})}},[h.dragState.isActive,o,g]),C=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 _.jsx(ir,{width:t,height:n,draw:mN,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]),_.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:b,onMouseUp:A,onMouseDown:E,onWheel:S,children:[w,US,C]})},_N=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,S)=>[(c?.length||0)/2+(S-(c?.length||0)/2)*i,m]),v=Zh(e,h);a.push({pointsInPaintBox:v,offsetFromParentCenter:[o.pixelX,o.pixelY],color:l.waveformColors.base})}}}}),a},BN=(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 D=r[y],w=i[y];e.fillStyle="#dddddd",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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,S,p;a&&o&&u&&l?(v=a,m=o,S=u,p=l):a&&o&&!u&&!l?(v=void 0,m=a,S=o,p=void 0):(v=void 0,m=void 0,S=void 0,p=void 0),v&&v.length>0&&p&&p.length>0&&v.forEach((g,y)=>{if(!v||!p)throw Error("unexpected");const D=v[y],w=p[y];e.fillStyle="#dddddd",e.strokeStyle="#dddddd",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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&&S&&S.length>0&&m.forEach((g,y)=>{if(!m||!S)throw Error("unexpected");const D=m[y],w=S[y];e.fillStyle="#bbbbbb",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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()},FN=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,S=-i*(.5+1/v),p=a*r/2,g=ze([[m,0,S],[0,-p,0],[0,0,1]]).toArray(),y=ma(g,n,t,"normal",o),D=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),A=ma(g,n,t,"percentile3",o),C=ma(g,n,t,"percentile4",o);b.length===0&&(b=void 0),E.length===0&&(E=void 0),A.length===0&&(A=void 0),C.length===0&&(C=void 0);const T=s==="vertical"?(u-i)/2:0,B={pixelSpacePaths:y,pixelSpacePathsLower:D,pixelSpacePathsUpper:w,pixelSpacePathsPercentile1:b,pixelSpacePathsPercentile2:E,pixelSpacePathsPercentile3:A,pixelSpacePathsPercentile4:C,xMargin:T,waveformWidth:c,affineTransform:f,useUnitColors:d};return _.jsx(ir,{width:u,height:l,draw:BN,drawData:B})},[n,t,a,u,l,i,r,s,c,f,o,d])},NN={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)"}},RN=e=>{const t=e.colors??NN.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:S}=Lm(l,s,{shift:!0,alt:!0}),p=M.useMemo(()=>_.jsx(kS,{electrodes:n,width:l,height:s,layoutMode:o,colors:t,showLabels:c,maxElectrodePixelRadius:v,disableSelection:!0,disableAutoRotate:h,affineTransform:S}),[n,l,s,o,t,c,h,S]),{convertedElectrodes:g,pixelRadius:y,xMargin:D}=jm(l,s,n,o,v,{disableAutoRotate:h}),w=D||Oo,b=M.useMemo(()=>_N(e.peakAmplitude),[e.peakAmplitude]),E=M.useMemo(()=>i*b,[i,b]),A=o==="geom"?y*2:s/n.length,C=o==="geom"?y*2:l-w-(c?2*y:0),T=_.jsx(FN,{electrodes:g,waveforms:r,oneElectrodeHeight:A,oneElectrodeWidth:C,horizontalStretchFactor:a,yScale:E,width:l,height:s,layoutMode:o,waveformWidth:d,affineTransform:S,useUnitColors:f});return _.jsxs("div",{style:{width:l,height:s,position:"relative"},onWheel:m,children:[!u&&p,T]})},ON=({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 S=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 A of w.channelIds)E.push(S.map(C=>C.id).indexOf(A));return{electrodeIndices:E,waveform:w.waveform,waveformStdDev:w.waveformStdDev,waveformPercentiles:w.waveformPercentiles,waveformColors:b}}),[S,n]),D=_.jsx(RN,{waveforms:y,electrodes:S,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?_.jsxs("div",{style:{position:"relative",width:v,height:m},children:[_.jsx("div",{style:{position:"absolute",left:0,top:0,width:g,height:m},children:_.jsx(kS,{electrodes:p,disableSelection:!1,width:g,height:m})}),_.jsx("div",{style:{position:"absolute",left:g,top:0,width:v-g,height:m},children:D})]}):D},zN=({data:e,width:t,height:n})=>{const r=M.useMemo(()=>{const $=[];for(const q of e.averageWaveforms)for(const V of q.channelIds)$.includes(V)||$.push(V);return yr($)},[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,S]=M.useState(!0),[p,g]=M.useState(!1),[y,D]=M.useState(e.showReferenceProbe||!1),[w,b]=M.useState(!1),[E,A]=M.useState(1),[C,T]=M.useState(!0),[B,x]=M.useState(!0);M.useEffect(()=>{c({type:oo,newUnitOrder:yr(e.averageWaveforms.map($=>$.unitId))})},[e.averageWaveforms,c]);const[R,F]=M.useState(2),z=M.useMemo(()=>{let $=0;return e.averageWaveforms.forEach(q=>{q.waveform.forEach(V=>{V.forEach(te=>{const W=Math.abs(te);W>$&&($=W)})})}),$},[e.averageWaveforms]),N=M.useMemo(()=>e.averageWaveforms.filter($=>i.onlyShowSelected?o.has($.unitId):!0).map($=>{const q=[{channelIds:$.channelIds,waveform:IN($.waveform),waveformStdDev:m&&!w?$.waveformStdDev:void 0,waveformPercentiles:m&&!w&&$.waveformPercentiles?$N($.waveformPercentiles,$.waveform):void 0,waveformColor:wr(Ct($.unitId))}],V={allChannelIds:r,channelIds:$.channelIds,units:q,layoutMode:h,hideElectrodes:C,channelLocations:e.channelLocations,samplingFrequency:e.samplingFrequency,peakAmplitude:z,ampScaleFactor:f,horizontalStretchFactor:E,showChannelIds:p,useUnitColors:B,width:120*R+(y?120*R/4:0),height:120*R,showReferenceProbe:y,disableAutoRotate:!0};return{unitId:$.unitId,key:$.unitId,label:`Unit ${$.unitId}`,labelColor:wr(Ct($.unitId)),clickHandler:i.onlyShowSelected?void 0:s($.unitId),props:V}}),[e.averageWaveforms,e.channelLocations,e.samplingFrequency,r,z,h,f,s,i.onlyShowSelected,o,R,m,p,y,w,E,C,B]),U=M.useMemo(()=>l?l.map($=>N.filter(q=>q.unitId===$)[0]).filter($=>$!==void 0):N,[N,l]),I=M.useMemo(()=>w?UN(U):U,[U,w]),L=M.useMemo(()=>[{type:"button",callback:()=>{A($=>$*1.1)},title:"Increase horizontal stretch [alt + mouse-wheel]",icon:_.jsx(B_,{})},{type:"button",callback:()=>{A(1)},title:"Reset scale amplitude",icon:_.jsx(XD,{})},{type:"button",callback:()=>{A($=>$/1.1)},title:"Decrease horizontal stretch [alt + mouse-wheel]",icon:_.jsx(__,{})}],[]),X=M.useMemo(()=>{const $=lN({ampScaleFactor:f,setAmpScaleFactor:d}),q={type:"toggle",subtype:"checkbox",callback:()=>v(se=>se==="geom"?"vertical":"geom"),title:"Show electrode geometry",selected:h==="geom"},V={type:"toggle",subtype:"checkbox",callback:()=>T(se=>!se),title:"Show electrodes",selected:!C},te=[{type:"button",callback:()=>F(se=>se*1.3),title:"Increase box size",icon:_.jsx(Tc,{})},{type:"button",callback:()=>F(se=>se/1.3),title:"Decrease box size",icon:_.jsx(Cc,{})}],W={type:"toggle",subtype:"checkbox",callback:()=>S(se=>!se),title:"Show waveform stdev",selected:m===!0},ne={type:"toggle",subtype:"checkbox",callback:()=>g(se=>!se),title:"Show channel IDs",selected:p===!0},fe={type:"toggle",subtype:"checkbox",callback:()=>D(se=>!se),title:"Show reference probes",selected:y===!0},ee={type:"toggle",subtype:"checkbox",callback:()=>b(se=>!se),title:"Show overlapping",selected:w===!0},le={type:"toggle",subtype:"checkbox",callback:()=>x(se=>!se),title:"Use unit colors",selected:B===!0};return[{type:"divider"},...te,{type:"divider"},...$,{type:"divider"},...L,{type:"divider"},q,V,{type:"divider"},W,{type:"divider"},ne,{type:"divider"},fe,{type:"divider"},ee,{type:"divider"},le]},[h,f,m,p,w,y,L,C,B]),Z=M.useCallback($=>{$.shiftKey&&!$.altKey?$.deltaY<0?d(q=>q*1.3):d(q=>q/1.3):$.altKey&&!$.shiftKey&&($.deltaY<0?A(q=>q*1.1):A(q=>q/1.1))},[]),P=30,j=M.useCallback($=>{$&&$.addEventListener("wheel",q=>{(q.shiftKey||q.altKey)&&q.preventDefault()})},[]),Y=fl;return _.jsxs("div",{ref:$=>j($),onWheel:Z,children:[_.jsxs(Ro,{width:t,height:n-P,initialPosition:Y,adjustable:!1,children:[_.jsx(dl,{width:Y,height:n,customActions:X}),_.jsx(wc,{width:0,height:0,children:_.jsx(xc,{plots:I,plotComponent:ON,selectedPlotKeys:i.onlyShowSelected?void 0:o,currentPlotKey:u})})]}),_.jsx("div",{style:{position:"absolute",top:n-P,height:P,overflow:"hidden"},children:_.jsx(wf,{options:i,setOptions:a})})]})},UN=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]},IN=e=>e.map(t=>{const n=LS(t);return t.map(r=>r-n)}),$N=(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?t_(e):0,kN=e=>_.jsx(Jr,{context:e.contexts.unitSelection,children:_.jsx(LN,{...e})}),LN=({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,S=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`,{}),S){const g=s.find(y=>y.name===d);g&&u.push({unitId:g.unit_id,channelIds:g.channel_ids,waveform:jS(S,m),waveformStdDev:p?jS(p,m):void 0})}}a||i({type:"AverageWaveforms",averageWaveforms:u})})(),()=>{a=!0}},[e]),r?_.jsx(zN,{data:r,width:t,height:n}):_.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,jN=({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 D of o){const w=p.filter(b=>b.unitId1===y&&b.unitId2===D)[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((D,w)=>({key:`${w}`,unitId:D?D.unitId1:0,label:D?g>80?`Unit ${D.unitId1}/${D.unitId2}`:`${D.unitId1}/${D.unitId2}`:"",labelColor:"black",clickHandler:void 0,props:{binEdgesSec:D?D.binEdgesSec:void 0,binCounts:D?D.binCounts:void 0,color:D?.unitId1===D?.unitId2?wr(Ct(D?.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]),S=_.jsxs(Ro,{width:t-s,height:n,initialPosition:c,adjustable:!1,children:[_.jsx(dl,{width:c,height:n,customActions:v}),_.jsx(wc,{width:0,height:0,disableScroll:!0,children:o.length>HS?_.jsxs("div",{children:["Not showing cross-correlogram matrix. Too many units selected (max ="," ",HS,")."]}):o.length===0?_.jsx("div",{children:"Select one or more units to view cross-correlograms."}):_.jsx(xc,{plots:h,plotComponent:xS,selectedPlotKeys:void 0,numPlotsPerRow:o.length})})]});return u?S:_.jsxs("div",{style:{position:"relative",width:t,height:n},children:[_.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:_.jsx(CS,{data:m,width:s,height:n})}),_.jsx("div",{style:{position:"absolute",left:s,top:0,width:t-s,height:n},children:S})]})},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}},HN=({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,D=Array.from(h.slice(y,y+v));l.push({unitId1:g.unit_id1,unitId2:g.unit_id2,binEdgesSec:d,binCounts:D})}const S=e.attrs.hide_unit_selector||!1;o||a({type:"CrossCorrelograms",crossCorrelograms:l,hideUnitSelector:S})})(),()=>{o=!0}},[e]),i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(jN,{data:i,width:n,height:r})}):_.jsx("div",{children:"Loading..."})},PN=1.4,qN=(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??PN;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}},VN=(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)},GN=(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,l)=>{t({type:"setCurrentTime",currentTime:u,ensureVisible:l?.ensureVisible})},[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=qN({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=VN({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=GN({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}},YN=({width:e,height:t,customActions:n})=>!n||n.length===0?null:_.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:_.jsx("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:n.map(r=>r.component?_.jsx("div",{style:{display:"flex",alignItems:"center"},children:r.component},r.id):_.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&&_.jsx("span",{children:r.icon}),r.label]},r.id))})}),XN=e=>{if(!e||!e.current)return;e.current.querySelectorAll("canvas").forEach(n=>{n.addEventListener("wheel",r=>{r.preventDefault()})})},ZN=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")}`},QN=({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 _.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:[_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[_.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"}),_.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"})]}),_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[_.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:"⬅️"}),_.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:"🔍➖"}),_.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:"🔍➕"}),_.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:"➡️"}),_.jsx("div",{style:{width:"1px",height:"20px",backgroundColor:"#dee2e6",margin:"0 4px"}}),_.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:"🏠"})]}),_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[_.jsx("span",{style:{color:"#6c757d",fontWeight:"500"},children:"Time:"}),_.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?ZN(i):"--:--:--.---"})]})]})},KN=[{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`}],YS=(e,t,n,r)=>{if(t===void 0||n===void 0)return[];if(n<=t)return[];const i=[],a=e/(n-t);for(const o of KN){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},WN=(e,t,n,r)=>M.useMemo(()=>YS(e,t,n,r),[t,n,r,e]),JN=e=>{if(!e||typeof e=="function")return;const t=e.current,n=t&&t.getContext("2d");if(n)return n},e7={position:"absolute",left:0,top:0},XS=e=>{const{width:t,height:n,draw:r,drawData:i}=e,a=M.useRef(null);return M.useEffect(()=>{const o=JN(a);o&&o.canvas&&r(o,i)},[r,a,i]),_.jsx("canvas",{ref:a,width:t,height:n,style:e7})},ZS=(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;t7(e,a,s,i.top,{hideGridlines:o?.hideX},t.hideTimeAxisLabels),e.strokeStyle="lightgray",Hm(e,i.left,s,n-i.right,s),u&&n7(e,u,s,i.left,n-i.right,i.top,{hideGridlines:o?.hideY}),l&&r7(e,l,i.left,i.bottom,i.top,e.canvas.height)},t7=(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))})},n7=(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)})},r7=(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()},i7={},a7=e=>{const{width:t,height:n}=e,r=M.useCallback(i=>{ZS(i,e)},[e]);return _.jsx("span",{className:"TSV2AxesLayer",children:_.jsx(XS,{width:t,height:n,draw:r,drawData:i7})})},o7=(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()}},u7=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 _.jsx(XS,{width:t,height:n,draw:o7,drawData:u})},l7=({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 _.jsx("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none",zIndex:10},children:_.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"}})})},s7=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),[S,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 A=E.clientX-E.currentTarget.getBoundingClientRect().x;s==="select-zoom"?(g.current.selectionStartX=A,g.current.selectionEndX=A,p({startX:A,endX:A})):(g.current.mouseDownAchorX=A,g.current.mouseDownAnchorTime=t(A),g.current.mouseDownAnchorVisibleStartTime=n||null,g.current.mouseDownAnchorPixelToTime=t),g.current.moved=!1}else i&&i(E)},[t,i,n,s]),D=M.useCallback(E=>{if(!E.shiftKey&&!E.ctrlKey&&!E.altKey){const A=E.clientX-E.currentTarget.getBoundingClientRect().x;if(s==="select-zoom"&&g.current.selectionStartX!==null){const C=Math.min(g.current.selectionStartX,A),T=Math.max(g.current.selectionStartX,A);if(Math.abs(T-C)>5){const B=t(C),x=t(T);f(B,x)}else if(!g.current.moved){const B=t(A);if(r(B),l){const x=E.clientY-E.currentTarget.getBoundingClientRect().y;l(A,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 C=t(A);if(r(C),l){const T=E.clientY-E.currentTarget.getBoundingClientRect().y;l(A,T)}}}else a&&a(E)},[a,t,r,s,f,l]),w=M.useCallback(E=>{const A=E.clientX-E.currentTarget.getBoundingClientRect().x,C=t(A);if(m(C),!E.shiftKey&&!E.ctrlKey&&!E.altKey){if(s==="select-zoom"&&g.current.selectionStartX!==null)g.current.selectionEndX=A,p({startX:Math.min(g.current.selectionStartX,A),endX:Math.max(g.current.selectionStartX,A)}),g.current.moved=!0;else if(s==="pan"&&g.current.mouseDownAchorX!==null&&g.current.mouseDownAnchorPixelToTime!==null){const T=g.current.mouseDownAnchorPixelToTime(A),B=g.current.mouseDownAnchorTime,x=g.current.mouseDownAnchorVisibleStartTime;if(B!==null&&x!==null){const R=T-B,F=A-g.current.mouseDownAchorX;if(Math.abs(F)>2||Math.abs(R)>.01){const z=x-R;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:S,handleMouseDown:y,handleMouseUp:D,handleMouseMove:w,handleMouseOut:b}},c7=({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}},f7=23,d7=60,h7=(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)},m7=(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)},p7=(e,t)=>Math.floor(e*Math.pow(10,-(t+1)))*Math.pow(10,t+1),g7=(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}},v7=(e,t,n,r,i)=>{const a=h7(t,n,r,e).map(l=>Math.round(l*1e9)/1e9),o=m7(t,n);return a.map(l=>g7(l,o,i))},QS={ticks:[],datamin:0,datamax:0},y7=(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}},KS=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;i<=1&&(i=1);const a=r??1;if(t===void 0||n===void 0||t===n)return QS;const o=t/a,u=n/a,l=u-o,s=i/d7,c=i/f7,f=y7(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."),QS;const h=p7(o,f.scale);return{ticks:v7(h,o,u,d,f.scale),datamin:o,datamax:u}},b7=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;return i<=1&&(i=1),M.useMemo(()=>KS({datamin:t,datamax:n,userSpecifiedZoom:r,pixelHeight:i}),[n,t,i,r])},WS=({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:S=!1,drawContentForExport:p,setDrawForExport:g})=>{const{visibleStartTimeSec:y,visibleEndTimeSec:D,zoomTimeseriesSelection:w,panTimeseriesSelection:b,setVisibleTimeRange:E}=_f(),{currentTime:A,setCurrentTime:C,startTimeSec:T,endTimeSec:B}=Mf(),x=M.useMemo(()=>[y,D],[y,D]),{margins:R,canvasWidth:F,canvasHeight:z}=c7({width:e,height:t,leftMargin:d,customToolbarActions:h,hideNavToolbar:m}),N=M.useMemo(()=>y===void 0||D===void 0?()=>0:D<=y?()=>0:H=>R.left+(H-y)/(D-y)*(F-R.left-R.right),[F,y,D,R]),U=M.useMemo(()=>y===void 0||D===void 0?()=>0:D<=y?()=>0:H=>y+(H-R.left)/(F-R.left-R.right)*(D-y),[F,y,D,R]),I=M.useMemo(()=>{const H=s?.yMin||0,G=s?.yMax||0;return G<=H?()=>0:ie=>z-R.bottom-(ie-H)/(G-H)*(z-R.top-R.bottom)},[s,z,R]),L=WN(F,y,D,N),X=b7({datamin:s?.yMin||0,datamax:s?.yMax||0,pixelHeight:z-R.left-R.right}),Z=M.useMemo(()=>({datamin:X.datamin,datamax:X.datamax,ticks:X.ticks.map(H=>({...H,pixelValue:I(H.dataValue)}))}),[X,I]),P=z,j=M.useMemo(()=>_.jsx(a7,{width:F,height:P,timeRange:x,margins:R,timeTicks:L,yTickSet:s?.showTicks?Z:void 0,yLabel:s?.yLabel,gridlineOpts:r,hideTimeAxisLabels:S}),[r,F,P,x,R,L,s?.showTicks,s?.yLabel,Z,S]),Y=M.useMemo(()=>A!==void 0?N(A):void 0,[A,N]),$=M.useMemo(()=>_.jsx(u7,{width:F,height:P,timeRange:x,margins:R,currentTimePixels:Y}),[F,P,x,R,Y]),q=M.useRef(null),[V,te]=M.useState("pan"),{isViewClicked:W,hoverTime:ne,selectionRect:fe,handleMouseDown:ee,handleMouseUp:le,handleMouseMove:se,handleMouseOut:De}=s7({pixelToTime:U,visibleStartTimeSec:y,setCurrentTime:C,onMouseDown:a,onMouseUp:l,onMouseMove:o,onMouseOut:u,onCanvasClick:v,interactionMode:V});M.useEffect(()=>{(f===!1||W)&&XN(q)},[f,W]);const be=M.useCallback(H=>{if(c&&!H.shiftKey||H.deltaY===0||f!==!1&&!W)return;const G=-H.deltaY/100;w(G>0?"in":"out",1.2,ne)},[c,w,ne,f,W]),xe=M.useCallback(H=>{H.key==="="?w("in"):H.key==="-"?w("out"):H.key==="ArrowRight"?b("forward"):H.key==="ArrowLeft"&&b("back"),i&&i(H)},[i,w,b]),we=M.useCallback(()=>{T!==void 0&&B!==void 0&&E(T,B)},[T,B,E]),Re=M.useMemo(()=>_.jsx(l7,{width:F,height:P,selectionRect:fe}),[F,P,fe]),[Ce,Be]=M.useState(null);M.useEffect(()=>{Ce&&n(Ce,F,z,R)},[Ce,F,z,R,n]),M.useEffect(()=>{if(!g)return;g(async G=>{if(!G||!R)return;const ie=oe=>{const de=s?.yMin||0,ue=s?.yMax||0;return ue<=de?0:G.height-R.bottom-(oe-de)/(ue-de)*(G.height-R.top-R.bottom)},J=YS(G.width,y,D,N),he=KS({datamin:s?.yMin,datamax:s?.yMax,pixelHeight:G.height});for(const oe of he.ticks)oe.pixelValue=ie(oe.dataValue);ZS(G.context,{timeTicks:J,margins:R,gridlineOpts:r,yTickSet:he,yLabel:s?.yLabel,width:G.width,height:G.height,hideTimeAxisLabels:S}),p&&await p(G.context,G.width,G.height,R,{exporting:!0})})},[p,g,R,y,D,N,x,r,s,S,I]);const pe=M.useMemo(()=>_.jsxs("div",{style:{position:"relative",overflow:"hidden",width:F,height:P},onWheel:!f||W?be:void 0,onMouseDown:ee,onMouseUp:le,onMouseMove:se,onMouseOut:De,tabIndex:0,onKeyDown:xe,children:[j,_.jsx("canvas",{style:{position:"absolute",width:F,height:P},ref:H=>Be(H),width:F,height:P}),$,Re]}),[j,$,Re,F,P,xe,be,ee,le,se,De,f,W]),O=M.useMemo(()=>_.jsx(QN,{width:e,height:40,interactionMode:V,onInteractionModeChange:te,currentTime:A,onZoomToFit:we}),[e,V,te,A,we]),k=M.useMemo(()=>_.jsx(YN,{width:e,height:40,customActions:h}),[e,h]);return _.jsxs("div",{className:"time-scroll-view-3",ref:q,style:{position:"absolute",width:e,height:t,background:"white"},children:[pe,!m&&_.jsxs("div",{style:{position:"absolute",bottom:0,left:0,right:0},children:[O,k]})]})},JS=15,D7={hideX:!1,hideY:!0},S7={showTicks:!1,yMin:void 0,yMax:void 0},x7=({dataClient:e,width:t,height:n,setDrawForExport:r})=>{const{visibleStartTimeSec:i,visibleEndTimeSec:a}=_f(),{initializeTimeseriesSelection:o}=Mf(),{selectedUnitIds:u,unitIdSelectionDispatch:l}=qr(),[s,c]=M.useState(void 0),f=M.useRef(null),[d,h]=M.useState(null),[v,m]=M.useState(null),[S,p]=M.useState(!1),[g,y]=M.useState(null),[D,w]=M.useState(null),b=M.useMemo(()=>i===void 0||a===void 0?"raster":a-i>120?"heatmap":"raster",[i,a]),E=e.metadata.unitIds;M.useEffect(()=>{e.metadata&&o({startTimeSec:e.metadata.startTimeSec,endTimeSec:e.metadata.endTimeSec,initialVisibleStartTimeSec:e.metadata.startTimeSec,initialVisibleEndTimeSec:e.metadata.endTimeSec})},[o,e.metadata]),M.useEffect(()=>{let $=!1;const q=async()=>{if(!(i===void 0||a===void 0))try{if(b==="raster"){const V=await e.getDataForRange({startTimeSec:i,endTimeSec:a});if($)return;m(V),w(null)}else{const V=e.getSpikeCountsForRange({startTimeSec:i,endTimeSec:a});if($)return;w(V),m(null)}y(null)}catch(V){if($)return;console.error("Error loading data:",V),y(`Error loading data: ${V}`)}};return p(!0),q().finally(()=>{$||p(!1)}),()=>{$=!0}},[e,i,a,b]);const{onlyShowSelected:A,customToolbarActions:C}=GS(),[T,B]=M.useState(t),[x,R]=M.useState(n),[F,z]=M.useState(null),N=M.useMemo(()=>{const $=[];return A&&E.forEach((q,V)=>{u.has(q)&&$.push(V)}),$},[A,u,E]),U=M.useMemo(()=>N.map($=>E[$]),[N,E]),I=M.useCallback(()=>{if(!F||!f.current||!d||!D||!e.metadata||i===void 0||a===void 0)return;if(d.clearRect(0,0,T,x),S&&(d.fillStyle="rgba(0, 0, 0, 0.02)",d.fillRect(0,0,T,x),d.fillStyle="black",d.font="16px Arial",d.textAlign="center",d.fillText("Loading...",T/2,x/2)),g){d.fillStyle="rgba(255, 0, 0, 0.1)",d.fillRect(0,0,T,x),d.fillStyle="red",d.font="14px Arial",d.textAlign="center",d.fillText(g,T/2,x/2);return}const q=x-F.top-F.bottom,V=T-F.left-F.right,te=a-i;let W;if(A){let ee=0;E.forEach((le,se)=>{u.has(le)&&ee++}),W=ee}else E.forEach((ee,le)=>{}),W=E.length;const ne=q/(W||1);d.save(),d.beginPath(),d.rect(F.left,F.top,V,q),d.clip();let fe=1;if(D.counts.forEach(ee=>{A?N.forEach(le=>{const se=ee[le];se>fe&&(fe=se)}):ee.forEach(le=>{le>fe&&(fe=le)})}),D.counts.forEach((ee,le)=>{const se=D.binEdges[le],De=D.binEdges[le+1],be=F.left+(se-i)/te*V,xe=F.left+(De-i)/te*V;if(A)for(let we=0;we<N.length;we++){const Re=N[we],Be=ee[Re]/fe,pe=F.top+(N.length-1-we)*ne,O=ex(Be);d.fillStyle=O,d.fillRect(be,pe,xe-be+.5,ne)}else ee.forEach((we,Re)=>{const Ce=we/fe,Be=F.top+(E.length-1-Re)*ne,pe=ex(Ce);d.fillStyle=pe,d.fillRect(be,Be,xe-be+.5,ne)})}),d.restore(),ne>=JS){d.globalAlpha=1;const ee=A?U:E;ee.forEach((le,se)=>{const be=F.top+(ee.length-1-se)*ne+ne/2,xe=mh(Ct(le));d.fillStyle=xe,d.font="12px Arial",d.textAlign="right",d.fillText(`Unit ${le}`,F.left-5,be)})}},[T,x,F,D,i,a,e.metadata,S,g,d,u,A,E,N,U]);console.log(u,N,U);const L=M.useCallback(()=>{if(!F||!f.current||!d||!v||!e.metadata||i===void 0||a===void 0)return;if(d.clearRect(0,0,T,x),S&&(d.fillStyle="rgba(0, 0, 0, 0.02)",d.fillRect(0,0,T,x),d.fillStyle="black",d.font="16px Arial",d.textAlign="center",d.fillText("Loading...",T/2,x/2)),g){d.fillStyle="rgba(255, 0, 0, 0.1)",d.fillRect(0,0,T,x),d.fillStyle="red",d.font="14px Arial",d.textAlign="center",d.fillText(g,T/2,x/2);return}const q=x-F.top-F.bottom,V=T-F.left-F.right,te=a-i,W=e.metadata.unitIds,ne={};let fe;if(A){for(let le=0;le<N.length;le++){const se=N[le];ne[se]=le}fe=N.length}else W.forEach((le,se)=>{ne[se]=se}),fe=W.length;const ee=q/(fe||1);d.save(),d.beginPath(),d.rect(F.left,F.top,V,q),d.clip();for(let le=0;le<v.timestamps.length;le++){const se=v.timestamps[le],De=ne[v.unitIndices[le]];if(De===void 0)continue;const be=W[v.unitIndices[le]],xe=F.top+(fe-1-De)*ee+ee/2,we=mh(Ct(be)),Re=s===be,Ce=u.has(be);d.strokeStyle=we,d.lineWidth=Re||Ce?2:1,d.globalAlpha=Ce?1:Re?.8:.6;const Be=F.left+(se-i)/te*V;d.beginPath(),d.moveTo(Be,xe-ee*.4),d.lineTo(Be,xe+ee*.4),d.stroke()}if(d.restore(),ee>=JS){d.globalAlpha=1;const le=A?U:W;le.forEach((se,De)=>{const xe=F.top+(le.length-1-De)*ee+ee/2,we=mh(Ct(se));d.fillStyle=we,d.font="12px Arial",d.textAlign="right",d.fillText(`Unit ${se}`,F.left-5,xe)})}},[T,x,F,v,e.metadata,i,a,S,g,s,u,A,d,U,N]);M.useEffect(()=>{b==="heatmap"&&D?I():L()},[L,I,b,D]);const X=M.useCallback(()=>{},[]),Z=M.useCallback($=>{if(!F||!e.metadata)return;const q=e.metadata.unitIds,V=q.length,te=1-($.y-F.top)/(x-F.top-F.bottom),W=Math.round(te*V-.5);if(0<=W&&W<V)return q[W]},[x,F,e.metadata]),P=M.useCallback($=>{const q=$.currentTarget.getBoundingClientRect(),V={x:$.clientX-q.x,y:$.clientY-q.y},te=Z(V);$.shiftKey||$.ctrlKey?l({type:"TOGGLE_UNIT",targetUnit:te}):l({type:"UNIQUE_SELECT",targetUnit:te})},[Z,l]),j=M.useCallback($=>{const q=$.currentTarget.getBoundingClientRect(),V={x:$.clientX-q.x,y:$.clientY-q.y},te=Z(V);te!==void 0&&c(te)},[Z]),Y=M.useCallback(()=>{c(void 0)},[]);return e.metadata?_.jsx(WS,{width:t,height:n,customToolbarActions:C,onCanvasElement:($,q,V,te)=>{f.current=$;const W=$?.getContext("2d");h(W),B(q),R(V),z(te)},gridlineOpts:D7,onKeyDown:X,onMouseDown:P,onMouseMove:j,onMouseOut:Y,yAxisInfo:S7,setDrawForExport:r}):_.jsx("div",{children:"Loading metadata..."})},ex=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 w7=({zarrGroup:e,contexts:t,width:n,height:r,setDrawForExport:i})=>{const a=E7(e);return a?_.jsx(tx,{context:t.timeseriesSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(x7,{dataClient:a,width:n,height:r,setDrawForExport:i})})}):null},tx=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?_.jsx(_.Fragment,{children:"Waiting for context..."}):_.jsx(VS.Provider,{value:{timeseriesSelection:n,dispatch:r},children:t})},E7=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},A7=({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),S=fl,{onlyShowSelected:p,customToolbarActions:g}=GS(),[y,D]=M.useState(t),[w,b]=M.useState(n),[E,A]=M.useState(null),C=e.metadata;M.useEffect(()=>{C&&i({type:oo,newUnitOrder:yr(C.unitIds)})},[C,i]),M.useEffect(()=>{C&&a({startTimeSec:C.startTimeSec,endTimeSec:C.endTimeSec,initialVisibleStartTimeSec:C.startTimeSec,initialVisibleEndTimeSec:C.endTimeSec})},[a,C]),M.useEffect(()=>{let x=!1;const R=async()=>{if(o!==void 0&&u!==void 0){let F=1e4;for(;;){const z=await e.getDataForRange({startTimeSec:o,endTimeSec:u},{maxNumEvents:F});if(x)return;if(z&&f(z),z.subsampleFactor>1){if(F===1e6)break;F=Math.max(F*3,z.timestamps.length*3),F>1e6&&(F=1e6)}else break}}};return h(!0),m(null),R().catch(F=>{x||m(`Failed to load data: ${F}`),m(`Failed to load data: ${F}`)}).finally(()=>{h(!1)}),()=>{x=!0}},[o,u,e]);const T=M.useMemo(()=>{if(!c||!C||c.amplitudes.length===0)return{yMin:0,yMax:10};let x=1/0,R=-1/0;for(let z=0;z<c.amplitudes.length;z++){const N=C.unitIds[c.unitIndices[z]];if(p?r.has(N):!0){const I=c.amplitudes[z];I<x&&(x=I),I>R&&(R=I)}}if(x===1/0)return{yMin:0,yMax:10};const F=(R-x)*.1;return{yMin:x-F,yMax:R+F}},[c,C,p,r]);M.useEffect(()=>{if(!l||!c||!C||!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 F=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=C.unitIds[c.unitIndices[N]];if(U<o||U>u||!(p?r.has(L):!0))continue;const Z=wr(Ct(L)),j=r.has(L)?1:.3;l.fillStyle=Z,l.globalAlpha=j;const Y=F(U),$=z(I);l.beginPath(),l.arc(Y,$,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,C,o,u,y,w,E,T,r,p,d,v]);const B=M.useMemo(()=>({showTicks:!0,yMin:T.yMin,yMax:T.yMax,yLabel:"Amplitude"}),[T]);return C?_.jsx("div",{children:_.jsxs(Ro,{width:t,height:n,initialPosition:S,adjustable:!1,children:[_.jsx(dl,{width:S,height:n}),_.jsx(WS,{width:t-S,height:n,onCanvasElement:(x,R,F,z)=>{if(!x)return;const N=x.getContext("2d");s(N),D(R),b(F),A(z)},yAxisInfo:B,customToolbarActions:g})]})}):_.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 C7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=T7(e);return i?_.jsx(tx,{context:t.timeseriesSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(A7,{dataClient:i,width:n,height:r})})}):null},T7=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},M7=25,qm=2*Math.PI,_7={maxElectrodePixelRadius:M7},Vm={},zo=8,B7=()=>({selectedElectrodeIds:[]}),F7=e=>{const{width:t,height:n,electrodes:r,units:i,disableAutoRotate:a,onlyShowSelected:o}=e,{selectedElectrodeIds:u}=B7(),{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||_7.maxElectrodePixelRadius,m=e.colors??hl,S=e.showLabels??!1,p=e.offsetLabels??!1,{convertedElectrodes:g,pixelRadius:y,transform:D}=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,X=g.map(Z=>{const P=(u||[]).includes(Z.e.id),j=!1,Y=!1,$=P?Y?m.draggedSelected:j?m.selectedHover:m.selected:Y?m.dragged:j?m.hover:m.base;return{...Z,color:$,textColor:P||j&&!Y?m.textDark:m.textLight}});if(U.clearRect(0,0,U.canvas.width,U.canvas.height),X.forEach(Z=>{const P=ha(c,{x:Z.pixelX,y:Z.pixelY});U.fillStyle=Z.color,U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.fill()}),U.strokeStyle=hl.border,g.forEach(Z=>{const P=ha(c,{x:Z.pixelX,y:Z.pixelY});U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.stroke()}),S){U.font=`${L}px Arial`,U.textAlign=p?"right":"center",U.textBaseline="middle";const Z=p?1.4*L:0;X.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-Z,j.y)})}},[m,p,g,y,u,S,c,w]),E=M.useCallback((U,I)=>{const L=zo;U.clearRect(0,0,U.canvas.width,U.canvas.height);const X=(Z,P,j)=>{U.fillStyle=j,U.strokeStyle="black",U.beginPath(),U.ellipse(Z,P,L,L,0,0,qm),U.fill(),U.stroke()};for(const Z of h){const P=Xh(D,[Z.x,Z.y]),j=ha(c,{x:P[0],y:P[1]}),Y=l.size===0||l.has(Z.unitId)?wr(Ct(Z.unitId)):"rgb(220, 220, 220)";X(j.x,j.y,Y)}},[D,h,l,c]),A=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:b,drawData:Vm}),[t,n,b]),C=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:E,drawData:Vm}),[t,n,E]),T=M.useCallback((U,{ctrlKey:I})=>{const L=N7(c,U),X=km(c),Z=zo/Math.sqrt(X),P=[];for(const j of h){const Y=Xh(D,[j.x,j.y]);Yh(Ff([Y[0]-Z,Y[1]-Z,Z*2,Z*2]),Ff(L))&&(Ff([Y[0]-Z,Y[1]-Z,Z*2,Z*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})},[D,s,h,c]),B=M.useCallback((U,{ctrlKey:I})=>{let L=!1;for(const X of h){const Z=Xh(D,[X.x,X.y]);n_(U,Ff([Z[0]-zo,Z[1]-zo,zo*2,zo*2]))&&(L=!0,s(I?{type:"TOGGLE_UNIT",targetUnit:X.unitId}:{type:"SET_SELECTION",incomingSelectedUnitIds:[X.unitId]}))}L||s({type:"SET_SELECTION",incomingSelectedUnitIds:[]})},[D,s,h]),{onMouseMove:x,onMouseDown:R,onMouseUp:F,paintDragSelectLayer:z}=Hs(t,n,T,B),N=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:z,drawData:Vm}),[t,n,z]);return t>0&&n>0?_.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:x,onMouseUp:F,onMouseDown:R,onWheel:f,children:[A,C,N]}):_.jsx("div",{})},Ff=e=>({xmin:e[0],ymin:e[1],xmax:e[0]+e[2],ymax:e[1]+e[3]}),N7=(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]},R7=e=>{const{data:t,width:n,height:r}=e,[i,a]=M.useState({...xf,onlyShowSelected:!1}),o=30,u=Object.keys(t.channelLocations),l=vN(u,t.channelLocations),s=M.useMemo(()=>({width:n-20,height:r-o,top:0,position:"absolute"}),[n,r]);return _.jsxs("div",{children:[_.jsx("div",{style:s,children:_.jsx(F7,{width:n-20,height:r-o,electrodes:l,units:t.units,disableAutoRotate:t.disableAutoRotate,onlyShowSelected:i.onlyShowSelected})}),_.jsx("div",{style:{position:"absolute",top:r-o,height:o,overflow:"hidden"},children:_.jsx(wf,{options:i,setOptions:a})})]})},O7=({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 S=new Float32Array(m);if(S.length!==h.length*2)throw new Error(`Expected coords length ${h.length*2}, got ${S.length}`);const p=[];for(let g=0;g<h.length;g++)p.push({unitId:h[g],x:S[g*2],y:S[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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit locations data..."}):i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(R7,{data:i,width:n,height:r})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit locations data available"})},z7=({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]),S=M.useCallback(p=>{i&&i(p)},[i]);return _.jsxs(vF,{className:"NiceTable",children:[_.jsx(FF,{children:_.jsxs(SS,{children:[_.jsx(Sf,{style:{width:0}},"_first"),t.map(p=>_.jsx(Sf,{children:p.element?p.element:_.jsx("span",{children:p.label})},p.key))]})}),_.jsx(xF,{children:e.map(p=>_.jsxs(SS,{children:[_.jsxs(Sf,{children:[n&&(f===p.key?_.jsx(I7,{title:r||"",onConfirmDeleteRow:m,rowKey:p.key}):_.jsx(U7,{title:r||"",onDeleteRow:v,rowKey:p.key})),i&&_.jsx($7,{title:a||"",onEditRow:S,rowKey:p.key}),o!=="none"&&_.jsx(hS,{checked:c[p.key]||!1,onClick:()=>h(p.key),disabled:s})]}),t.map(g=>_.jsx(Sf,{children:_.jsx("span",{children:k7(p.columnValues[g.key])})},g.key))]},p.key))})]})},U7=({title:e,rowKey:t,onDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t)},[n,t]);return _.jsx(cl,{title:e,onClick:r,children:_.jsx(YD,{})})},I7=({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 _.jsxs("span",{children:["Confirm delete?",_.jsx(cl,{title:e,onClick:r,children:_.jsx(YD,{})}),_.jsx(cl,{title:"Cancel",onClick:i,children:_.jsx(R_,{})})]})},$7=({title:e,rowKey:t,onEditRow:n})=>_.jsx(cl,{title:e,onClick:()=>n&&n(t),children:_.jsx(N_,{})}),k7=e=>e==0?e:e?typeof e=="object"?e.element?e.element:e.text||"":e:"",L7=({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 _.jsx("div",{style:{position:"absolute",width:e,height:t},children:_.jsx(z7,{rows:o,columns:a,selectedRowKeys:n,onSelectedRowKeysChanged:u,selectionMode:"multiple"})})},j7=(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)},H7=e=>_.jsx(ir,{width:e.width,height:e.height,draw:j7,drawData:e}),P7={},q7=({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)},A=o-E.left-E.right,C=u-E.top-E.bottom,T=e.map(R=>({key:R.key,x1:E.left+(R.xStart-l)/(s-l)*A,x2:E.left+(R.xEnd-l)/(s-l)*A,y1:E.top+C*(1-R.height/c),y2:E.top+C,tooltip:R.tooltip,color:R.color})),B=n?n.map(R=>({x:E.left+(R.x-l)/(s-l)*A,label:`${R.label}`})):void 0,x=r?r.map(R=>({x:E.left+(R.x-l)/(s-l)*A,color:R.color})):void 0;return{barBoxes:T,margins:E,pixelTicks:B,pixelVerticalLines:x}},[e,n,r,l,s,c,o,u,i]),m=M.useCallback((E,{ctrlKey:A,shiftKey:C})=>{const T=[],B={x:E[0],y:E[1],width:E[2],height:E[3]};for(const z of f)z.x1<=B.x+B.width&&z.x2>=B.x&&T.push(z.key);const x=o-d.left-d.right,R=(B.x-d.left)/x*(s-l)+l,F=(B.x+B.width-d.left)/x*(s-l)+l;a&&a(B,T,{ctrlKey:A,shiftKey:C,xMin:R,xMax:F})},[f,a,d.left,d.right,o,l,s]),S=M.useCallback(()=>{},[]),{onMouseMove:p,onMouseDown:g,onMouseUp:y,onMouseLeave:D,paintDragSelectLayer:w}=Hs(o,u,m,S),b=M.useMemo(()=>_.jsx(ir,{width:o,height:u,draw:w,drawData:P7}),[o,u,w]);return _.jsxs("div",{style:{width:o,height:u,position:"relative"},onMouseDown:g,onMouseMove:p,onMouseUp:y,onMouseLeave:D,children:[_.jsx(H7,{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v,xLabel:i,width:o,height:u}),b]})},V7=(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},G7=({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),S=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 Y7(h,v,S,a||10)},[n,e,r,a]),d=M.useCallback((h,v,{ctrlKey:m,shiftKey:S,xMin:p,xMax:g})=>{if(S){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 A=s[E];y.push(A)}const D=Math.min(...y.map(E=>E.xStart)),w=Math.max(...y.map(E=>E.xEnd)),b=[];for(const E of n){const A=E.values[e.key];A!==void 0&&D<=A&&A<=w&&b.push(E.unitId)}i(m||S?[...new Set([...r,...b])]:b)},[s,e,r,i,n,o]);return _.jsx(q7,{width:u,height:l,bars:s,range:t,ticks:c,verticalLines:f,onSelectRect:d})},Y7=(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=X7(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}},X7=(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 V7(e*r,t*r).map(i=>i/r)},Z7=(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()})},Q7=e=>_.jsx(ir,{width:e.width,height:e.height,draw:Z7,drawData:e}),K7={},W7=({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,A,C;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?(A=n.min,C=n.max):e.length>0?(A=Math.min(...e.map(T=>T.y)),C=Math.max(...e.map(T=>T.y))):(A=0,C=1),{xMin:b,xMax:E,yMin:A,yMax:C}},[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:A})=>{const C={x:b[0],y:b[1],width:b[2],height:b[3]},T=[];for(const x of e){const R=d({x:x.x,y:x.y}),F={xmin:R.x-x.radius,ymin:R.y-x.radius,xmax:R.x+x.radius,ymax:R.y+x.radius};Yh({xmin:C.x,xmax:C.x+C.width,ymin:C.y,ymax:C.y+C.height},F)&&T.push(x.key)}const B=J7(h,C);r&&r(B,T,{ctrlKey:E,shiftKey:A})},[r,h,e,d]),m=M.useCallback((b,{ctrlKey:E,shiftKey:A})=>{const C={x:b[0],y:b[1]},T={x:C.x,y:C.y,width:1,height:1};let B;for(const x of e){const R=d({x:x.x,y:x.y}),F={xmin:R.x-x.radius,ymin:R.y-x.radius,xmax:R.x+x.radius,ymax:R.y+x.radius};Yh({xmin:T.x,xmax:T.x+T.width,ymin:T.y,ymax:T.y+T.height},F)&&(B=x.key)}i&&i(h(C),B,{ctrlKey:E,shiftKey:A})},[d,e,i,h]),{onMouseMove:S,onMouseDown:p,onMouseUp:g,onMouseLeave:y,paintDragSelectLayer:D}=Hs(a,o,v,m),w=M.useMemo(()=>_.jsx(ir,{width:a,height:o,draw:D,drawData:K7}),[a,o,D]);return _.jsxs("div",{style:{width:a,height:o,position:"relative"},onMouseDown:p,onMouseMove:S,onMouseUp:g,onMouseLeave:y,children:[_.jsx(Q7,{markers:e,margins:u,coord2Pixel:d,width:a,height:o}),w]})},J7=(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)}},eR=({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 S=m.values[e.key],p=m.values[t.key];S!==void 0&&p!==void 0&&v.push({key:m.unitId,x:S,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:S,shiftKey:p})=>{if(p){u&&u(v);return}let g=m;S&&(g=[...new Set([...m,...a])]),o(g)},[o,a,u]),h=M.useCallback((v,m,{ctrlKey:S,shiftKey:p})=>{let g;if(S||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 _.jsx(W7,{width:l,height:s,markers:f,xRange:n,yRange:r,onSelectRect:d,onClickPoint:h})},tR=({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 _.jsx(G7,{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 _.jsx(eR,{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 _.jsx("div",{style:{width:c,textAlign:"center"},children:t?.label||_.jsx("span",{children:" "})});if(e==="left-label")return _.jsx("div",{style:{width:c,height:f,overflow:"hidden",writingMode:"vertical-lr",transform:"rotate(-180deg)",textAlign:"center"},children:t?.label||_.jsx("span",{children:" "})});throw Error(`Unexpected type: ${e}`)}},nR=({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:_.jsx(Tc,{})},{type:"button",callback:()=>s(w=>w/1.3),title:"Decrease box size",icon:_.jsx(Cc,{})}]:[],y=[{type:"text",content:"# bins",title:""},{type:"button",callback:()=>f(w=>w+5),title:"Increase num. histogram bins",icon:_.jsx(Tc,{})},{type:"button",callback:()=>f(w=>Math.max(5,w-5)),title:"Decrease num. histogram bins",icon:_.jsx(Cc,{})}],D={type:"button",callback:()=>h({}),title:"Reset zoom",text:"reset"};return[...g,{type:"divider"},...y,{type:"divider"},D]},[u.length]),S=fl,p=M.useMemo(()=>{const g=y=>{o({type:"SET_SELECTION",incomingSelectedUnitIds:y})};if(u.length===0)return i.map(y=>{const D={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:D}});{const{plotWidth:w,plotHeight:b}=PS(t-S-30-10,n-30-10,u.length),E=[];for(const A of u){const C=i.filter(T=>T.key===A)[0];{const T={type:"left-label",metric1:C,metric2:C,units:v,numHistogramBins:c,width:30,height:b,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`left-label-${A}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}for(const T of u){const B=i.filter(x=>x.key===T)[0];if(C&&B){const x={type:A===T?"histogram":"scatter",metric1:B,metric2:C,metric1Range:d[B.key],metric2Range:d[C.key],units:v,numHistogramBins:c,width:w,height:b,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:R=>{h(A!==T?{...d,[B.key]:{min:R.x,max:R.x+R.width},[C.key]:{min:R.y,max:R.y+R.height}}:{...d,[C.key]:{min:R.x,max:R.x+R.width}})}};E.push({key:`${T}-${A}`,label:x.type==="histogram"?A:void 0,unitId:"",labelColor:"black",props:x})}}}{const A={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:A,hideBorderColor:!0})}for(const A of u){const C=i.filter(B=>B.key===A)[0],T={type:"bottom-label",metric1:C,metric2:C,units:v,numHistogramBins:c,width:w,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`bottom-label-${A}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}return E}},[i,a,v,l,u,c,t,n,o,d,S]);return _.jsxs(Ro,{width:t,height:n,initialPosition:S,adjustable:!1,children:[_.jsx(dl,{width:S,height:n,customActions:m}),_.jsx(wc,{width:0,height:0,disableScroll:u.length>0,children:_.jsx(xc,{plots:p,plotComponent:tR,numPlotsPerRow:u.length===0?void 0:u.length+1})})]})},rR=({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]),_.jsxs(Ro,{width:t,height:n,initialPosition:200,adjustable:!0,children:[_.jsx(L7,{width:0,height:0}),_.jsx(nR,{data:e,width:0,height:0})]})},iR=e=>js(e,{key:Ls,label:Ls,dtype:Ls}),aR=e=>js(e,{unitId:IA([UA,Ls]),values:()=>!0}),oR=e=>js(e,{type:$A("UnitMetricsGraph"),metrics:Cy(iR),units:Cy(aR)}),uR=({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),S=JSON.parse(m);if(c)return;const p={type:"UnitMetricsGraph",metrics:d,units:S.map(g=>({unitId:g.unit_id,values:g.values}))};if(!oR(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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit metrics data..."}):i?_.jsx(lR,{context:t.unitMetricSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(rR,{data:i,width:n,height:r})})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit metrics data available"})},lR=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?_.jsx(_.Fragment,{children:"Waiting for unit metric selection context..."}):_.jsx(hy.Provider,{value:{unitMetricSelection:n,unitMetricSelectionDispatch:r},children:t})},nx=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=rA(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:nx}},rx=()=>{const e={current:Sy},t=[];return{stateRef:e,dispatch:i=>{e.current=BA(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:rx}},ix=()=>{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:ix}},sR=({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]),_.jsx(o,{zarrGroup:f,width:u,height:s,contexts:a})},cR=e=>t=>{const{container:n,zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l}=t;nA.createRoot(n).render(_.jsx(sR,{zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l,component:e}))};(()=>{const e=[{name:"spike_sorting.Autocorrelograms",component:QF},{name:"spike_sorting.AverageWaveforms",component:kN},{name:"spike_sorting.CrossCorrelograms",component:HN},{name:"spike_sorting.RasterPlot",component:w7},{name:"spike_sorting.SpikeAmplitudes",component:C7},{name:"spike_sorting.UnitLocations",component:O7},{name:"spike_sorting.UnitMetricsGraph",component:uR},{name:"spike_sorting.UnitsTable",component:uN},{name:"spike_sorting.SortingCuration",component:aN}],t=window.figpack_p1.registerFPViewComponent;for(const i of e)t({name:i.name,render:cR(i.component)});const n=window.figpack_p1.registerFPViewContextCreator;n({name:"unitSelection",create:rx}),n({name:"unitMetricSelection",create:nx}),n({name:"sortingCuration",create:ix});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},tN={sortingCuration:eN,sortingCurationDispatch:e=>{console.warn("No sortingCurationDispatch function provided.")},curating:!1},wS=Nt.createContext(tN),ES=()=>{const e=M.useContext(wS);if(!e)throw Error("useSortingCuration must be used within a SortingCurationContext.Provider");return e},nN=(e,t)=>e.filter(n=>t.includes(n)),rN=(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];nN(i,o).length>0&&(t[r]=rN(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=>_.jsx(KF,{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=>_.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 A=b.score,C=E.score;return A===void 0&&C!==void 0?-1:A!==void 0&&C===void 0?1:A===void 0&&C===void 0?0:A!==void 0&&C!==void 0?A<C?-1:A>C?1:0:0},dataElement: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,A)=>E<A?-1:E>A?1:0:b.dtype==="int"?(E,A)=>E-A:b.dtype=="bool"?(E,A)=>(E?1:0)-(A?1:0):b.dtype==="float"?(E,A)=>E-A:(E,A)=>E-A,dataElement:E=>_.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}`]||[],A={value:{unitId:b.unitId,mergeGroup:WF(b.unitId,d)},sortValue:b.unitId},C=w[b.unitId],T={_unitId:A,_labels:{value:E,sortValue:E.join(", ")},_similarity:{value:C!==void 0?C.toFixed(3):void 0,sortValue:{unitId:b.unitId,score:C}}};for(const B of e.columns){const x=`${b.values[B.key]!==void 0?b.values[B.key]:""}`;T[B.key]={value:x,sortValue:b.values[B.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 S=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]),D=M.useCallback(()=>{f({type:"REDISTRIBUTE_UNIT_COLORS"})},[f]);return _.jsxs("div",{children:[_.jsx("div",{style:g,onKeyDown:y,children:_.jsx(JF,{columns:v,rows:S,orderedUnitIds:u,visibleUnitIds:h,selectedUnitIds:a,currentUnitId:o,selectionDispatch:f,primarySortRule:s})}),_.jsx("div",{style:{position:"absolute",top:n-p,height:p,overflow:"hidden"},children:_.jsx(wf,{options:r,setOptions:i,onRedistributeUnitColors:D})})]})},iN=({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 S=M.useCallback(j=>{if(r.length===0)return"none";const Y=r.filter($=>(l[$.toString()]||[]).includes(j));return Y.length===0?"none":Y.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(Y=>Y.includes(j)),[l]),D=M.useCallback(j=>{o&&(y(j)||a({type:"SET_LABEL_CHOICES",labelChoices:m.filter(Y=>Y!==j)}))},[m,a,y,o]),w=M.useCallback(j=>s.find(Y=>Y.includes(j)),[s]),b=M.useMemo(()=>{if(r.length===0)return{canMerge:!1,canUnmerge:!1,groupsInvolved:[],unmergedUnits:[]};const j=new Set,Y=[];r.forEach(V=>{const te=w(V);te?j.add(te):Y.push(V)});const $=r.length>=2,q=j.size>0;return{canMerge:$,canUnmerge:q,groupsInvolved:Array.from(j),unmergedUnits:Y}},[r,w]),E=M.useCallback(()=>{o&&(r.length<2||c||a({type:"MERGE_UNITS",unitIds:r}))},[r,c,a,o]),A=M.useCallback(()=>{o&&(r.length===0||c||a({type:"UNMERGE_UNITS",unitIds:r}))},[r,c,a,o]),C=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]),B={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"},R={fontWeight:"bold",marginBottom:"4px",fontSize:"11px",color:"#333"},F={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"},X={...U,backgroundColor:c?"#f8d7da":"#d4edda",borderColor:c?"#f5c6cb":"#c3e6cb",color:c?"#721c24":"#155724"},Z={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 _.jsxs("div",{style:B,children:[_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Selected Units"}),_.jsx("div",{style:{fontSize:"10px",color:"#666"},children:T})]}),_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Label Assignment"}),m.map(j=>{const Y=S(j);return _.jsxs("div",{style:I,onClick:o?()=>p(j):void 0,children:[_.jsx("input",{type:"checkbox",checked:Y==="full",ref:$=>{$&&($.indeterminate=Y==="partial")},onChange:()=>{},style:{marginRight:"4px"},disabled:r.length===0||c}),_.jsx("span",{style:{fontSize:"10px"},children:j})]},j)}),r.length===0&&_.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic"},children:"Select units to assign labels"})]}),_.jsxs("div",{style:x,children:[_.jsx("div",{style:R,children:"Unit Merging"}),r.length>0&&b.groupsInvolved.length>0&&_.jsxs("div",{style:{marginBottom:"6px"},children:[_.jsx("div",{style:{fontSize:"10px",color:"#666",marginBottom:"2px"},children:"Merge groups involving selected units:"}),b.groupsInvolved.map((j,Y)=>{const $={...F,backgroundColor:"#e3f2fd",borderColor:"#90caf9",color:"#1565c0"};return _.jsx("span",{style:$,children:j.join(", ")},Y)})]}),_.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center",flexWrap:"wrap"},children:[_.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"}),_.jsx("button",{onClick:o?A: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&&_.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"4px"},children:[b.groupsInvolved.length>0&&_.jsxs("div",{children:["Selected units in"," ",b.groupsInvolved.length," merge group(s)"]}),b.unmergedUnits.length>0&&_.jsxs("div",{children:[b.unmergedUnits.length," unmerged unit(s) selected"]})]}),r.length===0&&_.jsx("div",{style:{fontSize:"10px",color:"#999",fontStyle:"italic",marginTop:"4px"},children:"Select units to merge or unmerge"})]}),_.jsxs("div",{style:x,children:[_.jsxs("div",{style:Z,onClick:()=>v(!h),children:[_.jsx("span",{style:P,children:"▶"}),"Manage Label Choices"]}),h&&_.jsxs("div",{children:[_.jsx("div",{style:{marginBottom:"4px"},children:m.map(j=>{const Y=y(j);return _.jsxs("span",{style:F,children:[j,!c&&!Y&&_.jsx("span",{style:z,onClick:o?()=>D(j):void 0,title:"Remove label choice",children:"×"})]},j)})}),!c&&_.jsxs("div",{style:{display:"flex",alignItems:"center"},children:[_.jsx("input",{type:"text",value:f,onChange:j=>d(j.target.value),onKeyPress:j=>j.key==="Enter"&&o&&g(),placeholder:"Add label...",style:N}),_.jsx("button",{onClick:o?g:void 0,style:U,disabled:!f.trim(),children:"Add"})]})]})]}),_.jsxs("div",{style:L,children:[_.jsx("button",{onClick:o?C:void 0,style:X,children:c?"Reopen Curation":"Finalize Curation"}),_.jsxs("div",{style:{fontSize:"10px",color:"#666",marginTop:"2px"},children:["Status: ",c?"Closed":"Open"]})]})]})},aN=({zarrGroup:e,contexts:t,width:n,height:r})=>_.jsx(Jr,{context:t.unitSelection,children:_.jsx(TS,{contexts:t,editable:!0,children:_.jsx(oN,{zarrGroup:e,contexts:t,width:n,height:r})})}),oN=({zarrGroup:e,width:t,height:n})=>{const r=e.attrs.default_label_options||[];return _.jsx(iN,{defaultLabelOptions:r,width:t,height:n})},TS=({contexts:e,children:t,editable:n})=>{const{annotations:r,setAnnotation:i}=ZF(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 _.jsx(wS.Provider,{value:{sortingCuration:a,sortingCurationDispatch:o,curating:!!i},children:t})},uN=({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),S=JSON.parse(m);let p;try{const g=await e.getDatasetData("similarity_scores_data",{});if(g&&g.length>0){const y=new Uint8Array(g),D=new TextDecoder("utf-8").decode(y);p=JSON.parse(D)}}catch(g){console.warn("No similarity scores data found: "+g)}if(c)return;a({type:"UnitsTable",columns:d,rows:S,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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading units table data..."}):i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(TS,{contexts:t,editable:!1,children:_.jsx(CS,{data:i,width:n,height:r})})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No units table data available"})},lN=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:_.jsx(F_,{}),keyCode:38},{type:"button",callback:a,title:"Reset scale amplitude",icon:_.jsx(XD,{})},{type:"button",callback:i,title:"Scale amplitude down [shift + mouse-wheel]",icon:_.jsx(M_,{}),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]}),sN=(e,t)=>({forward:_S(e.forward,t.forward),inverse:_S(t.inverse,e.inverse)}),cN=e=>({forward:[...e.map(t=>[...t])],inverse:dN(e)}),fN=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]]],dN=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=cN([[d,0,(1-d)*c.x],[0,d,(1-d)*c.y]]);f>0&&(h=fN(h));let v=sN(h,a);const m=ha(v,{x:0,y:0}),S=ha(v,{x:e,y:t});return 0<=m.x&&m.x<e&&0<=m.y&&m.y<t&&0<=S.x&&S.x<e&&0<=S.y&&S.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)"},hN=2*Math.PI,mN=(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"?gN(e,t):pN(e,t),e.restore()},pN=(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)})}},gN=(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),S=h?m?c.draggedSelected:v?c.selectedHover:c.selected:m?c.dragged:v?c.hover:c.base;return{...d,color:S,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,hN),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,vN=(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}),yN=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}},bN=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},DN=(e,t)=>d_(n=>{const r=Oo+n[0]*(e-2*Oo),i=ml+n[1]*(t-2*ml);return[r,i]}),SN=(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}})},xN=(e,t,n,r,i)=>{const a=e-Oo*2,o=t-ml*2,u=Sc(i),l=zD(i);return P5(a/u,o/l,r/n)},wN=(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]]},EN=(e,t,n,r={})=>{const i=(e-Oo*2)/(t-ml*2),a=bN(n),{boxAspect:o}=yN(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}},AN=(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=DN(e,t),S=SN(n,m),p=(t-2*ml)/(1+n.length);return{transform:m,convertedElectrodes:S,pixelRadius:p}}const{electrodes:o,rotated:u}=EN(e,t,n,{disableAutoRotate:a.disableAutoRotate}),l=FS(o),s=NS(o,l),c=xN(e,t,l,i,s),f=l*c;let d=wN(e,t,c,s);const h=(e-Sc(s)*c)/2,v=AN(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},CN=(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=o_(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},TN=e=>{const t=e.currentTarget.getBoundingClientRect();return[e.clientX-t.x,e.clientY-t.y]},MN=()=>({selectedElectrodeIds:[],setSelectedElectrodeIds:e=>{}}),kS=e=>{const{width:t,height:n,electrodes:r,disableAutoRotate:i,affineTransform:a}=e,{selectedElectrodeIds:o,setSelectedElectrodeIds:u}=MN(),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(CN,{convertedElectrodes:[],pixelRadius:-1,draggedElectrodeIds:[],pendingSelectedElectrodeIds:o||[],dragState:{isActive:!1},xMarginWidth:-1}),{affineTransform:m,handleWheel:S}=Lm(t,n,{shift:!0,alt:!1}),p=M.useMemo(()=>{const T=h.convertedElectrodes.map(B=>{const x=ha(m,{x:B.pixelX,y:B.pixelY});return{...B,pixelX:x.x,pixelY:x.y}});return{...h,convertedElectrodes:T,pixelRadius:h.pixelRadius*Math.sqrt(km(m))}},[m,h]),g=M.useMemo(()=>T=>{const B=TN(T),x=$m(m,{x:B[0],y:B[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),D=M.useRef(0),w=l||_.jsx(f_,{width:t,height:n,newState:h.dragState}),b=M.useCallback(T=>{if(!l_(T,{nextDragStateUpdate:y,nextFrame:D,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})){const x=g(T);v({type:"UPDATEHOVER",point:x})}},[g]),E=M.useCallback(T=>{s_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE"}})},[]),A=M.useCallback(T=>{if(h.dragState.isActive)c_(T,{nextDragStateUpdate:y,reducer:v,reducerOtherProps:{type:"DRAGUPDATE",selectedElectrodeIds:o}});else{const B=g(T);v({type:"UPDATECLICK",point:B,shift:T.shiftKey,ctrl:T.ctrlKey,selectedElectrodeIds:o||[]})}},[h.dragState.isActive,o,g]),C=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 _.jsx(ir,{width:t,height:n,draw:mN,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]),_.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:b,onMouseUp:A,onMouseDown:E,onWheel:S,children:[w,US,C]})},_N=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,S)=>[(c?.length||0)/2+(S-(c?.length||0)/2)*i,m]),v=Zh(e,h);a.push({pointsInPaintBox:v,offsetFromParentCenter:[o.pixelX,o.pixelY],color:l.waveformColors.base})}}}}),a},BN=(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 D=r[y],w=i[y];e.fillStyle="#dddddd",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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,S,p;a&&o&&u&&l?(v=a,m=o,S=u,p=l):a&&o&&!u&&!l?(v=void 0,m=a,S=o,p=void 0):(v=void 0,m=void 0,S=void 0,p=void 0),v&&v.length>0&&p&&p.length>0&&v.forEach((g,y)=>{if(!v||!p)throw Error("unexpected");const D=v[y],w=p[y];e.fillStyle="#dddddd",e.strokeStyle="#dddddd",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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&&S&&S.length>0&&m.forEach((g,y)=>{if(!m||!S)throw Error("unexpected");const D=m[y],w=S[y];e.fillStyle="#bbbbbb",e.strokeStyle="#bbbbbb",e.lineWidth=1,e.translate(D.offsetFromParentCenter[0],D.offsetFromParentCenter[1]),e.beginPath(),e.moveTo(D.pointsInPaintBox[0][0],D.pointsInPaintBox[0][1]);for(let b=0;b<D.pointsInPaintBox.length;b++)e.lineTo(D.pointsInPaintBox[b][0],D.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()},FN=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,S=-i*(.5+1/v),p=a*r/2,g=ze([[m,0,S],[0,-p,0],[0,0,1]]).toArray(),y=ma(g,n,t,"normal",o),D=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),A=ma(g,n,t,"percentile3",o),C=ma(g,n,t,"percentile4",o);b.length===0&&(b=void 0),E.length===0&&(E=void 0),A.length===0&&(A=void 0),C.length===0&&(C=void 0);const T=s==="vertical"?(u-i)/2:0,B={pixelSpacePaths:y,pixelSpacePathsLower:D,pixelSpacePathsUpper:w,pixelSpacePathsPercentile1:b,pixelSpacePathsPercentile2:E,pixelSpacePathsPercentile3:A,pixelSpacePathsPercentile4:C,xMargin:T,waveformWidth:c,affineTransform:f,useUnitColors:d};return _.jsx(ir,{width:u,height:l,draw:BN,drawData:B})},[n,t,a,u,l,i,r,s,c,f,o,d])},NN={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)"}},RN=e=>{const t=e.colors??NN.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:S}=Lm(l,s,{shift:!0,alt:!0}),p=M.useMemo(()=>_.jsx(kS,{electrodes:n,width:l,height:s,layoutMode:o,colors:t,showLabels:c,maxElectrodePixelRadius:v,disableSelection:!0,disableAutoRotate:h,affineTransform:S}),[n,l,s,o,t,c,h,S]),{convertedElectrodes:g,pixelRadius:y,xMargin:D}=jm(l,s,n,o,v,{disableAutoRotate:h}),w=D||Oo,b=M.useMemo(()=>_N(e.peakAmplitude),[e.peakAmplitude]),E=M.useMemo(()=>i*b,[i,b]),A=o==="geom"?y*2:s/n.length,C=o==="geom"?y*2:l-w-(c?2*y:0),T=_.jsx(FN,{electrodes:g,waveforms:r,oneElectrodeHeight:A,oneElectrodeWidth:C,horizontalStretchFactor:a,yScale:E,width:l,height:s,layoutMode:o,waveformWidth:d,affineTransform:S,useUnitColors:f});return _.jsxs("div",{style:{width:l,height:s,position:"relative"},onWheel:m,children:[!u&&p,T]})},ON=({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 S=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 A of w.channelIds)E.push(S.map(C=>C.id).indexOf(A));return{electrodeIndices:E,waveform:w.waveform,waveformStdDev:w.waveformStdDev,waveformPercentiles:w.waveformPercentiles,waveformColors:b}}),[S,n]),D=_.jsx(RN,{waveforms:y,electrodes:S,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?_.jsxs("div",{style:{position:"relative",width:v,height:m},children:[_.jsx("div",{style:{position:"absolute",left:0,top:0,width:g,height:m},children:_.jsx(kS,{electrodes:p,disableSelection:!1,width:g,height:m})}),_.jsx("div",{style:{position:"absolute",left:g,top:0,width:v-g,height:m},children:D})]}):D},zN=({data:e,width:t,height:n})=>{const r=M.useMemo(()=>{const $=[];for(const q of e.averageWaveforms)for(const V of q.channelIds)$.includes(V)||$.push(V);return yr($)},[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,S]=M.useState(!0),[p,g]=M.useState(!1),[y,D]=M.useState(e.showReferenceProbe||!1),[w,b]=M.useState(!1),[E,A]=M.useState(1),[C,T]=M.useState(!0),[B,x]=M.useState(!0);M.useEffect(()=>{c({type:oo,newUnitOrder:yr(e.averageWaveforms.map($=>$.unitId))})},[e.averageWaveforms,c]);const[R,F]=M.useState(2),z=M.useMemo(()=>{let $=0;return e.averageWaveforms.forEach(q=>{q.waveform.forEach(V=>{V.forEach(te=>{const W=Math.abs(te);W>$&&($=W)})})}),$},[e.averageWaveforms]),N=M.useMemo(()=>e.averageWaveforms.filter($=>i.onlyShowSelected?o.has($.unitId):!0).map($=>{const q=[{channelIds:$.channelIds,waveform:IN($.waveform),waveformStdDev:m&&!w?$.waveformStdDev:void 0,waveformPercentiles:m&&!w&&$.waveformPercentiles?$N($.waveformPercentiles,$.waveform):void 0,waveformColor:wr(Ct($.unitId))}],V={allChannelIds:r,channelIds:$.channelIds,units:q,layoutMode:h,hideElectrodes:C,channelLocations:e.channelLocations,samplingFrequency:e.samplingFrequency,peakAmplitude:z,ampScaleFactor:f,horizontalStretchFactor:E,showChannelIds:p,useUnitColors:B,width:120*R+(y?120*R/4:0),height:120*R,showReferenceProbe:y,disableAutoRotate:!0};return{unitId:$.unitId,key:$.unitId,label:`Unit ${$.unitId}`,labelColor:wr(Ct($.unitId)),clickHandler:i.onlyShowSelected?void 0:s($.unitId),props:V}}),[e.averageWaveforms,e.channelLocations,e.samplingFrequency,r,z,h,f,s,i.onlyShowSelected,o,R,m,p,y,w,E,C,B]),U=M.useMemo(()=>l?l.map($=>N.filter(q=>q.unitId===$)[0]).filter($=>$!==void 0):N,[N,l]),I=M.useMemo(()=>w?UN(U):U,[U,w]),L=M.useMemo(()=>[{type:"button",callback:()=>{A($=>$*1.1)},title:"Increase horizontal stretch [alt + mouse-wheel]",icon:_.jsx(B_,{})},{type:"button",callback:()=>{A(1)},title:"Reset scale amplitude",icon:_.jsx(XD,{})},{type:"button",callback:()=>{A($=>$/1.1)},title:"Decrease horizontal stretch [alt + mouse-wheel]",icon:_.jsx(__,{})}],[]),X=M.useMemo(()=>{const $=lN({ampScaleFactor:f,setAmpScaleFactor:d}),q={type:"toggle",subtype:"checkbox",callback:()=>v(se=>se==="geom"?"vertical":"geom"),title:"Show electrode geometry",selected:h==="geom"},V={type:"toggle",subtype:"checkbox",callback:()=>T(se=>!se),title:"Show electrodes",selected:!C},te=[{type:"button",callback:()=>F(se=>se*1.3),title:"Increase box size",icon:_.jsx(Tc,{})},{type:"button",callback:()=>F(se=>se/1.3),title:"Decrease box size",icon:_.jsx(Cc,{})}],W={type:"toggle",subtype:"checkbox",callback:()=>S(se=>!se),title:"Show waveform stdev",selected:m===!0},ne={type:"toggle",subtype:"checkbox",callback:()=>g(se=>!se),title:"Show channel IDs",selected:p===!0},fe={type:"toggle",subtype:"checkbox",callback:()=>D(se=>!se),title:"Show reference probes",selected:y===!0},ee={type:"toggle",subtype:"checkbox",callback:()=>b(se=>!se),title:"Show overlapping",selected:w===!0},le={type:"toggle",subtype:"checkbox",callback:()=>x(se=>!se),title:"Use unit colors",selected:B===!0};return[{type:"divider"},...te,{type:"divider"},...$,{type:"divider"},...L,{type:"divider"},q,V,{type:"divider"},W,{type:"divider"},ne,{type:"divider"},fe,{type:"divider"},ee,{type:"divider"},le]},[h,f,m,p,w,y,L,C,B]),Z=M.useCallback($=>{$.shiftKey&&!$.altKey?$.deltaY<0?d(q=>q*1.3):d(q=>q/1.3):$.altKey&&!$.shiftKey&&($.deltaY<0?A(q=>q*1.1):A(q=>q/1.1))},[]),P=30,j=M.useCallback($=>{$&&$.addEventListener("wheel",q=>{(q.shiftKey||q.altKey)&&q.preventDefault()})},[]),Y=fl;return _.jsxs("div",{ref:$=>j($),onWheel:Z,children:[_.jsxs(Ro,{width:t,height:n-P,initialPosition:Y,adjustable:!1,children:[_.jsx(dl,{width:Y,height:n,customActions:X}),_.jsx(wc,{width:0,height:0,children:_.jsx(xc,{plots:I,plotComponent:ON,selectedPlotKeys:i.onlyShowSelected?void 0:o,currentPlotKey:u})})]}),_.jsx("div",{style:{position:"absolute",top:n-P,height:P,overflow:"hidden"},children:_.jsx(wf,{options:i,setOptions:a})})]})},UN=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]},IN=e=>e.map(t=>{const n=LS(t);return t.map(r=>r-n)}),$N=(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?t_(e):0,kN=e=>_.jsx(Jr,{context:e.contexts.unitSelection,children:_.jsx(LN,{...e})}),LN=({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,S=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`,{}),S){const g=s.find(y=>y.name===d);g&&u.push({unitId:g.unit_id,channelIds:g.channel_ids,waveform:jS(S,m),waveformStdDev:p?jS(p,m):void 0})}}a||i({type:"AverageWaveforms",averageWaveforms:u})})(),()=>{a=!0}},[e]),r?_.jsx(zN,{data:r,width:t,height:n}):_.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,jN=({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 D of o){const w=p.filter(b=>b.unitId1===y&&b.unitId2===D)[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((D,w)=>({key:`${w}`,unitId:D?D.unitId1:0,label:D?g>80?`Unit ${D.unitId1}/${D.unitId2}`:`${D.unitId1}/${D.unitId2}`:"",labelColor:"black",clickHandler:void 0,props:{binEdgesSec:D?D.binEdgesSec:void 0,binCounts:D?D.binCounts:void 0,color:D?.unitId1===D?.unitId2?wr(Ct(D?.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]),S=_.jsxs(Ro,{width:t-s,height:n,initialPosition:c,adjustable:!1,children:[_.jsx(dl,{width:c,height:n,customActions:v}),_.jsx(wc,{width:0,height:0,disableScroll:!0,children:o.length>HS?_.jsxs("div",{children:["Not showing cross-correlogram matrix. Too many units selected (max ="," ",HS,")."]}):o.length===0?_.jsx("div",{children:"Select one or more units to view cross-correlograms."}):_.jsx(xc,{plots:h,plotComponent:xS,selectedPlotKeys:void 0,numPlotsPerRow:o.length})})]});return u?S:_.jsxs("div",{style:{position:"relative",width:t,height:n},children:[_.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:_.jsx(CS,{data:m,width:s,height:n})}),_.jsx("div",{style:{position:"absolute",left:s,top:0,width:t-s,height:n},children:S})]})},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}},HN=({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,D=Array.from(h.slice(y,y+v));l.push({unitId1:g.unit_id1,unitId2:g.unit_id2,binEdgesSec:d,binCounts:D})}const S=e.attrs.hide_unit_selector||!1;o||a({type:"CrossCorrelograms",crossCorrelograms:l,hideUnitSelector:S})})(),()=>{o=!0}},[e]),i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(jN,{data:i,width:n,height:r})}):_.jsx("div",{children:"Loading..."})},PN=1.4,qN=(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??PN;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}},VN=(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)},GN=(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,l)=>{t({type:"setCurrentTime",currentTime:u,ensureVisible:l?.ensureVisible})},[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=qN({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=VN({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=GN({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}},YN=({width:e,height:t,customActions:n})=>!n||n.length===0?null:_.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:_.jsx("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:n.map(r=>r.component?_.jsx("div",{style:{display:"flex",alignItems:"center"},children:r.component},r.id):_.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&&_.jsx("span",{children:r.icon}),r.label]},r.id))})}),XN=e=>{if(!e||!e.current)return;e.current.querySelectorAll("canvas").forEach(n=>{n.addEventListener("wheel",r=>{r.preventDefault()})})},ZN=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")}`},QN=({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 _.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:[_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[_.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"}),_.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"})]}),_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[_.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:"⬅️"}),_.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:"🔍➖"}),_.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:"🔍➕"}),_.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:"➡️"}),_.jsx("div",{style:{width:"1px",height:"20px",backgroundColor:"#dee2e6",margin:"0 4px"}}),_.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:"🏠"})]}),_.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[_.jsx("span",{style:{color:"#6c757d",fontWeight:"500"},children:"Time:"}),_.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?ZN(i):"--:--:--.---"})]})]})},KN=[{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`}],YS=(e,t,n,r)=>{if(t===void 0||n===void 0)return[];if(n<=t)return[];const i=[],a=e/(n-t);for(const o of KN){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},WN=(e,t,n,r)=>M.useMemo(()=>YS(e,t,n,r),[t,n,r,e]),JN=e=>{if(!e||typeof e=="function")return;const t=e.current,n=t&&t.getContext("2d");if(n)return n},e7={position:"absolute",left:0,top:0},XS=e=>{const{width:t,height:n,draw:r,drawData:i}=e,a=M.useRef(null);return M.useEffect(()=>{const o=JN(a);o&&o.canvas&&r(o,i)},[r,a,i]),_.jsx("canvas",{ref:a,width:t,height:n,style:e7})},ZS=(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;t7(e,a,s,i.top,{hideGridlines:o?.hideX},t.hideTimeAxisLabels),e.strokeStyle="lightgray",Hm(e,i.left,s,n-i.right,s),u&&n7(e,u,s,i.left,n-i.right,i.top,{hideGridlines:o?.hideY}),l&&r7(e,l,i.left,i.bottom,i.top,e.canvas.height)},t7=(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))})},n7=(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)})},r7=(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()},i7={},a7=e=>{const{width:t,height:n}=e,r=M.useCallback(i=>{ZS(i,e)},[e]);return _.jsx("span",{className:"TSV2AxesLayer",children:_.jsx(XS,{width:t,height:n,draw:r,drawData:i7})})},o7=(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()}},u7=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 _.jsx(XS,{width:t,height:n,draw:o7,drawData:u})},l7=({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 _.jsx("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none",zIndex:10},children:_.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"}})})},s7=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),[S,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 A=E.clientX-E.currentTarget.getBoundingClientRect().x;s==="select-zoom"?(g.current.selectionStartX=A,g.current.selectionEndX=A,p({startX:A,endX:A})):(g.current.mouseDownAchorX=A,g.current.mouseDownAnchorTime=t(A),g.current.mouseDownAnchorVisibleStartTime=n||null,g.current.mouseDownAnchorPixelToTime=t),g.current.moved=!1}else i&&i(E)},[t,i,n,s]),D=M.useCallback(E=>{if(!E.shiftKey&&!E.ctrlKey&&!E.altKey){const A=E.clientX-E.currentTarget.getBoundingClientRect().x;if(s==="select-zoom"&&g.current.selectionStartX!==null){const C=Math.min(g.current.selectionStartX,A),T=Math.max(g.current.selectionStartX,A);if(Math.abs(T-C)>5){const B=t(C),x=t(T);f(B,x)}else if(!g.current.moved){const B=t(A);if(r(B),l){const x=E.clientY-E.currentTarget.getBoundingClientRect().y;l(A,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 C=t(A);if(r(C),l){const T=E.clientY-E.currentTarget.getBoundingClientRect().y;l(A,T)}}}else a&&a(E)},[a,t,r,s,f,l]),w=M.useCallback(E=>{const A=E.clientX-E.currentTarget.getBoundingClientRect().x,C=t(A);if(m(C),!E.shiftKey&&!E.ctrlKey&&!E.altKey){if(s==="select-zoom"&&g.current.selectionStartX!==null)g.current.selectionEndX=A,p({startX:Math.min(g.current.selectionStartX,A),endX:Math.max(g.current.selectionStartX,A)}),g.current.moved=!0;else if(s==="pan"&&g.current.mouseDownAchorX!==null&&g.current.mouseDownAnchorPixelToTime!==null){const T=g.current.mouseDownAnchorPixelToTime(A),B=g.current.mouseDownAnchorTime,x=g.current.mouseDownAnchorVisibleStartTime;if(B!==null&&x!==null){const R=T-B,F=A-g.current.mouseDownAchorX;if(Math.abs(F)>2||Math.abs(R)>.01){const z=x-R;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:S,handleMouseDown:y,handleMouseUp:D,handleMouseMove:w,handleMouseOut:b}},c7=({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}},f7=23,d7=60,h7=(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)},m7=(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)},p7=(e,t)=>Math.floor(e*Math.pow(10,-(t+1)))*Math.pow(10,t+1),g7=(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}},v7=(e,t,n,r,i)=>{const a=h7(t,n,r,e).map(l=>Math.round(l*1e9)/1e9),o=m7(t,n);return a.map(l=>g7(l,o,i))},QS={ticks:[],datamin:0,datamax:0},y7=(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}},KS=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;i<=1&&(i=1);const a=r??1;if(t===void 0||n===void 0||t===n)return QS;const o=t/a,u=n/a,l=u-o,s=i/d7,c=i/f7,f=y7(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."),QS;const h=p7(o,f.scale);return{ticks:v7(h,o,u,d,f.scale),datamin:o,datamax:u}},b7=e=>{const{datamin:t,datamax:n,userSpecifiedZoom:r}=e;let{pixelHeight:i}=e;return i<=1&&(i=1),M.useMemo(()=>KS({datamin:t,datamax:n,userSpecifiedZoom:r,pixelHeight:i}),[n,t,i,r])},WS=({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:S=!1,drawContentForExport:p,setDrawForExport:g})=>{const{visibleStartTimeSec:y,visibleEndTimeSec:D,zoomTimeseriesSelection:w,panTimeseriesSelection:b,setVisibleTimeRange:E}=_f(),{currentTime:A,setCurrentTime:C,startTimeSec:T,endTimeSec:B}=Mf(),x=M.useMemo(()=>[y,D],[y,D]),{margins:R,canvasWidth:F,canvasHeight:z}=c7({width:e,height:t,leftMargin:d,customToolbarActions:h,hideNavToolbar:m}),N=M.useMemo(()=>y===void 0||D===void 0?()=>0:D<=y?()=>0:H=>R.left+(H-y)/(D-y)*(F-R.left-R.right),[F,y,D,R]),U=M.useMemo(()=>y===void 0||D===void 0?()=>0:D<=y?()=>0:H=>y+(H-R.left)/(F-R.left-R.right)*(D-y),[F,y,D,R]),I=M.useMemo(()=>{const H=s?.yMin||0,G=s?.yMax||0;return G<=H?()=>0:ie=>z-R.bottom-(ie-H)/(G-H)*(z-R.top-R.bottom)},[s,z,R]),L=WN(F,y,D,N),X=b7({datamin:s?.yMin||0,datamax:s?.yMax||0,pixelHeight:z-R.left-R.right}),Z=M.useMemo(()=>({datamin:X.datamin,datamax:X.datamax,ticks:X.ticks.map(H=>({...H,pixelValue:I(H.dataValue)}))}),[X,I]),P=z,j=M.useMemo(()=>_.jsx(a7,{width:F,height:P,timeRange:x,margins:R,timeTicks:L,yTickSet:s?.showTicks?Z:void 0,yLabel:s?.yLabel,gridlineOpts:r,hideTimeAxisLabels:S}),[r,F,P,x,R,L,s?.showTicks,s?.yLabel,Z,S]),Y=M.useMemo(()=>A!==void 0?N(A):void 0,[A,N]),$=M.useMemo(()=>_.jsx(u7,{width:F,height:P,timeRange:x,margins:R,currentTimePixels:Y}),[F,P,x,R,Y]),q=M.useRef(null),[V,te]=M.useState("pan"),{isViewClicked:W,hoverTime:ne,selectionRect:fe,handleMouseDown:ee,handleMouseUp:le,handleMouseMove:se,handleMouseOut:De}=s7({pixelToTime:U,visibleStartTimeSec:y,setCurrentTime:C,onMouseDown:a,onMouseUp:l,onMouseMove:o,onMouseOut:u,onCanvasClick:v,interactionMode:V});M.useEffect(()=>{(f===!1||W)&&XN(q)},[f,W]);const be=M.useCallback(H=>{if(c&&!H.shiftKey||H.deltaY===0||f!==!1&&!W)return;const G=-H.deltaY/100;w(G>0?"in":"out",1.2,ne)},[c,w,ne,f,W]),xe=M.useCallback(H=>{H.key==="="?w("in"):H.key==="-"?w("out"):H.key==="ArrowRight"?b("forward"):H.key==="ArrowLeft"&&b("back"),i&&i(H)},[i,w,b]),we=M.useCallback(()=>{T!==void 0&&B!==void 0&&E(T,B)},[T,B,E]),Re=M.useMemo(()=>_.jsx(l7,{width:F,height:P,selectionRect:fe}),[F,P,fe]),[Ce,Be]=M.useState(null);M.useEffect(()=>{Ce&&n(Ce,F,z,R)},[Ce,F,z,R,n]),M.useEffect(()=>{if(!g)return;g(async G=>{if(!G||!R)return;const ie=oe=>{const de=s?.yMin||0,ue=s?.yMax||0;return ue<=de?0:G.height-R.bottom-(oe-de)/(ue-de)*(G.height-R.top-R.bottom)},J=YS(G.width,y,D,N),he=KS({datamin:s?.yMin,datamax:s?.yMax,pixelHeight:G.height});for(const oe of he.ticks)oe.pixelValue=ie(oe.dataValue);ZS(G.context,{timeTicks:J,margins:R,gridlineOpts:r,yTickSet:he,yLabel:s?.yLabel,width:G.width,height:G.height,hideTimeAxisLabels:S}),p&&await p(G.context,G.width,G.height,R,{exporting:!0})})},[p,g,R,y,D,N,x,r,s,S,I]);const pe=M.useMemo(()=>_.jsxs("div",{style:{position:"relative",overflow:"hidden",width:F,height:P},onWheel:!f||W?be:void 0,onMouseDown:ee,onMouseUp:le,onMouseMove:se,onMouseOut:De,tabIndex:0,onKeyDown:xe,children:[j,_.jsx("canvas",{style:{position:"absolute",width:F,height:P},ref:H=>Be(H),width:F,height:P}),$,Re]}),[j,$,Re,F,P,xe,be,ee,le,se,De,f,W]),O=M.useMemo(()=>_.jsx(QN,{width:e,height:40,interactionMode:V,onInteractionModeChange:te,currentTime:A,onZoomToFit:we}),[e,V,te,A,we]),k=M.useMemo(()=>_.jsx(YN,{width:e,height:40,customActions:h}),[e,h]);return _.jsxs("div",{className:"time-scroll-view-3",ref:q,style:{position:"absolute",width:e,height:t,background:"white"},children:[pe,!m&&_.jsxs("div",{style:{position:"absolute",bottom:0,left:0,right:0},children:[O,k]})]})},JS=15,D7={hideX:!1,hideY:!0},S7={showTicks:!1,yMin:void 0,yMax:void 0},x7=({dataClient:e,width:t,height:n,setDrawForExport:r})=>{const{visibleStartTimeSec:i,visibleEndTimeSec:a}=_f(),{initializeTimeseriesSelection:o}=Mf(),{selectedUnitIds:u,unitIdSelectionDispatch:l}=qr(),[s,c]=M.useState(void 0),f=M.useRef(null),[d,h]=M.useState(null),[v,m]=M.useState(null),[S,p]=M.useState(!1),[g,y]=M.useState(null),[D,w]=M.useState(null),b=M.useMemo(()=>i===void 0||a===void 0?"raster":a-i>120?"heatmap":"raster",[i,a]),E=e.metadata.unitIds;M.useEffect(()=>{e.metadata&&o({startTimeSec:e.metadata.startTimeSec,endTimeSec:e.metadata.endTimeSec,initialVisibleStartTimeSec:e.metadata.startTimeSec,initialVisibleEndTimeSec:e.metadata.endTimeSec})},[o,e.metadata]),M.useEffect(()=>{let $=!1;const q=async()=>{if(!(i===void 0||a===void 0))try{if(b==="raster"){const V=await e.getDataForRange({startTimeSec:i,endTimeSec:a});if($)return;m(V),w(null)}else{const V=e.getSpikeCountsForRange({startTimeSec:i,endTimeSec:a});if($)return;w(V),m(null)}y(null)}catch(V){if($)return;console.error("Error loading data:",V),y(`Error loading data: ${V}`)}};return p(!0),q().finally(()=>{$||p(!1)}),()=>{$=!0}},[e,i,a,b]);const{onlyShowSelected:A,customToolbarActions:C}=GS(),[T,B]=M.useState(t),[x,R]=M.useState(n),[F,z]=M.useState(null),N=M.useMemo(()=>{const $=[];return A&&E.forEach((q,V)=>{u.has(q)&&$.push(V)}),$},[A,u,E]),U=M.useMemo(()=>N.map($=>E[$]),[N,E]),I=M.useCallback(()=>{if(!F||!f.current||!d||!D||!e.metadata||i===void 0||a===void 0)return;if(d.clearRect(0,0,T,x),S&&(d.fillStyle="rgba(0, 0, 0, 0.02)",d.fillRect(0,0,T,x),d.fillStyle="black",d.font="16px Arial",d.textAlign="center",d.fillText("Loading...",T/2,x/2)),g){d.fillStyle="rgba(255, 0, 0, 0.1)",d.fillRect(0,0,T,x),d.fillStyle="red",d.font="14px Arial",d.textAlign="center",d.fillText(g,T/2,x/2);return}const q=x-F.top-F.bottom,V=T-F.left-F.right,te=a-i;let W;if(A){let ee=0;E.forEach((le,se)=>{u.has(le)&&ee++}),W=ee}else E.forEach((ee,le)=>{}),W=E.length;const ne=q/(W||1);d.save(),d.beginPath(),d.rect(F.left,F.top,V,q),d.clip();let fe=1;if(D.counts.forEach(ee=>{A?N.forEach(le=>{const se=ee[le];se>fe&&(fe=se)}):ee.forEach(le=>{le>fe&&(fe=le)})}),D.counts.forEach((ee,le)=>{const se=D.binEdges[le],De=D.binEdges[le+1],be=F.left+(se-i)/te*V,xe=F.left+(De-i)/te*V;if(A)for(let we=0;we<N.length;we++){const Re=N[we],Be=ee[Re]/fe,pe=F.top+(N.length-1-we)*ne,O=ex(Be);d.fillStyle=O,d.fillRect(be,pe,xe-be+.5,ne)}else ee.forEach((we,Re)=>{const Ce=we/fe,Be=F.top+(E.length-1-Re)*ne,pe=ex(Ce);d.fillStyle=pe,d.fillRect(be,Be,xe-be+.5,ne)})}),d.restore(),ne>=JS){d.globalAlpha=1;const ee=A?U:E;ee.forEach((le,se)=>{const be=F.top+(ee.length-1-se)*ne+ne/2,xe=mh(Ct(le));d.fillStyle=xe,d.font="12px Arial",d.textAlign="right",d.fillText(`Unit ${le}`,F.left-5,be)})}},[T,x,F,D,i,a,e.metadata,S,g,d,u,A,E,N,U]),L=M.useCallback(()=>{if(!F||!f.current||!d||!v||!e.metadata||i===void 0||a===void 0)return;if(d.clearRect(0,0,T,x),S&&(d.fillStyle="rgba(0, 0, 0, 0.02)",d.fillRect(0,0,T,x),d.fillStyle="black",d.font="16px Arial",d.textAlign="center",d.fillText("Loading...",T/2,x/2)),g){d.fillStyle="rgba(255, 0, 0, 0.1)",d.fillRect(0,0,T,x),d.fillStyle="red",d.font="14px Arial",d.textAlign="center",d.fillText(g,T/2,x/2);return}const q=x-F.top-F.bottom,V=T-F.left-F.right,te=a-i,W=e.metadata.unitIds,ne={};let fe;if(A){for(let le=0;le<N.length;le++){const se=N[le];ne[se]=le}fe=N.length}else W.forEach((le,se)=>{ne[se]=se}),fe=W.length;const ee=q/(fe||1);d.save(),d.beginPath(),d.rect(F.left,F.top,V,q),d.clip();for(let le=0;le<v.timestamps.length;le++){const se=v.timestamps[le],De=ne[v.unitIndices[le]];if(De===void 0)continue;const be=W[v.unitIndices[le]],xe=F.top+(fe-1-De)*ee+ee/2,we=mh(Ct(be)),Re=s===be,Ce=u.has(be);d.strokeStyle=we,d.lineWidth=Re||Ce?2:1,d.globalAlpha=Ce?1:Re?.8:.6;const Be=F.left+(se-i)/te*V;d.beginPath(),d.moveTo(Be,xe-ee*.4),d.lineTo(Be,xe+ee*.4),d.stroke()}if(d.restore(),ee>=JS){d.globalAlpha=1;const le=A?U:W;le.forEach((se,De)=>{const xe=F.top+(le.length-1-De)*ee+ee/2,we=mh(Ct(se));d.fillStyle=we,d.font="12px Arial",d.textAlign="right",d.fillText(`Unit ${se}`,F.left-5,xe)})}},[T,x,F,v,e.metadata,i,a,S,g,s,u,A,d,U,N]);M.useEffect(()=>{b==="heatmap"&&D?I():L()},[L,I,b,D]);const X=M.useCallback(()=>{},[]),Z=M.useCallback($=>{if(!F||!e.metadata)return;const q=e.metadata.unitIds,V=q.length,te=1-($.y-F.top)/(x-F.top-F.bottom),W=Math.round(te*V-.5);if(0<=W&&W<V)return q[W]},[x,F,e.metadata]),P=M.useCallback($=>{const q=$.currentTarget.getBoundingClientRect(),V={x:$.clientX-q.x,y:$.clientY-q.y},te=Z(V);$.shiftKey||$.ctrlKey?l({type:"TOGGLE_UNIT",targetUnit:te}):l({type:"UNIQUE_SELECT",targetUnit:te})},[Z,l]),j=M.useCallback($=>{const q=$.currentTarget.getBoundingClientRect(),V={x:$.clientX-q.x,y:$.clientY-q.y},te=Z(V);te!==void 0&&c(te)},[Z]),Y=M.useCallback(()=>{c(void 0)},[]);return e.metadata?_.jsx(WS,{width:t,height:n,customToolbarActions:C,onCanvasElement:($,q,V,te)=>{f.current=$;const W=$?.getContext("2d");h(W),B(q),R(V),z(te)},gridlineOpts:D7,onKeyDown:X,onMouseDown:P,onMouseMove:j,onMouseOut:Y,yAxisInfo:S7,setDrawForExport:r}):_.jsx("div",{children:"Loading metadata..."})},ex=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 w7=({zarrGroup:e,contexts:t,width:n,height:r,setDrawForExport:i})=>{const a=E7(e);return a?_.jsx(tx,{context:t.timeseriesSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(x7,{dataClient:a,width:n,height:r,setDrawForExport:i})})}):null},tx=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?_.jsx(_.Fragment,{children:"Waiting for context..."}):_.jsx(VS.Provider,{value:{timeseriesSelection:n,dispatch:r},children:t})},E7=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},A7=({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),S=fl,{onlyShowSelected:p,customToolbarActions:g}=GS(),[y,D]=M.useState(t),[w,b]=M.useState(n),[E,A]=M.useState(null),C=e.metadata;M.useEffect(()=>{C&&i({type:oo,newUnitOrder:yr(C.unitIds)})},[C,i]),M.useEffect(()=>{C&&a({startTimeSec:C.startTimeSec,endTimeSec:C.endTimeSec,initialVisibleStartTimeSec:C.startTimeSec,initialVisibleEndTimeSec:C.endTimeSec})},[a,C]),M.useEffect(()=>{let x=!1;const R=async()=>{if(o!==void 0&&u!==void 0){let F=1e4;for(;;){const z=await e.getDataForRange({startTimeSec:o,endTimeSec:u},{maxNumEvents:F});if(x)return;if(z&&f(z),z.subsampleFactor>1){if(F===1e6)break;F=Math.max(F*3,z.timestamps.length*3),F>1e6&&(F=1e6)}else break}}};return h(!0),m(null),R().catch(F=>{x||m(`Failed to load data: ${F}`),m(`Failed to load data: ${F}`)}).finally(()=>{h(!1)}),()=>{x=!0}},[o,u,e]);const T=M.useMemo(()=>{if(!c||!C||c.amplitudes.length===0)return{yMin:0,yMax:10};let x=1/0,R=-1/0;for(let z=0;z<c.amplitudes.length;z++){const N=C.unitIds[c.unitIndices[z]];if(p?r.has(N):!0){const I=c.amplitudes[z];I<x&&(x=I),I>R&&(R=I)}}if(x===1/0)return{yMin:0,yMax:10};const F=(R-x)*.1;return{yMin:x-F,yMax:R+F}},[c,C,p,r]);M.useEffect(()=>{if(!l||!c||!C||!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 F=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=C.unitIds[c.unitIndices[N]];if(U<o||U>u||!(p?r.has(L):!0))continue;const Z=wr(Ct(L)),j=r.has(L)?1:.3;l.fillStyle=Z,l.globalAlpha=j;const Y=F(U),$=z(I);l.beginPath(),l.arc(Y,$,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,C,o,u,y,w,E,T,r,p,d,v]);const B=M.useMemo(()=>({showTicks:!0,yMin:T.yMin,yMax:T.yMax,yLabel:"Amplitude"}),[T]);return C?_.jsx("div",{children:_.jsxs(Ro,{width:t,height:n,initialPosition:S,adjustable:!1,children:[_.jsx(dl,{width:S,height:n}),_.jsx(WS,{width:t-S,height:n,onCanvasElement:(x,R,F,z)=>{if(!x)return;const N=x.getContext("2d");s(N),D(R),b(F),A(z)},yAxisInfo:B,customToolbarActions:g})]})}):_.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 C7=({zarrGroup:e,contexts:t,width:n,height:r})=>{const i=T7(e);return i?_.jsx(tx,{context:t.timeseriesSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(A7,{dataClient:i,width:n,height:r})})}):null},T7=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},M7=25,qm=2*Math.PI,_7={maxElectrodePixelRadius:M7},Vm={},zo=8,B7=()=>({selectedElectrodeIds:[]}),F7=e=>{const{width:t,height:n,electrodes:r,units:i,disableAutoRotate:a,onlyShowSelected:o}=e,{selectedElectrodeIds:u}=B7(),{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||_7.maxElectrodePixelRadius,m=e.colors??hl,S=e.showLabels??!1,p=e.offsetLabels??!1,{convertedElectrodes:g,pixelRadius:y,transform:D}=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,X=g.map(Z=>{const P=(u||[]).includes(Z.e.id),j=!1,Y=!1,$=P?Y?m.draggedSelected:j?m.selectedHover:m.selected:Y?m.dragged:j?m.hover:m.base;return{...Z,color:$,textColor:P||j&&!Y?m.textDark:m.textLight}});if(U.clearRect(0,0,U.canvas.width,U.canvas.height),X.forEach(Z=>{const P=ha(c,{x:Z.pixelX,y:Z.pixelY});U.fillStyle=Z.color,U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.fill()}),U.strokeStyle=hl.border,g.forEach(Z=>{const P=ha(c,{x:Z.pixelX,y:Z.pixelY});U.beginPath(),U.ellipse(P.x,P.y,L,L,0,0,qm),U.stroke()}),S){U.font=`${L}px Arial`,U.textAlign=p?"right":"center",U.textBaseline="middle";const Z=p?1.4*L:0;X.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-Z,j.y)})}},[m,p,g,y,u,S,c,w]),E=M.useCallback((U,I)=>{const L=zo;U.clearRect(0,0,U.canvas.width,U.canvas.height);const X=(Z,P,j)=>{U.fillStyle=j,U.strokeStyle="black",U.beginPath(),U.ellipse(Z,P,L,L,0,0,qm),U.fill(),U.stroke()};for(const Z of h){const P=Xh(D,[Z.x,Z.y]),j=ha(c,{x:P[0],y:P[1]}),Y=l.size===0||l.has(Z.unitId)?wr(Ct(Z.unitId)):"rgb(220, 220, 220)";X(j.x,j.y,Y)}},[D,h,l,c]),A=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:b,drawData:Vm}),[t,n,b]),C=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:E,drawData:Vm}),[t,n,E]),T=M.useCallback((U,{ctrlKey:I})=>{const L=N7(c,U),X=km(c),Z=zo/Math.sqrt(X),P=[];for(const j of h){const Y=Xh(D,[j.x,j.y]);Yh(Ff([Y[0]-Z,Y[1]-Z,Z*2,Z*2]),Ff(L))&&(Ff([Y[0]-Z,Y[1]-Z,Z*2,Z*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})},[D,s,h,c]),B=M.useCallback((U,{ctrlKey:I})=>{let L=!1;for(const X of h){const Z=Xh(D,[X.x,X.y]);n_(U,Ff([Z[0]-zo,Z[1]-zo,zo*2,zo*2]))&&(L=!0,s(I?{type:"TOGGLE_UNIT",targetUnit:X.unitId}:{type:"SET_SELECTION",incomingSelectedUnitIds:[X.unitId]}))}L||s({type:"SET_SELECTION",incomingSelectedUnitIds:[]})},[D,s,h]),{onMouseMove:x,onMouseDown:R,onMouseUp:F,paintDragSelectLayer:z}=Hs(t,n,T,B),N=M.useMemo(()=>_.jsx(ir,{width:t,height:n,draw:z,drawData:Vm}),[t,n,z]);return t>0&&n>0?_.jsxs("div",{style:{width:t,height:n,position:"relative"},onMouseMove:x,onMouseUp:F,onMouseDown:R,onWheel:f,children:[A,C,N]}):_.jsx("div",{})},Ff=e=>({xmin:e[0],ymin:e[1],xmax:e[0]+e[2],ymax:e[1]+e[3]}),N7=(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]},R7=e=>{const{data:t,width:n,height:r}=e,[i,a]=M.useState({...xf,onlyShowSelected:!1}),o=30,u=Object.keys(t.channelLocations),l=vN(u,t.channelLocations),s=M.useMemo(()=>({width:n-20,height:r-o,top:0,position:"absolute"}),[n,r]);return _.jsxs("div",{children:[_.jsx("div",{style:s,children:_.jsx(F7,{width:n-20,height:r-o,electrodes:l,units:t.units,disableAutoRotate:t.disableAutoRotate,onlyShowSelected:i.onlyShowSelected})}),_.jsx("div",{style:{position:"absolute",top:r-o,height:o,overflow:"hidden"},children:_.jsx(wf,{options:i,setOptions:a})})]})},O7=({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 S=new Float32Array(m);if(S.length!==h.length*2)throw new Error(`Expected coords length ${h.length*2}, got ${S.length}`);const p=[];for(let g=0;g<h.length;g++)p.push({unitId:h[g],x:S[g*2],y:S[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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit locations data..."}):i?_.jsx(Jr,{context:t.unitSelection,children:_.jsx(R7,{data:i,width:n,height:r})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit locations data available"})},z7=({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]),S=M.useCallback(p=>{i&&i(p)},[i]);return _.jsxs(vF,{className:"NiceTable",children:[_.jsx(FF,{children:_.jsxs(SS,{children:[_.jsx(Sf,{style:{width:0}},"_first"),t.map(p=>_.jsx(Sf,{children:p.element?p.element:_.jsx("span",{children:p.label})},p.key))]})}),_.jsx(xF,{children:e.map(p=>_.jsxs(SS,{children:[_.jsxs(Sf,{children:[n&&(f===p.key?_.jsx(I7,{title:r||"",onConfirmDeleteRow:m,rowKey:p.key}):_.jsx(U7,{title:r||"",onDeleteRow:v,rowKey:p.key})),i&&_.jsx($7,{title:a||"",onEditRow:S,rowKey:p.key}),o!=="none"&&_.jsx(hS,{checked:c[p.key]||!1,onClick:()=>h(p.key),disabled:s})]}),t.map(g=>_.jsx(Sf,{children:_.jsx("span",{children:k7(p.columnValues[g.key])})},g.key))]},p.key))})]})},U7=({title:e,rowKey:t,onDeleteRow:n})=>{const r=M.useCallback(()=>{n&&n(t)},[n,t]);return _.jsx(cl,{title:e,onClick:r,children:_.jsx(YD,{})})},I7=({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 _.jsxs("span",{children:["Confirm delete?",_.jsx(cl,{title:e,onClick:r,children:_.jsx(YD,{})}),_.jsx(cl,{title:"Cancel",onClick:i,children:_.jsx(R_,{})})]})},$7=({title:e,rowKey:t,onEditRow:n})=>_.jsx(cl,{title:e,onClick:()=>n&&n(t),children:_.jsx(N_,{})}),k7=e=>e==0?e:e?typeof e=="object"?e.element?e.element:e.text||"":e:"",L7=({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 _.jsx("div",{style:{position:"absolute",width:e,height:t},children:_.jsx(z7,{rows:o,columns:a,selectedRowKeys:n,onSelectedRowKeysChanged:u,selectionMode:"multiple"})})},j7=(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)},H7=e=>_.jsx(ir,{width:e.width,height:e.height,draw:j7,drawData:e}),P7={},q7=({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)},A=o-E.left-E.right,C=u-E.top-E.bottom,T=e.map(R=>({key:R.key,x1:E.left+(R.xStart-l)/(s-l)*A,x2:E.left+(R.xEnd-l)/(s-l)*A,y1:E.top+C*(1-R.height/c),y2:E.top+C,tooltip:R.tooltip,color:R.color})),B=n?n.map(R=>({x:E.left+(R.x-l)/(s-l)*A,label:`${R.label}`})):void 0,x=r?r.map(R=>({x:E.left+(R.x-l)/(s-l)*A,color:R.color})):void 0;return{barBoxes:T,margins:E,pixelTicks:B,pixelVerticalLines:x}},[e,n,r,l,s,c,o,u,i]),m=M.useCallback((E,{ctrlKey:A,shiftKey:C})=>{const T=[],B={x:E[0],y:E[1],width:E[2],height:E[3]};for(const z of f)z.x1<=B.x+B.width&&z.x2>=B.x&&T.push(z.key);const x=o-d.left-d.right,R=(B.x-d.left)/x*(s-l)+l,F=(B.x+B.width-d.left)/x*(s-l)+l;a&&a(B,T,{ctrlKey:A,shiftKey:C,xMin:R,xMax:F})},[f,a,d.left,d.right,o,l,s]),S=M.useCallback(()=>{},[]),{onMouseMove:p,onMouseDown:g,onMouseUp:y,onMouseLeave:D,paintDragSelectLayer:w}=Hs(o,u,m,S),b=M.useMemo(()=>_.jsx(ir,{width:o,height:u,draw:w,drawData:P7}),[o,u,w]);return _.jsxs("div",{style:{width:o,height:u,position:"relative"},onMouseDown:g,onMouseMove:p,onMouseUp:y,onMouseLeave:D,children:[_.jsx(H7,{barBoxes:f,margins:d,pixelTicks:h,pixelVerticalLines:v,xLabel:i,width:o,height:u}),b]})},V7=(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},G7=({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),S=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 Y7(h,v,S,a||10)},[n,e,r,a]),d=M.useCallback((h,v,{ctrlKey:m,shiftKey:S,xMin:p,xMax:g})=>{if(S){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 A=s[E];y.push(A)}const D=Math.min(...y.map(E=>E.xStart)),w=Math.max(...y.map(E=>E.xEnd)),b=[];for(const E of n){const A=E.values[e.key];A!==void 0&&D<=A&&A<=w&&b.push(E.unitId)}i(m||S?[...new Set([...r,...b])]:b)},[s,e,r,i,n,o]);return _.jsx(q7,{width:u,height:l,bars:s,range:t,ticks:c,verticalLines:f,onSelectRect:d})},Y7=(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=X7(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}},X7=(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 V7(e*r,t*r).map(i=>i/r)},Z7=(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()})},Q7=e=>_.jsx(ir,{width:e.width,height:e.height,draw:Z7,drawData:e}),K7={},W7=({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,A,C;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?(A=n.min,C=n.max):e.length>0?(A=Math.min(...e.map(T=>T.y)),C=Math.max(...e.map(T=>T.y))):(A=0,C=1),{xMin:b,xMax:E,yMin:A,yMax:C}},[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:A})=>{const C={x:b[0],y:b[1],width:b[2],height:b[3]},T=[];for(const x of e){const R=d({x:x.x,y:x.y}),F={xmin:R.x-x.radius,ymin:R.y-x.radius,xmax:R.x+x.radius,ymax:R.y+x.radius};Yh({xmin:C.x,xmax:C.x+C.width,ymin:C.y,ymax:C.y+C.height},F)&&T.push(x.key)}const B=J7(h,C);r&&r(B,T,{ctrlKey:E,shiftKey:A})},[r,h,e,d]),m=M.useCallback((b,{ctrlKey:E,shiftKey:A})=>{const C={x:b[0],y:b[1]},T={x:C.x,y:C.y,width:1,height:1};let B;for(const x of e){const R=d({x:x.x,y:x.y}),F={xmin:R.x-x.radius,ymin:R.y-x.radius,xmax:R.x+x.radius,ymax:R.y+x.radius};Yh({xmin:T.x,xmax:T.x+T.width,ymin:T.y,ymax:T.y+T.height},F)&&(B=x.key)}i&&i(h(C),B,{ctrlKey:E,shiftKey:A})},[d,e,i,h]),{onMouseMove:S,onMouseDown:p,onMouseUp:g,onMouseLeave:y,paintDragSelectLayer:D}=Hs(a,o,v,m),w=M.useMemo(()=>_.jsx(ir,{width:a,height:o,draw:D,drawData:K7}),[a,o,D]);return _.jsxs("div",{style:{width:a,height:o,position:"relative"},onMouseDown:p,onMouseMove:S,onMouseUp:g,onMouseLeave:y,children:[_.jsx(Q7,{markers:e,margins:u,coord2Pixel:d,width:a,height:o}),w]})},J7=(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)}},eR=({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 S=m.values[e.key],p=m.values[t.key];S!==void 0&&p!==void 0&&v.push({key:m.unitId,x:S,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:S,shiftKey:p})=>{if(p){u&&u(v);return}let g=m;S&&(g=[...new Set([...m,...a])]),o(g)},[o,a,u]),h=M.useCallback((v,m,{ctrlKey:S,shiftKey:p})=>{let g;if(S||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 _.jsx(W7,{width:l,height:s,markers:f,xRange:n,yRange:r,onSelectRect:d,onClickPoint:h})},tR=({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 _.jsx(G7,{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 _.jsx(eR,{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 _.jsx("div",{style:{width:c,textAlign:"center"},children:t?.label||_.jsx("span",{children:" "})});if(e==="left-label")return _.jsx("div",{style:{width:c,height:f,overflow:"hidden",writingMode:"vertical-lr",transform:"rotate(-180deg)",textAlign:"center"},children:t?.label||_.jsx("span",{children:" "})});throw Error(`Unexpected type: ${e}`)}},nR=({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:_.jsx(Tc,{})},{type:"button",callback:()=>s(w=>w/1.3),title:"Decrease box size",icon:_.jsx(Cc,{})}]:[],y=[{type:"text",content:"# bins",title:""},{type:"button",callback:()=>f(w=>w+5),title:"Increase num. histogram bins",icon:_.jsx(Tc,{})},{type:"button",callback:()=>f(w=>Math.max(5,w-5)),title:"Decrease num. histogram bins",icon:_.jsx(Cc,{})}],D={type:"button",callback:()=>h({}),title:"Reset zoom",text:"reset"};return[...g,{type:"divider"},...y,{type:"divider"},D]},[u.length]),S=fl,p=M.useMemo(()=>{const g=y=>{o({type:"SET_SELECTION",incomingSelectedUnitIds:y})};if(u.length===0)return i.map(y=>{const D={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:D}});{const{plotWidth:w,plotHeight:b}=PS(t-S-30-10,n-30-10,u.length),E=[];for(const A of u){const C=i.filter(T=>T.key===A)[0];{const T={type:"left-label",metric1:C,metric2:C,units:v,numHistogramBins:c,width:30,height:b,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`left-label-${A}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}for(const T of u){const B=i.filter(x=>x.key===T)[0];if(C&&B){const x={type:A===T?"histogram":"scatter",metric1:B,metric2:C,metric1Range:d[B.key],metric2Range:d[C.key],units:v,numHistogramBins:c,width:w,height:b,selectedUnitIds:a,setSelectedUnitIds:g,onZoomToRect:R=>{h(A!==T?{...d,[B.key]:{min:R.x,max:R.x+R.width},[C.key]:{min:R.y,max:R.y+R.height}}:{...d,[C.key]:{min:R.x,max:R.x+R.width}})}};E.push({key:`${T}-${A}`,label:x.type==="histogram"?A:void 0,unitId:"",labelColor:"black",props:x})}}}{const A={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:A,hideBorderColor:!0})}for(const A of u){const C=i.filter(B=>B.key===A)[0],T={type:"bottom-label",metric1:C,metric2:C,units:v,numHistogramBins:c,width:w,height:30,selectedUnitIds:a,setSelectedUnitIds:g};E.push({key:`bottom-label-${A}`,label:void 0,unitId:"",labelColor:"black",props:T,hideBorderColor:!0})}return E}},[i,a,v,l,u,c,t,n,o,d,S]);return _.jsxs(Ro,{width:t,height:n,initialPosition:S,adjustable:!1,children:[_.jsx(dl,{width:S,height:n,customActions:m}),_.jsx(wc,{width:0,height:0,disableScroll:u.length>0,children:_.jsx(xc,{plots:p,plotComponent:tR,numPlotsPerRow:u.length===0?void 0:u.length+1})})]})},rR=({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]),_.jsxs(Ro,{width:t,height:n,initialPosition:200,adjustable:!0,children:[_.jsx(L7,{width:0,height:0}),_.jsx(nR,{data:e,width:0,height:0})]})},iR=e=>js(e,{key:Ls,label:Ls,dtype:Ls}),aR=e=>js(e,{unitId:IA([UA,Ls]),values:()=>!0}),oR=e=>js(e,{type:$A("UnitMetricsGraph"),metrics:Cy(iR),units:Cy(aR)}),uR=({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),S=JSON.parse(m);if(c)return;const p={type:"UnitMetricsGraph",metrics:d,units:S.map(g=>({unitId:g.unit_id,values:g.values}))};if(!oR(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?_.jsxs("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:["Error: ",o]}):l?_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"Loading unit metrics data..."}):i?_.jsx(lR,{context:t.unitMetricSelection,children:_.jsx(Jr,{context:t.unitSelection,children:_.jsx(rR,{data:i,width:n,height:r})})}):_.jsx("div",{style:{width:n,height:r,display:"flex",alignItems:"center",justifyContent:"center",color:"#666",backgroundColor:"#f5f5f5"},children:"No unit metrics data available"})},lR=({context:e,children:t})=>{const{state:n,dispatch:r}=Ef(e);return!r||!n?_.jsx(_.Fragment,{children:"Waiting for unit metric selection context..."}):_.jsx(hy.Provider,{value:{unitMetricSelection:n,unitMetricSelectionDispatch:r},children:t})},nx=()=>{const e={current:{}},t=[];return{stateRef:e,dispatch:i=>{e.current=rA(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:nx}},rx=()=>{const e={current:Sy},t=[];return{stateRef:e,dispatch:i=>{e.current=BA(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:rx}},ix=()=>{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:ix}},sR=({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]),_.jsx(o,{zarrGroup:f,width:u,height:s,contexts:a})},cR=e=>t=>{const{container:n,zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l}=t;nA.createRoot(n).render(_.jsx(sR,{zarrGroup:r,width:i,height:a,onResize:o,onDataChange:u,contexts:l,component:e}))};(()=>{const e=[{name:"spike_sorting.Autocorrelograms",component:QF},{name:"spike_sorting.AverageWaveforms",component:kN},{name:"spike_sorting.CrossCorrelograms",component:HN},{name:"spike_sorting.RasterPlot",component:w7},{name:"spike_sorting.SpikeAmplitudes",component:C7},{name:"spike_sorting.UnitLocations",component:O7},{name:"spike_sorting.UnitMetricsGraph",component:uR},{name:"spike_sorting.UnitsTable",component:uN},{name:"spike_sorting.SortingCuration",component:aN}],t=window.figpack_p1.registerFPViewComponent;for(const i of e)t({name:i.name,render:cR(i.component)});const n=window.figpack_p1.registerFPViewContextCreator;n({name:"unitSelection",create:rx}),n({name:"unitMetricSelection",create:nx}),n({name:"sortingCuration",create:ix});const r=window.figpack_p1.registerFPExtension;r({name:"figpack-spike-sorting"})})()})();
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{figpack_spike_sorting-0.1.6 → figpack_spike_sorting-0.1.7}/figpack_spike_sorting/views/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|