@fnndsc/argus 0.10.0 → 0.12.0

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.
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-CyzBYFSJ.js","./_commonjsHelpers-CE1G-McA.js","./index-C19QNF8p.js","./index-OFbQkEGT.css"])))=>i.map(i=>d[i]);
2
- import{_ as h,I as u}from"./index-C19QNF8p.js";const c={gray:"gray",hot:"hot",jet:"jet",cool:"cool"},d={wl:"contrast",pan:"pan",length:"measurement",angle:"angle"};class v{name="niivue";host;path;nv=null;module=null;layout="mpr";tool="wl";colormap="gray";slice=0;slices=0;refused=0;disposed=!1;constructor(s,t){this.host=s,this.path=t}async open(s){const t=document.createElement("canvas");t.className="image-canvas",s.appendChild(t),this.host.readout_set("LOADING"),this.host.progress_set({label:"READING VOLUME",done:0,total:0});const e=performance.now();if(this.module=await h(()=>import("./index-CyzBYFSJ.js"),__vite__mapDeps([0,1,2,3]),import.meta.url),this.disposed)return;const i=new this.module.Niivue({isResizeCanvas:!0,logLevel:"error",dragAndDropEnabled:!1,crosshairWidth:.4,crosshairWidthUnit:"percent"});i.onLocationChange=o=>{const r=o,l=r.vox?.[2];l!==void 0&&(this.slice=l+1),this.host.readout_set(`${this.slices>0?`SLICE ${this.slice} OF ${this.slices} · `:""}${r.string??""}`)},await i.attachToCanvas(t);const n=this.path.split("/").pop()??"volume.nii.gz";try{await i.loadVolumes([{url:`${location.origin}${this.host.source.url_of(this.path)}`,name:n}])}catch(o){this.refused=1,this.host.progress_set(null),this.host.readout_set("REFUSED 1 OF 1"),this.host.note(`image: ${this.path}: ${o instanceof Error?o.message:String(o)}`);return}if(this.host.progress_set(null),this.disposed)return;this.nv=i;const a=i.volumes[0]?.dims;this.slices=a?.[3]??0,i.setSliceType(i.sliceTypeMultiplanar),this.layout="mpr",this.host.readout_set(`${this.slices} SLICES`),this.host.note(`image: ${n} drawn in ${Math.round(performance.now()-e)} ms`),this.host.regard(this.path)}async layout_set(s){return s==="slab"||this.nv===null?!1:(this.nv.setSliceType(s==="single"?this.nv.sliceTypeAxial:s==="mpr"?this.nv.sliceTypeMultiplanar:this.nv.sliceTypeRender),this.layout=s,this.host.readout_set(`${this.slices} SLICES`),!0)}slice_set(s){if(this.nv===null||this.slices===0)return!1;const t=Math.max(1,Math.min(s,this.slices)),e=this.slice>0?this.slice:Math.ceil(this.slices/2);return this.nv.moveCrosshairInVox(0,0,t-e),this.slice=t,!0}wl_set(s,t){const e=this.nv?.volumes[0];return this.nv===null||e===void 0?!1:(e.cal_min=s,e.cal_max=t,this.nv.updateGLVolume(),!0)}colormap_set(s){const t=this.nv?.volumes[0];return this.nv===null||t?.id===void 0?!1:(this.colormap=s,this.nv.setColormap(t.id,c[s]),!0)}toolsOffered_get(){return u}ghost_set(s){return!1}tool_set(s){const t=d[s];return this.nv===null||t===void 0?!1:(this.nv.setDragMode(t),this.tool=s,!0)}annotations_export(){return Promise.resolve(null)}annotations_import(){return Promise.resolve(0)}async slices_fill(){return this.nv!==null}state_get(){return{engine:"niivue",layout:this.layout,slice:this.slice,slices:this.slices,tool:this.tool,primaryTool:this.tool,refused:this.refused,annotations:0,filled:this.nv!==null,colormap:this.colormap}}dispose(){this.disposed=!0,this.nv=null}}export{v as NiivueEngine};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-CTKW4bNT.js","./_commonjsHelpers-CE1G-McA.js","./index-QlzdWpod.js","./index-BizDkoHX.css"])))=>i.map(i=>d[i]);
2
+ import{_ as h,I as u}from"./index-QlzdWpod.js";const c={gray:"gray",hot:"hot",jet:"jet",cool:"cool"},d={wl:"contrast",pan:"pan",length:"measurement",angle:"angle"};class v{name="niivue";host;path;nv=null;module=null;layout="mpr";tool="wl";colormap="gray";slice=0;slices=0;refused=0;disposed=!1;constructor(s,t){this.host=s,this.path=t}async open(s){const t=document.createElement("canvas");t.className="image-canvas",s.appendChild(t),this.host.readout_set("LOADING"),this.host.progress_set({label:"READING VOLUME",done:0,total:0});const e=performance.now();if(this.module=await h(()=>import("./index-CTKW4bNT.js"),__vite__mapDeps([0,1,2,3]),import.meta.url),this.disposed)return;const i=new this.module.Niivue({isResizeCanvas:!0,logLevel:"error",dragAndDropEnabled:!1,crosshairWidth:.4,crosshairWidthUnit:"percent"});i.onLocationChange=o=>{const r=o,l=r.vox?.[2];l!==void 0&&(this.slice=l+1),this.host.readout_set(`${this.slices>0?`SLICE ${this.slice} OF ${this.slices} · `:""}${r.string??""}`)},await i.attachToCanvas(t);const n=this.path.split("/").pop()??"volume.nii.gz";try{await i.loadVolumes([{url:`${location.origin}${this.host.source.url_of(this.path)}`,name:n}])}catch(o){this.refused=1,this.host.progress_set(null),this.host.readout_set("REFUSED 1 OF 1"),this.host.note(`image: ${this.path}: ${o instanceof Error?o.message:String(o)}`);return}if(this.host.progress_set(null),this.disposed)return;this.nv=i;const a=i.volumes[0]?.dims;this.slices=a?.[3]??0,i.setSliceType(i.sliceTypeMultiplanar),this.layout="mpr",this.host.readout_set(`${this.slices} SLICES`),this.host.note(`image: ${n} drawn in ${Math.round(performance.now()-e)} ms`),this.host.regard(this.path)}async layout_set(s){return s==="slab"||this.nv===null?!1:(this.nv.setSliceType(s==="single"?this.nv.sliceTypeAxial:s==="mpr"?this.nv.sliceTypeMultiplanar:this.nv.sliceTypeRender),this.layout=s,this.host.readout_set(`${this.slices} SLICES`),!0)}slice_set(s){if(this.nv===null||this.slices===0)return!1;const t=Math.max(1,Math.min(s,this.slices)),e=this.slice>0?this.slice:Math.ceil(this.slices/2);return this.nv.moveCrosshairInVox(0,0,t-e),this.slice=t,!0}wl_set(s,t){const e=this.nv?.volumes[0];return this.nv===null||e===void 0?!1:(e.cal_min=s,e.cal_max=t,this.nv.updateGLVolume(),!0)}colormap_set(s){const t=this.nv?.volumes[0];return this.nv===null||t?.id===void 0?!1:(this.colormap=s,this.nv.setColormap(t.id,c[s]),!0)}toolsOffered_get(){return u}ghost_set(s){return!1}tool_set(s){const t=d[s];return this.nv===null||t===void 0?!1:(this.nv.setDragMode(t),this.tool=s,!0)}annotations_export(){return Promise.resolve(null)}annotations_import(){return Promise.resolve(0)}async slices_fill(){return this.nv!==null}state_get(){return{engine:"niivue",layout:this.layout,slice:this.slice,slices:this.slices,tool:this.tool,primaryTool:this.tool,refused:this.refused,annotations:0,filled:this.nv!==null,colormap:this.colormap}}dispose(){this.disposed=!0,this.nv=null}}export{v as NiivueEngine};
@@ -1,4 +1,4 @@
1
- import{m as v,as as _e,R as gt,K as Pe,L as Ge,W as ke,N as Le,k as de,E as j,t as ft,i as Me,x as ce,F as vt,Z as ht,h as St,D as dt,al as Tt,c as wt,at as yt,d as Ve,au as Ct,y as ue,ak as le,av as We,j as pe}from"./cornerstoneEngine-Bvuqk7P7.js";import{ae as ze,am as De,an as ae,K as D,k as Q,al as W,D as se,U as Ne,X as Be,B as b,J as xt,E as Et,ak as Rt,$ as $e,a2 as _t,Z as Mt,b as Vt,_ as Ke,ao as Dt,ap as He,aq as Bt,ar as Te,as as mt,z as Ot,at as Ut,au as Ft,av as re,ad as Pt,R as Gt,aw as I,ah as kt,ai as Lt,C as Wt,P as zt,I as Nt,a as $t}from"./Texture--SwN-Vnl.js";import"./index-C19QNF8p.js";import"./_commonjsHelpers-CE1G-McA.js";function Kt(t){return t}function ye(t){if(t===null||t==="null")return null;if(t==="true")return!0;if(t==="false")return!1;if(!(t===void 0||t==="undefined"))return t[0]==="["&&t[t.length-1]==="]"?t.substring(1,t.length-1).split(",").map(e=>ye(e.trim())):t===""||Number.isNaN(Number(t))?t:Number(t)}function Ht(t=!0,e=window.location.search){const a={},s=t?ye:Kt;return new URLSearchParams(e).forEach((n,r)=>{r&&(a[r]=n?s(n):!0)}),a}var bt={toNativeType:ye,extractURLParameters:Ht},It={IS_START:0,IS_NONE:0,IS_ROTATE:1,IS_PAN:2,IS_SPIN:3,IS_DOLLY:4,IS_CAMERA_POSE:11,IS_WINDOW_LEVEL:1024,IS_SLICE:1025},Ce={States:It},{vtkErrorMacro:jt,VOID:Qt}=v;function Yt(t,e,a,s){return t.getRenderWindow().getViews()[0].worldToDisplay(e,a,s,t)}function Xt(t,e,a,s){return t.getRenderWindow().getViews()[0].displayToWorld(e,a,s,t)}var Zt={computeWorldToDisplay:Yt,computeDisplayToWorld:Xt};function Jt(t,e){e.classHierarchy.push("vtkInteractorObserver");const a={...t};function s(){for(;e.subscribedEvents.length;)e.subscribedEvents.pop().unsubscribe()}function n(){ze.handledEvents.forEach(r=>{t[`handle${r}`]&&e.subscribedEvents.push(e._interactor[`on${r}`](o=>e.processEvents?t[`handle${r}`](o):Qt,e.priority))})}t.setInteractor=r=>{r!==e._interactor&&(s(),e._interactor=r,r&&e.enabled&&n(),t.modified())},t.setEnabled=r=>{r!==e.enabled&&(s(),r&&(e._interactor?n():jt(`
1
+ import{m as v,as as _e,R as gt,K as Pe,L as Ge,W as ke,N as Le,k as de,E as j,t as ft,i as Me,x as ce,F as vt,Z as ht,h as St,D as dt,al as Tt,c as wt,at as yt,d as Ve,au as Ct,y as ue,ak as le,av as We,j as pe}from"./cornerstoneEngine-hAkB6jjG.js";import{ae as ze,am as De,an as ae,K as D,k as Q,al as W,D as se,U as Ne,X as Be,B as b,J as xt,E as Et,ak as Rt,$ as $e,a2 as _t,Z as Mt,b as Vt,_ as Ke,ao as Dt,ap as He,aq as Bt,ar as Te,as as mt,z as Ot,at as Ut,au as Ft,av as re,ad as Pt,R as Gt,aw as I,ah as kt,ai as Lt,C as Wt,P as zt,I as Nt,a as $t}from"./Texture-CIGczsau.js";import"./index-QlzdWpod.js";import"./_commonjsHelpers-CE1G-McA.js";function Kt(t){return t}function ye(t){if(t===null||t==="null")return null;if(t==="true")return!0;if(t==="false")return!1;if(!(t===void 0||t==="undefined"))return t[0]==="["&&t[t.length-1]==="]"?t.substring(1,t.length-1).split(",").map(e=>ye(e.trim())):t===""||Number.isNaN(Number(t))?t:Number(t)}function Ht(t=!0,e=window.location.search){const a={},s=t?ye:Kt;return new URLSearchParams(e).forEach((n,r)=>{r&&(a[r]=n?s(n):!0)}),a}var bt={toNativeType:ye,extractURLParameters:Ht},It={IS_START:0,IS_NONE:0,IS_ROTATE:1,IS_PAN:2,IS_SPIN:3,IS_DOLLY:4,IS_CAMERA_POSE:11,IS_WINDOW_LEVEL:1024,IS_SLICE:1025},Ce={States:It},{vtkErrorMacro:jt,VOID:Qt}=v;function Yt(t,e,a,s){return t.getRenderWindow().getViews()[0].worldToDisplay(e,a,s,t)}function Xt(t,e,a,s){return t.getRenderWindow().getViews()[0].displayToWorld(e,a,s,t)}var Zt={computeWorldToDisplay:Yt,computeDisplayToWorld:Xt};function Jt(t,e){e.classHierarchy.push("vtkInteractorObserver");const a={...t};function s(){for(;e.subscribedEvents.length;)e.subscribedEvents.pop().unsubscribe()}function n(){ze.handledEvents.forEach(r=>{t[`handle${r}`]&&e.subscribedEvents.push(e._interactor[`on${r}`](o=>e.processEvents?t[`handle${r}`](o):Qt,e.priority))})}t.setInteractor=r=>{r!==e._interactor&&(s(),e._interactor=r,r&&e.enabled&&n(),t.modified())},t.setEnabled=r=>{r!==e.enabled&&(s(),r&&(e._interactor?n():jt(`
2
2
  The interactor must be set before subscribing to events
3
3
  `)),e.enabled=r,t.modified())},t.computeDisplayToWorld=(r,o,i,u)=>r?e._interactor.getView().displayToWorld(o,i,u,r):null,t.computeWorldToDisplay=(r,o,i,u)=>r?e._interactor.getView().worldToDisplay(o,i,u,r):null,t.setPriority=r=>{a.setPriority(r)&&e._interactor&&(s(),n())}}var qt={enabled:!0,priority:0,processEvents:!0,subscribedEvents:[]};function be(t,e,a={}){Object.assign(e,qt,a),v.obj(t,e),v.event(t,e,"InteractionEvent"),v.event(t,e,"StartInteractionEvent"),v.event(t,e,"EndInteractionEvent"),v.get(t,e,["_interactor","enabled"]),v.setGet(t,e,["priority","processEvents"]),v.moveToProtected(t,e,["interactor"]),Jt(t,e)}var At=v.newInstance(be,"vtkInteractorObserver"),en={newInstance:At,extend:be,...Zt},{States:L}=Ce,ge={Rotate:L.IS_ROTATE,Pan:L.IS_PAN,Spin:L.IS_SPIN,Dolly:L.IS_DOLLY,CameraPose:L.IS_CAMERA_POSE,WindowLevel:L.IS_WINDOW_LEVEL,Slice:L.IS_SLICE};function tn(t,e){e.classHierarchy.push("vtkInteractorStyle"),Object.keys(ge).forEach(a=>{v.event(t,e,`Start${a}Event`),t[`start${a}`]=()=>{e.state===L.IS_NONE&&(e.state=ge[a],e._interactor.requestAnimation(t),t.invokeStartInteractionEvent({type:"StartInteractionEvent"}),t[`invokeStart${a}Event`]({type:`Start${a}Event`}))},v.event(t,e,`End${a}Event`),t[`end${a}`]=()=>{e.state===ge[a]&&(e.state=L.IS_NONE,e._interactor.cancelAnimation(t),t.invokeEndInteractionEvent({type:"EndInteractionEvent"}),t[`invokeEnd${a}Event`]({type:`End${a}Event`}),e._interactor.render())}}),e.getRenderer=a=>e.focusedRenderer||a.pokedRenderer,t.handleKeyPress=a=>{const s=e._interactor;let n=null;switch(a.key){case"r":case"R":e.getRenderer(a).resetCamera(),s.render();break;case"w":case"W":n=e.getRenderer(a).getActors(),n.forEach(r=>{const o=r.getProperty();o.setRepresentationToWireframe&&o.setRepresentationToWireframe()}),s.render();break;case"s":case"S":n=e.getRenderer(a).getActors(),n.forEach(r=>{const o=r.getProperty();o.setRepresentationToSurface&&o.setRepresentationToSurface()}),s.render();break;case"v":case"V":n=e.getRenderer(a).getActors(),n.forEach(r=>{const o=r.getProperty();o.setRepresentationToPoints&&o.setRepresentationToPoints()}),s.render();break}}}var nn={state:L.IS_NONE,handleObservers:1,autoAdjustCameraClippingRange:1};function Ie(t,e,a={}){Object.assign(e,nn,a),en.extend(t,e,a),v.setGet(t,e,["focusedRenderer"]),tn(t,e)}var an=v.newInstance(Ie,"vtkInteractorStyle"),xe={newInstance:an,extend:Ie,...Ce},{States:G}=Ce;function rn(t,e){e.classHierarchy.push("vtkInteractorStyleTrackballCamera"),t.handleMouseMove=a=>{const s=a.position,n=e.getRenderer(a);switch(e.state){case G.IS_ROTATE:t.handleMouseRotate(n,s),t.invokeInteractionEvent({type:"InteractionEvent"});break;case G.IS_PAN:t.handleMousePan(n,s),t.invokeInteractionEvent({type:"InteractionEvent"});break;case G.IS_DOLLY:e.wheelDolly||(t.handleMouseDolly(n,s),t.invokeInteractionEvent({type:"InteractionEvent"}));break;case G.IS_SPIN:t.handleMouseSpin(n,s),t.invokeInteractionEvent({type:"InteractionEvent"});break}e.previousPosition=s},t.handleButton3D=a=>{if(a&&a.pressed&&a.device===De.RightController&&(a.input===ae.Trigger||a.input===ae.TrackPad)){t.startCameraPose();return}a&&!a.pressed&&a.device===De.RightController&&(a.input===ae.Trigger||a.input===ae.TrackPad)&&e.state===G.IS_CAMERA_POSE&&t.endCameraPose()},t.handleMove3D=a=>{e.state===G.IS_CAMERA_POSE&&t.updateCameraPose(a)},t.updateCameraPose=a=>{const s=e.getRenderer(a).getActiveCamera(),n=s.getPhysicalTranslation(),r=.5*.05*s.getPhysicalScale(),o=s.physicalOrientationToWorldDirection([a.orientation.x,a.orientation.y,a.orientation.z,a.orientation.w]);s.setPhysicalTranslation(n[0]+o[0]*r,n[1]+o[1]*r,n[2]+o[2]*r)},t.handleLeftButtonPress=a=>{e.previousPosition=a.position,a.shiftKey?a.controlKey||a.altKey?t.startDolly():t.startPan():a.controlKey||a.altKey?t.startSpin():t.startRotate()},t.handleLeftButtonRelease=()=>{switch(e.state){case G.IS_DOLLY:t.endDolly();break;case G.IS_PAN:t.endPan();break;case G.IS_SPIN:t.endSpin();break;case G.IS_ROTATE:t.endRotate();break}},t.handleStartMouseWheel=()=>{e.wheelDolly=!0,t.startDolly()},t.handleEndMouseWheel=()=>{t.endDolly(),e.wheelDolly=!1},t.handleStartPinch=a=>{e.previousScale=a.scale,t.startDolly()},t.handleEndPinch=()=>{t.endDolly()},t.handleStartRotate=a=>{e.previousRotation=a.rotation,t.startRotate()},t.handleEndRotate=()=>{t.endRotate()},t.handleStartPan=a=>{e.previousTranslation=a.translation,t.startPan()},t.handleEndPan=()=>{t.endPan()},t.handlePinch=a=>{t.dollyByFactor(e.getRenderer(a),a.scale/e.previousScale),e.previousScale=a.scale},t.handlePan=a=>{const s=e.getRenderer(a).getActiveCamera();let n=s.getFocalPoint();n=t.computeWorldToDisplay(e.getRenderer(a),n[0],n[1],n[2]);const r=n[2],o=a.translation,i=e.previousTranslation,u=t.computeDisplayToWorld(e.getRenderer(a),n[0]+o[0]-i[0],n[1]+o[1]-i[1],r),p=t.computeDisplayToWorld(e.getRenderer(a),n[0],n[1],r),c=[];c[0]=p[0]-u[0],c[1]=p[1]-u[1],c[2]=p[2]-u[2],n=s.getFocalPoint();const l=s.getPosition();s.setFocalPoint(c[0]+n[0],c[1]+n[1],c[2]+n[2]),s.setPosition(c[0]+l[0],c[1]+l[1],c[2]+l[2]),e._interactor.getLightFollowCamera()&&e.getRenderer(a).updateLightsGeometryToFollowCamera(),s.orthogonalizeViewUp(),e.previousTranslation=a.translation},t.handleRotate=a=>{const s=e.getRenderer(a).getActiveCamera();s.roll(a.rotation-e.previousRotation),s.orthogonalizeViewUp(),e.previousRotation=a.rotation},t.handleMouseRotate=(a,s)=>{if(!e.previousPosition)return;const n=e._interactor,r=s.x-e.previousPosition.x,o=s.y-e.previousPosition.y,i=n.getView().getViewportSize(a);let u=-.1,p=-.1;i[0]&&i[1]&&(u=-20/i[1],p=-20/i[0]);const c=r*p*e.motionFactor,l=o*u*e.motionFactor,g=a.getActiveCamera();!Number.isNaN(c)&&!Number.isNaN(l)&&(g.azimuth(c),g.elevation(l),g.orthogonalizeViewUp()),e.autoAdjustCameraClippingRange&&a.resetCameraClippingRange(),n.getLightFollowCamera()&&a.updateLightsGeometryToFollowCamera()},t.handleMouseSpin=(a,s)=>{if(!e.previousPosition)return;const n=e._interactor,r=a.getActiveCamera(),o=n.getView().getViewportCenter(a),i=_e(Math.atan2(e.previousPosition.y-o[1],e.previousPosition.x-o[0])),u=_e(Math.atan2(s.y-o[1],s.x-o[0]))-i;Number.isNaN(u)||(r.roll(u),r.orthogonalizeViewUp())},t.handleMousePan=(a,s)=>{if(!e.previousPosition)return;const n=a.getActiveCamera();let r=n.getFocalPoint();r=t.computeWorldToDisplay(a,r[0],r[1],r[2]);const o=r[2],i=t.computeDisplayToWorld(a,s.x,s.y,o),u=t.computeDisplayToWorld(a,e.previousPosition.x,e.previousPosition.y,o),p=[];p[0]=u[0]-i[0],p[1]=u[1]-i[1],p[2]=u[2]-i[2],r=n.getFocalPoint();const c=n.getPosition();n.setFocalPoint(p[0]+r[0],p[1]+r[1],p[2]+r[2]),n.setPosition(p[0]+c[0],p[1]+c[1],p[2]+c[2]),e._interactor.getLightFollowCamera()&&a.updateLightsGeometryToFollowCamera()},t.handleMouseDolly=(a,s)=>{if(!e.previousPosition)return;const n=s.y-e.previousPosition.y,r=e._interactor.getView().getViewportCenter(a),o=e.motionFactor*n/r[1];t.dollyByFactor(a,1.1**o)},t.handleMouseWheel=a=>{const s=1-a.spinY/e.zoomFactor;t.dollyByFactor(e.getRenderer(a),s)},t.dollyByFactor=(a,s)=>{if(Number.isNaN(s))return;const n=a.getActiveCamera();n.getParallelProjection()?n.setParallelScale(n.getParallelScale()/s):(n.dolly(s),e.autoAdjustCameraClippingRange&&a.resetCameraClippingRange()),e._interactor.getLightFollowCamera()&&a.updateLightsGeometryToFollowCamera()}}var sn={motionFactor:10,zoomFactor:10,wheelDolly:!1};function je(t,e,a={}){Object.assign(e,sn,a),xe.extend(t,e,a),v.setGet(t,e,["motionFactor","zoomFactor"]),rn(t,e)}var on=v.newInstance(je,"vtkInteractorStyleTrackballCamera"),cn={newInstance:on,extend:je},{vtkErrorMacro:un}=gt,fe=["setBindGroup","setIndexBuffer","setVertexBuffer","draw","drawIndexed"];function ln(t,e){e.classHierarchy.push("vtkWebGPURenderEncoder"),t.begin=a=>{e.drawCallbacks=[],e.handle=a.beginRenderPass(e.description),e.label&&e.handle.pushDebugGroup(e.label)},t.end=()=>{for(let a=0;a<e.drawCallbacks.length;a++){const s=e.drawCallbacks[a],n=s.pipeline;t.setPipeline(n);for(let r=0;r<s.callbacks.length;r++)s.callbacks[r](t)}e.label&&e.handle.popDebugGroup(),e.handle.end(),e.boundPipeline=null},t.setPipeline=a=>{if(e.boundPipeline===a)return;e.handle.setPipeline(a.getHandle());const s=a.getPipelineDescription(),n=s.fragment?.targets;if(e.colorTextureViews.length!==n.length)console.log(`mismatched attachment counts on pipeline ${n.length} while encoder has ${e.colorTextureViews.length}`),console.trace();else for(let r=0;r<e.colorTextureViews.length;r++){const o=e.colorTextureViews[r].getTexture()?.getFormat();o&&o!==n[r].format&&(console.log(`mismatched attachments for attachment ${r} on pipeline ${n[r].format} while encoder has ${o}`),console.trace())}if(!!e.depthTextureView!="depthStencil"in s)console.log("mismatched depth attachments"),console.trace();else if(e.depthTextureView){const r=e.depthTextureView.getTexture()?.getFormat();r&&r!==s.depthStencil.format&&(console.log(`mismatched depth attachments on pipeline ${s.depthStencil.format} while encoder has ${r}`),console.trace())}e.boundPipeline=a},t.replaceShaderCode=a=>{e.replaceShaderCodeFunction(a)},t.setColorTextureView=(a,s)=>{e.colorTextureViews[a]!==s&&(e.colorTextureViews[a]=s)},t.activateBindGroup=a=>{const s=e.boundPipeline.getDevice(),n=e.boundPipeline.getBindGroupLayoutIndex(a.getLabel());if(n<0){un(`vtkWebGPURenderEncoder: could not find bind group layout ${a.getLabel()}`);return}e.handle.setBindGroup(n,a.getBindGroup(s));const r=s.getBindGroupLayoutDescription(a.getBindGroupLayout(s)),o=s.getBindGroupLayoutDescription(e.boundPipeline.getBindGroupLayout(n));r!==o&&(console.log(`renderEncoder ${e.pipelineHash} mismatched bind group layouts bind group has
4
4
  ${r}
package/dist/index.html CHANGED
@@ -12,8 +12,8 @@
12
12
  href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap"
13
13
  rel="stylesheet"
14
14
  />
15
- <script type="module" crossorigin src="./assets/index-C19QNF8p.js"></script>
16
- <link rel="stylesheet" crossorigin href="./assets/index-OFbQkEGT.css">
15
+ <script type="module" crossorigin src="./assets/index-QlzdWpod.js"></script>
16
+ <link rel="stylesheet" crossorigin href="./assets/index-BizDkoHX.css">
17
17
  </head>
18
18
  <body>
19
19
  <!-- ARGUS's own four sounds, synthesised rather than borrowed
@@ -45,6 +45,13 @@
45
45
  <div class="wrap">
46
46
  <div class="left-frame-top">
47
47
  <button class="panel-1"><span class="brand-mark" aria-hidden="true"></span><span class="brand-label">ARGUS<span class="hop">&nbsp;WEB</span></span></button>
48
+ <!-- The cohort's block sits BETWEEN the two, because the last
49
+ block in this column carries the frame's elbow and its
50
+ colour runs on into the frame below it: 02-CALYPSO is that
51
+ block, and a third one appended after it cut the corner off
52
+ the shape. The cohort is its own thing, so it takes the
53
+ light seat between the two dark ones. -->
54
+ <button class="panel-gather" id="header-gather-pill" title="the cohort: what this session has gathered">01<span class="hop">-GATHER</span></button>
48
55
  <button class="panel-2">02<span class="hop">-CALYPSO</span></button>
49
56
  </div>
50
57
  <div class="right-frame-top">
@@ -59,6 +66,7 @@
59
66
  <div class="header-controls">
60
67
  <button id="audio-pill" class="audio-pill" title="audio on/off">AUDIO</button>
61
68
  <button id="theme-pill" class="theme-pill" title="cycle the theme">LOWER DECKS</button>
69
+ <button id="door-pill" class="door-pill" title="leave this surface by the door it came in; the session stays" hidden>LOG OUT</button>
62
70
  </div>
63
71
  <div id="about-rows"></div>
64
72
  <footer class="about-footer">
@@ -74,6 +82,36 @@
74
82
  CURRENT; a sweep, a feed's walk, or arrivals each take a
75
83
  row with a bar while they move — and the cascade's labeled
76
84
  rows follow. -->
85
+ <!-- The cohort's face. A listing like any other: a rule turning
86
+ through an elbow into a spine, the frame carrying what acts
87
+ on the whole cohort, the rows beneath. -->
88
+ <div class="header-face" id="header-gather">
89
+ <!-- data-frame-host: this field is not in a pane, so it is
90
+ the thing whose `data-modes` opens its own frame. -->
91
+ <div class="gather-listing header-gather-field" data-frame-host>
92
+ <span class="field-rule"></span>
93
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
94
+ <span class="mode-elbow"></span>
95
+ <aside class="mode-frame">
96
+ <button class="strategy-pill gather-filter rail-off" title="filter the cohort (the bar reads FILTERED n/m)">FILTER OFF</button>
97
+ <button class="strategy-pill gather-pull" title="retrieve every member CUBE does not hold yet" hidden>PULL</button>
98
+ <button class="strategy-pill gather-remove" title="empty the cohort — gather clear" hidden>CLEAR</button>
99
+ <!-- The frame acts on the WHOLE listing, so the cohort's
100
+ own PROCESS stands here beside its PULL and REMOVE:
101
+ a row's verbs are that row's, the frame's are the
102
+ listing's. -->
103
+ <button class="strategy-pill gather-process" title="process the whole cohort" hidden>PROCESS</button>
104
+ <!-- A cohort too big for a band deserves a pane. The same
105
+ cohort, a second view of it: the band retracts as it
106
+ goes, and both stay in step because neither owns the
107
+ set they show. -->
108
+ <button class="strategy-pill gather-stage" title="show this cohort as a pane on the main panel">ON STAGE</button>
109
+ <span class="mode-fill"></span>
110
+ </aside>
111
+ <div class="gather-rows"></div>
112
+ </div>
113
+ <span class="pane-state gather-state"></span>
114
+ </div>
77
115
  <div class="header-face" id="header-telemetry"><div id="index-instrument"></div><div id="lane-instrument"></div></div>
78
116
  </div>
79
117
  <div class="bar-panel first-bar-panel">
@@ -231,6 +269,55 @@
231
269
  <div class="dag-empty files-empty">NO FEED IN VIEW &mdash; PRESS RUNS-02, cd INTO A FEED, OR RUN `feed diagram &lt;feed&gt;`</div>
232
270
  </div>
233
271
  </template>
272
+ <template id="tpl-pane-universe">
273
+ <div class="workspace-pane pane-universe">
274
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
275
+ <div class="lcars-bar-horizontal">
276
+ <span class="lcars-title universe-title">UNIVERSE</span>
277
+ <span class="pane-mode"></span>
278
+ <span class="pane-state"></span>
279
+ </div>
280
+ <div class="lcars-bar-end bar-punctuation"></div>
281
+ </div>
282
+ <div class="pane-drawer" hidden>
283
+ <span class="drawer-group drawer-structure">
284
+ <span class="drawer-label">SPLIT</span>
285
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
286
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
287
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
288
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
289
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
290
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
291
+ </span>
292
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
293
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
294
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
295
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
296
+ </span>
297
+ <span class="drawer-group drawer-children"></span>
298
+ </div>
299
+ <!-- The space of everything run here: every feed its own
300
+ molecule, clustered by pipeline shape. The field carries
301
+ the scene only; its two modes ride the frame. -->
302
+ <div class="universe-canvas">
303
+ <span class="field-rule"></span>
304
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
305
+ <span class="mode-elbow"></span>
306
+ <aside class="mode-frame">
307
+ <button class="strategy-pill universe-projection" title="projection: sculpted 3D or flat schematic">3D</button>
308
+ <button class="strategy-pill universe-scale" title="what sizes a sphere: its jobs (log scale) or nothing, shape alone">JOBS</button>
309
+ <button class="strategy-pill universe-refresh" title="ask the session for the space again">REFRESH</button>
310
+ <button class="strategy-pill universe-open" title="this feed in a RUNS pane of its own">OPEN FEED</button>
311
+ <button class="strategy-pill universe-back" title="climb out to the whole space (Esc)">BACK</button>
312
+ <span class="mode-fill"></span>
313
+ </aside>
314
+ <!-- The entered feed's node, indicated: its facts and its
315
+ verbs, overlaying the scene as the DAG pane's do. -->
316
+ <div class="dag-facts universe-facts" hidden></div>
317
+ </div>
318
+ <div class="universe-empty files-empty">NO SPACE YET &mdash; THE SESSION IS ASKED FOR EVERY FEED IT HOLDS</div>
319
+ </div>
320
+ </template>
234
321
  <template id="tpl-pane-gather">
235
322
  <!-- The GATHER pane: a cohort as a listing, born beside the
236
323
  PACS workspace when the first series is gathered. One
@@ -268,6 +355,18 @@
268
355
  <span class="mode-elbow"></span>
269
356
  <aside class="mode-frame">
270
357
  <button class="strategy-pill gather-filter rail-off" title="filter the cohort (the bar reads FILTERED n/m)">FILTER OFF</button>
358
+ <!-- The frame acts on the whole cohort: PULL fetches
359
+ the members CUBE does not hold yet. -->
360
+ <button class="strategy-pill gather-pull" title="retrieve every member CUBE does not hold yet" hidden>PULL</button>
361
+ <!-- REMOVE on a row takes one series out; the frame's
362
+ takes them all, because emptying a cohort one row
363
+ at a time is not a gesture anyone wants. -->
364
+ <button class="strategy-pill gather-remove" title="empty the cohort — gather clear" hidden>CLEAR</button>
365
+ <!-- The frame acts on the WHOLE listing, so the cohort's
366
+ own PROCESS stands here beside its PULL and REMOVE:
367
+ a row's verbs are that row's, the frame's are the
368
+ listing's. -->
369
+ <button class="strategy-pill gather-process" title="process the whole cohort" hidden>PROCESS</button>
271
370
  <span class="mode-fill"></span>
272
371
  </aside>
273
372
  <div class="gather-rows"></div>
@@ -702,6 +801,13 @@
702
801
  until someone opens it — so the control was 22px of
703
802
  clipped label and the operator reported it missing. A
704
803
  control nobody can see is a control that is not there. -->
804
+ <!-- GATHER acts on the whole answer, so it stands beside
805
+ EXPORT CSV, which does too. NOT on the results frame:
806
+ that is the closed spine until someone opens it, which
807
+ is how EXPORT CSV once became 22px of clipped label
808
+ that the operator reported as missing — and this block
809
+ repeated it. A control nobody can see is not there. -->
810
+ <button id="pacs-gather-shown" class="pacs-capsule" title="gather every series the listing is showing, which is the filtered set when a filter is on" hidden>GATHER SHOWN</button>
705
811
  <button id="pacs-export" class="pacs-capsule" title="write the whole answer as CSV into ChRIS storage">EXPORT CSV</button>
706
812
  <!-- Where the table went, said by the pane that made it:
707
813
  a readout, not a capsule, since it answers no press. -->
@@ -716,6 +822,12 @@
716
822
  <span class="mode-elbow"></span>
717
823
  <aside class="mode-frame">
718
824
  <button class="strategy-pill pacs-filter rail-off" title="filter the results (the bar reads FILTERED n/m)">FILTER OFF</button>
825
+ <!-- The frame's verbs act on the WHOLE listing, which is
826
+ what the frame answers to: PULL fetches every series
827
+ the listing is showing, the filtered set when a
828
+ filter is on. It says its count and stands down at
829
+ zero (aegis.adoc: a-readout-that-acts-says-so). -->
830
+ <button id="pacs-pull-shown" class="strategy-pill pacs-pull-shown" title="retrieve every series the listing is showing" hidden>PULL SHOWN</button>
719
831
  <!-- The ROW ZONE is minted here by the listing façade:
720
832
  the indicated study's or series' verbs, one under
721
833
  another (aegis.adoc: a-row-s-verbs-live-in-the-frame). -->
@@ -730,6 +842,10 @@
730
842
  </div>
731
843
  <div class="headtrim"></div>
732
844
  <div class="baseboard"></div>
845
+ <!-- The header's own drag strip, on the boundary it shares with the
846
+ body: the band is sized by the operator, exactly as the console
847
+ drawer is from the other side. Two drawers, one law. -->
848
+ <div id="header-strip" title="drag to resize the header band"></div>
733
849
  <!-- The header's lid strip: appears when the header glides away; click
734
850
  (or Esc) restores it. Same idiom as the console drawer's lid. -->
735
851
  <div id="header-restore" title="restore header" role="button" tabindex="0"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fnndsc/argus",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "ARGUS: the LCARS web surface for mise — a browser console over a calypso session",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -20,7 +20,7 @@
20
20
  "@cornerstonejs/metadata": "^5.8.2",
21
21
  "@cornerstonejs/tools": "^5.8.2",
22
22
  "@cornerstonejs/utils": "^5.8.2",
23
- "@fnndsc/menu": "^0.9.0",
23
+ "@fnndsc/menu": "^0.11.0",
24
24
  "@kitware/vtk.js": "^36.4.1",
25
25
  "@niivue/niivue": "^0.69.0",
26
26
  "@types/three": "^0.185.4",
@@ -32,10 +32,10 @@
32
32
  "three": "^0.185.1"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/jest": "^29.5.14",
36
- "jest": "^29.7.0",
37
- "jest-environment-jsdom": "^29.7.0",
38
- "ts-jest": "^29.2.5",
35
+ "@types/jest": "^30.0.0",
36
+ "jest": "^30.2.0",
37
+ "jest-environment-jsdom": "^30.2.0",
38
+ "ts-jest": "^29.4.5",
39
39
  "typescript": "^5.0.0",
40
40
  "vite": "^7.1.0"
41
41
  },