import{C as fe,V as A,M as dt,T as lt,Q as Nt,S as Ot,a as G,R as ve,P as ye,b as be,c as _,d as B,e as vt,I as ie,O as ne,B as P,F as mt,f as J,A as et,g as X,L as j,h as gt,i as nt,j as ae,k as at,W as ot,l as oe,m as W,D as it,n as F,G as tt,o as Y,p as V,q as Z,E as we,r as q,s as L,t as Rt,u as Ee,v as xt,w as Wt,x as Tt,y as Ce,z as N,H as Me,J as Ct,K as re,N as Te,U as Se}from"./three-Cdmz7B_B.js";import{l as ft,s as It,a as le,b as de,c as ce}from"./d3-BwsdWUnD.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))i(s);new MutationObserver(s=>{for(const a of s)if(a.type==="childList")for(const n of a.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&i(n)}).observe(document,{childList:!0,subtree:!0});function e(s){const a={};return s.integrity&&(a.integrity=s.integrity),s.referrerPolicy&&(a.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?a.credentials="include":s.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(s){if(s.ep)return;s.ep=!0;const a=e(s);fetch(s.href,a)}})();const Gt={type:"change"},Ht={type:"start"},he={type:"end"},yt=new ve,jt=new ye,_e=Math.cos(70*be.DEG2RAD),D=new A,H=2*Math.PI,z={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6},_t=1e-6;class rt extends fe{constructor(t,e=null){super(t,e),this.state=z.NONE,this.enabled=!0,this.target=new A,this.cursor=new A,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minTargetRadius=0,this.maxTargetRadius=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.zoomToCursor=!1,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",BOTTOM:"ArrowDown"},this.mouseButtons={LEFT:dt.ROTATE,MIDDLE:dt.DOLLY,RIGHT:dt.PAN},this.touches={ONE:lt.ROTATE,TWO:lt.DOLLY_PAN},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._domElementKeyEvents=null,this._lastPosition=new A,this._lastQuaternion=new Nt,this._lastTargetPosition=new A,this._quat=new Nt().setFromUnitVectors(t.up,new A(0,1,0)),this._quatInverse=this._quat.clone().invert(),this._spherical=new Ot,this._sphericalDelta=new Ot,this._scale=1,this._panOffset=new A,this._rotateStart=new G,this._rotateEnd=new G,this._rotateDelta=new G,this._panStart=new G,this._panEnd=new G,this._panDelta=new G,this._dollyStart=new G,this._dollyEnd=new G,this._dollyDelta=new G,this._dollyDirection=new A,this._mouse=new G,this._performCursorZoom=!1,this._pointers=[],this._pointerPositions={},this._controlActive=!1,this._onPointerMove=Ae.bind(this),this._onPointerDown=ze.bind(this),this._onPointerUp=$e.bind(this),this._onContextMenu=Ie.bind(this),this._onMouseWheel=Pe.bind(this),this._onKeyDown=De.bind(this),this._onTouchStart=Fe.bind(this),this._onTouchMove=Re.bind(this),this._onMouseDown=ke.bind(this),this._onMouseMove=Le.bind(this),this._interceptControlDown=He.bind(this),this._interceptControlUp=Be.bind(this),this.domElement!==null&&this.connect(),this.update()}connect(){this.domElement.addEventListener("pointerdown",this._onPointerDown),this.domElement.addEventListener("pointercancel",this._onPointerUp),this.domElement.addEventListener("contextmenu",this._onContextMenu),this.domElement.addEventListener("wheel",this._onMouseWheel,{passive:!1}),this.domElement.getRootNode().addEventListener("keydown",this._interceptControlDown,{passive:!0,capture:!0}),this.domElement.style.touchAction="none"}disconnect(){this.domElement.removeEventListener("pointerdown",this._onPointerDown),this.domElement.removeEventListener("pointermove",this._onPointerMove),this.domElement.removeEventListener("pointerup",this._onPointerUp),this.domElement.removeEventListener("pointercancel",this._onPointerUp),this.domElement.removeEventListener("wheel",this._onMouseWheel),this.domElement.removeEventListener("contextmenu",this._onContextMenu),this.stopListenToKeyEvents(),this.domElement.getRootNode().removeEventListener("keydown",this._interceptControlDown,{capture:!0}),this.domElement.style.touchAction="auto"}dispose(){this.disconnect()}getPolarAngle(){return this._spherical.phi}getAzimuthalAngle(){return this._spherical.theta}getDistance(){return this.object.position.distanceTo(this.target)}listenToKeyEvents(t){t.addEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=t}stopListenToKeyEvents(){this._domElementKeyEvents!==null&&(this._domElementKeyEvents.removeEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=null)}saveState(){this.target0.copy(this.target),this.position0.copy(this.object.position),this.zoom0=this.object.zoom}reset(){this.target.copy(this.target0),this.object.position.copy(this.position0),this.object.zoom=this.zoom0,this.object.updateProjectionMatrix(),this.dispatchEvent(Gt),this.update(),this.state=z.NONE}update(t=null){const e=this.object.position;D.copy(e).sub(this.target),D.applyQuaternion(this._quat),this._spherical.setFromVector3(D),this.autoRotate&&this.state===z.NONE&&this._rotateLeft(this._getAutoRotationAngle(t)),this.enableDamping?(this._spherical.theta+=this._sphericalDelta.theta*this.dampingFactor,this._spherical.phi+=this._sphericalDelta.phi*this.dampingFactor):(this._spherical.theta+=this._sphericalDelta.theta,this._spherical.phi+=this._sphericalDelta.phi);let i=this.minAzimuthAngle,s=this.maxAzimuthAngle;isFinite(i)&&isFinite(s)&&(i<-Math.PI?i+=H:i>Math.PI&&(i-=H),s<-Math.PI?s+=H:s>Math.PI&&(s-=H),i<=s?this._spherical.theta=Math.max(i,Math.min(s,this._spherical.theta)):this._spherical.theta=this._spherical.theta>(i+s)/2?Math.max(i,this._spherical.theta):Math.min(s,this._spherical.theta)),this._spherical.phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,this._spherical.phi)),this._spherical.makeSafe(),this.enableDamping===!0?this.target.addScaledVector(this._panOffset,this.dampingFactor):this.target.add(this._panOffset),this.target.sub(this.cursor),this.target.clampLength(this.minTargetRadius,this.maxTargetRadius),this.target.add(this.cursor);let a=!1;if(this.zoomToCursor&&this._performCursorZoom||this.object.isOrthographicCamera)this._spherical.radius=this._clampDistance(this._spherical.radius);else{const n=this._spherical.radius;this._spherical.radius=this._clampDistance(this._spherical.radius*this._scale),a=n!=this._spherical.radius}if(D.setFromSpherical(this._spherical),D.applyQuaternion(this._quatInverse),e.copy(this.target).add(D),this.object.lookAt(this.target),this.enableDamping===!0?(this._sphericalDelta.theta*=1-this.dampingFactor,this._sphericalDelta.phi*=1-this.dampingFactor,this._panOffset.multiplyScalar(1-this.dampingFactor)):(this._sphericalDelta.set(0,0,0),this._panOffset.set(0,0,0)),this.zoomToCursor&&this._performCursorZoom){let n=null;if(this.object.isPerspectiveCamera){const o=D.length();n=this._clampDistance(o*this._scale);const r=o-n;this.object.position.addScaledVector(this._dollyDirection,r),this.object.updateMatrixWorld(),a=!!r}else if(this.object.isOrthographicCamera){const o=new A(this._mouse.x,this._mouse.y,0);o.unproject(this.object);const r=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),this.object.updateProjectionMatrix(),a=r!==this.object.zoom;const l=new A(this._mouse.x,this._mouse.y,0);l.unproject(this.object),this.object.position.sub(l).add(o),this.object.updateMatrixWorld(),n=D.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),this.zoomToCursor=!1;n!==null&&(this.screenSpacePanning?this.target.set(0,0,-1).transformDirection(this.object.matrix).multiplyScalar(n).add(this.object.position):(yt.origin.copy(this.object.position),yt.direction.set(0,0,-1).transformDirection(this.object.matrix),Math.abs(this.object.up.dot(yt.direction))<_e?this.object.lookAt(this.target):(jt.setFromNormalAndCoplanarPoint(this.object.up,this.target),yt.intersectPlane(jt,this.target))))}else if(this.object.isOrthographicCamera){const n=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),n!==this.object.zoom&&(this.object.updateProjectionMatrix(),a=!0)}return this._scale=1,this._performCursorZoom=!1,a||this._lastPosition.distanceToSquared(this.object.position)>_t||8*(1-this._lastQuaternion.dot(this.object.quaternion))>_t||this._lastTargetPosition.distanceToSquared(this.target)>_t?(this.dispatchEvent(Gt),this._lastPosition.copy(this.object.position),this._lastQuaternion.copy(this.object.quaternion),this._lastTargetPosition.copy(this.target),!0):!1}_getAutoRotationAngle(t){return t!==null?H/60*this.autoRotateSpeed*t:H/60/60*this.autoRotateSpeed}_getZoomScale(t){const e=Math.abs(t*.01);return Math.pow(.95,this.zoomSpeed*e)}_rotateLeft(t){this._sphericalDelta.theta-=t}_rotateUp(t){this._sphericalDelta.phi-=t}_panLeft(t,e){D.setFromMatrixColumn(e,0),D.multiplyScalar(-t),this._panOffset.add(D)}_panUp(t,e){this.screenSpacePanning===!0?D.setFromMatrixColumn(e,1):(D.setFromMatrixColumn(e,0),D.crossVectors(this.object.up,D)),D.multiplyScalar(t),this._panOffset.add(D)}_pan(t,e){const i=this.domElement;if(this.object.isPerspectiveCamera){const s=this.object.position;D.copy(s).sub(this.target);let a=D.length();a*=Math.tan(this.object.fov/2*Math.PI/180),this._panLeft(2*t*a/i.clientHeight,this.object.matrix),this._panUp(2*e*a/i.clientHeight,this.object.matrix)}else this.object.isOrthographicCamera?(this._panLeft(t*(this.object.right-this.object.left)/this.object.zoom/i.clientWidth,this.object.matrix),this._panUp(e*(this.object.top-this.object.bottom)/this.object.zoom/i.clientHeight,this.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),this.enablePan=!1)}_dollyOut(t){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale/=t:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_dollyIn(t){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale*=t:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_updateZoomParameters(t,e){if(!this.zoomToCursor)return;this._performCursorZoom=!0;const i=this.domElement.getBoundingClientRect(),s=t-i.left,a=e-i.top,n=i.width,o=i.height;this._mouse.x=s/n*2-1,this._mouse.y=-(a/o)*2+1,this._dollyDirection.set(this._mouse.x,this._mouse.y,1).unproject(this.object).sub(this.object.position).normalize()}_clampDistance(t){return Math.max(this.minDistance,Math.min(this.maxDistance,t))}_handleMouseDownRotate(t){this._rotateStart.set(t.clientX,t.clientY)}_handleMouseDownDolly(t){this._updateZoomParameters(t.clientX,t.clientX),this._dollyStart.set(t.clientX,t.clientY)}_handleMouseDownPan(t){this._panStart.set(t.clientX,t.clientY)}_handleMouseMoveRotate(t){this._rotateEnd.set(t.clientX,t.clientY),this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const e=this.domElement;this._rotateLeft(H*this._rotateDelta.x/e.clientHeight),this._rotateUp(H*this._rotateDelta.y/e.clientHeight),this._rotateStart.copy(this._rotateEnd),this.update()}_handleMouseMoveDolly(t){this._dollyEnd.set(t.clientX,t.clientY),this._dollyDelta.subVectors(this._dollyEnd,this._dollyStart),this._dollyDelta.y>0?this._dollyOut(this._getZoomScale(this._dollyDelta.y)):this._dollyDelta.y<0&&this._dollyIn(this._getZoomScale(this._dollyDelta.y)),this._dollyStart.copy(this._dollyEnd),this.update()}_handleMouseMovePan(t){this._panEnd.set(t.clientX,t.clientY),this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd),this.update()}_handleMouseWheel(t){this._updateZoomParameters(t.clientX,t.clientY),t.deltaY<0?this._dollyIn(this._getZoomScale(t.deltaY)):t.deltaY>0&&this._dollyOut(this._getZoomScale(t.deltaY)),this.update()}_handleKeyDown(t){let e=!1;switch(t.code){case this.keys.UP:t.ctrlKey||t.metaKey||t.shiftKey?this._rotateUp(H*this.rotateSpeed/this.domElement.clientHeight):this._pan(0,this.keyPanSpeed),e=!0;break;case this.keys.BOTTOM:t.ctrlKey||t.metaKey||t.shiftKey?this._rotateUp(-H*this.rotateSpeed/this.domElement.clientHeight):this._pan(0,-this.keyPanSpeed),e=!0;break;case this.keys.LEFT:t.ctrlKey||t.metaKey||t.shiftKey?this._rotateLeft(H*this.rotateSpeed/this.domElement.clientHeight):this._pan(this.keyPanSpeed,0),e=!0;break;case this.keys.RIGHT:t.ctrlKey||t.metaKey||t.shiftKey?this._rotateLeft(-H*this.rotateSpeed/this.domElement.clientHeight):this._pan(-this.keyPanSpeed,0),e=!0;break}e&&(t.preventDefault(),this.update())}_handleTouchStartRotate(t){if(this._pointers.length===1)this._rotateStart.set(t.pageX,t.pageY);else{const e=this._getSecondPointerPosition(t),i=.5*(t.pageX+e.x),s=.5*(t.pageY+e.y);this._rotateStart.set(i,s)}}_handleTouchStartPan(t){if(this._pointers.length===1)this._panStart.set(t.pageX,t.pageY);else{const e=this._getSecondPointerPosition(t),i=.5*(t.pageX+e.x),s=.5*(t.pageY+e.y);this._panStart.set(i,s)}}_handleTouchStartDolly(t){const e=this._getSecondPointerPosition(t),i=t.pageX-e.x,s=t.pageY-e.y,a=Math.sqrt(i*i+s*s);this._dollyStart.set(0,a)}_handleTouchStartDollyPan(t){this.enableZoom&&this._handleTouchStartDolly(t),this.enablePan&&this._handleTouchStartPan(t)}_handleTouchStartDollyRotate(t){this.enableZoom&&this._handleTouchStartDolly(t),this.enableRotate&&this._handleTouchStartRotate(t)}_handleTouchMoveRotate(t){if(this._pointers.length==1)this._rotateEnd.set(t.pageX,t.pageY);else{const i=this._getSecondPointerPosition(t),s=.5*(t.pageX+i.x),a=.5*(t.pageY+i.y);this._rotateEnd.set(s,a)}this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const e=this.domElement;this._rotateLeft(H*this._rotateDelta.x/e.clientHeight),this._rotateUp(H*this._rotateDelta.y/e.clientHeight),this._rotateStart.copy(this._rotateEnd)}_handleTouchMovePan(t){if(this._pointers.length===1)this._panEnd.set(t.pageX,t.pageY);else{const e=this._getSecondPointerPosition(t),i=.5*(t.pageX+e.x),s=.5*(t.pageY+e.y);this._panEnd.set(i,s)}this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd)}_handleTouchMoveDolly(t){const e=this._getSecondPointerPosition(t),i=t.pageX-e.x,s=t.pageY-e.y,a=Math.sqrt(i*i+s*s);this._dollyEnd.set(0,a),this._dollyDelta.set(0,Math.pow(this._dollyEnd.y/this._dollyStart.y,this.zoomSpeed)),this._dollyOut(this._dollyDelta.y),this._dollyStart.copy(this._dollyEnd);const n=(t.pageX+e.x)*.5,o=(t.pageY+e.y)*.5;this._updateZoomParameters(n,o)}_handleTouchMoveDollyPan(t){this.enableZoom&&this._handleTouchMoveDolly(t),this.enablePan&&this._handleTouchMovePan(t)}_handleTouchMoveDollyRotate(t){this.enableZoom&&this._handleTouchMoveDolly(t),this.enableRotate&&this._handleTouchMoveRotate(t)}_addPointer(t){this._pointers.push(t.pointerId)}_removePointer(t){delete this._pointerPositions[t.pointerId];for(let e=0;e({epoch:e.epoch,pressure:e.boundary_radius,crossed:e.coherence<.8}))}async function pe(){return((await Q("/api/coherence/alerts")).alerts??[]).map(t=>({target_id:t.sector,epoch:0,pressure:t.coherence,message:t.message}))}async function Ke(){return((await Q("/api/candidates/planet")).candidates??[]).map(t=>({id:t.id,name:t.id,score:t.score,period:t.period_days,radius:t.radius_earth,depth:t.transit_depth??.005+(1-t.score)*.005,snr:Math.round(t.score*40+5),stellarType:t.stellar_type,distance:t.distance_ly,status:t.status,mass:t.mass_earth??null,eqTemp:t.eq_temp_k??null,discoveryYear:t.discovery_year??0,discoveryMethod:t.discovery_method??"",telescope:t.telescope??"",reference:t.reference??"",transitDepth:t.transit_depth??null}))}async function Ue(){return((await Q("/api/candidates/life")).candidates??[]).map(t=>({id:t.id,name:t.id,score:t.life_score,o2:t.o2_normalized??Math.min(1,t.o2_ppm/21e4),ch4:t.ch4_normalized??Math.min(1,t.ch4_ppb/2500),h2o:t.h2o_normalized??(t.h2o_detected?.85:.2),co2:t.co2_normalized??Math.min(1,t.co2_ppm/1e4),disequilibrium:t.disequilibrium??t.biosig_confidence,habitability:t.habitability_index,atmosphereStatus:t.atmosphere_status??"Unknown",jwstObserved:t.jwst_observed??!1,moleculesConfirmed:t.molecules_confirmed??[],moleculesTentative:t.molecules_tentative??[],reference:t.reference??""}))}async function me(){return Q("/api/witness/log")}async function ue(){var t,e;const p=await Q("/api/status");return{uptime:p.uptime_seconds??0,segments:((t=p.store)==null?void 0:t.total_segments)??0,file_size:((e=p.store)==null?void 0:e.file_size)??0,download_progress:{LIGHT_SEG:1,SPECTRUM_SEG:.85,ORBIT_SEG:1,CAUSAL_SEG:.92}}}async function ge(){const p=await Q("/api/memory/tiers"),t=new Map;for(const e of p.tiers??[])t.set(e.name,{used:Math.round(e.used_mb),total:Math.round(e.capacity_mb)});return{small:t.get("S")??{used:0,total:0},medium:t.get("M")??{used:0,total:0},large:t.get("L")??{used:0,total:0}}}const Mt=[];let I=null,ct=null,ut=1e3,Bt=!1;const Ye=3e4,Ze=2;function Xe(p){try{const t=JSON.parse(p.data);for(const e of Mt)e(t)}catch{}}function qt(){Bt||ct||(ct=setTimeout(()=>{ct=null,xe()},ut),ut=Math.min(ut*Ze,Ye))}function xe(){if(I&&(I.readyState===WebSocket.OPEN||I.readyState===WebSocket.CONNECTING))return;const t=`${location.protocol==="https:"?"wss:":"ws:"}//${location.host}/ws/live`;try{I=new WebSocket(t)}catch{qt();return}I.addEventListener("open",()=>{ut=1e3}),I.addEventListener("message",Xe),I.addEventListener("close",()=>{I=null,qt()}),I.addEventListener("error",()=>{I==null||I.close()})}function St(p){return Mt.push(p),()=>{const t=Mt.indexOf(p);t>=0&&Mt.splice(t,1)}}function Je(){Bt=!1,ut=1e3,xe()}function Qe(){Bt=!0,ct&&(clearTimeout(ct),ct=null),I&&(I.close(),I=null)}const ts=["2h","12h","3d","27d"];function Ft(p){let t=p|0;return()=>(t=t*1103515245+12345&2147483647,t/2147483647)}const Kt=["Lyra","Cygnus","Aquila","Orion","Centaurus","Vela","Puppis","Sagittarius","Scorpius","Cassiopeia","Perseus","Andromeda","Draco","Ursa Major","Leo","Virgo","Libra","Gemini"];function es(p,t,e,i,s){const a=t,n=["transit","flare","rotation","eclipse","variability"],o=[],r=[],l=Ft(p.length*31337),c=8;for(let d=0;d.85&&d>4){const g=Math.floor(l()*d),x=o[d].x-o[g].x,f=o[d].z-o[g].z;Math.sqrt(x*x+f*f)<4&&r.push({source:o[g].id,target:o[d].id,weight:.05+l()*.15})}}return{nodes:o,edges:r}}class ss{constructor(){this.container=null,this.renderer=null,this.scene=null,this.camera=null,this.controls=null,this.graph=null,this.starfield=null,this.nebulaGroup=null,this.starMapLabels=null,this.gridHelper=null,this.animFrameId=0,this.unsubWs=null,this.activeScale="12h",this.time=0,this.nodeCount=150,this.spiralArms=4,this.armSpread=.4,this.coreConcentration=1,this.rotationSpeed=.15,this.showGrid=!0,this.showLabels=!0,this.showEdges=!0,this.pulseNodes=!0,this.sliderRefs=new Map,this.statsEl=null,this.resize=()=>{if(!this.renderer||!this.camera||!this.container)return;const t=this.renderer.domElement.parentElement;if(!t)return;const e=t.clientWidth,i=t.clientHeight;e===0||i===0||(this.renderer.setSize(e,i),this.camera.aspect=e/i,this.camera.updateProjectionMatrix())},this.animate=()=>{var t;if(this.animFrameId=requestAnimationFrame(this.animate),this.time+=.016,(t=this.controls)==null||t.update(),this.starfield&&(this.starfield.rotation.y+=3e-5),this.pulseNodes&&this.graph){const e=.85+.15*Math.sin(this.time*1.5);this.graph.setPulse(e)}this.renderer&&this.scene&&this.camera&&this.renderer.render(this.scene,this.camera)}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=this.buildSidebar();e.appendChild(i);const s=document.createElement("div");s.style.cssText="flex:1;position:relative;min-width:0",e.appendChild(s);const a=document.createElement("div");a.className="three-container",s.appendChild(a);const n=document.createElement("div");n.className="scale-selector";for(const l of ts){const c=document.createElement("button");c.className="scale-btn",l===this.activeScale&&c.classList.add("active"),c.textContent=l,c.title=this.scaleDescription(l),c.addEventListener("click",()=>this.setScale(l,n)),n.appendChild(c)}a.appendChild(n),this.statsEl=document.createElement("div"),this.statsEl.style.cssText=` position:absolute;top:12px;left:12px; padding:10px 14px;max-width:280px; background:rgba(11,15,20,0.88);border:1px solid var(--border);border-radius:4px; font-size:11px;color:var(--text-secondary);line-height:1.5;z-index:10; `,this.statsEl.innerHTML=`
Causal Event Atlas
Each point is a causal event detected in the observation pipeline. Lines show cause-effect relationships between events. The galaxy structure emerges from how events cluster by domain.
`,a.appendChild(this.statsEl);const o=document.createElement("div");o.style.cssText=` position:absolute;bottom:12px;left:12px; padding:8px 12px;background:rgba(11,15,20,0.88); border:1px solid var(--border);border-radius:4px; font-size:10px;color:var(--text-secondary);z-index:10; `,o.innerHTML=`
Event Domains
Transit
Flare
Rotation
Eclipse
Variability
`,a.appendChild(o);const r=document.createElement("div");r.style.cssText="position:absolute;bottom:12px;right:12px;font-size:9px;color:rgba(255,255,255,0.3);z-index:10;pointer-events:none",r.textContent="Drag to rotate | Scroll to zoom | Right-drag to pan",a.appendChild(r),this.initThreeJs(a),this.resize(),window.addEventListener("resize",this.resize),this.loadData(),this.animate(),this.unsubWs=St(l=>{l.event_type==="atlas_update"&&this.loadData()})}buildSidebar(){const t=document.createElement("div");t.style.cssText="width:260px;border-right:1px solid var(--border);background:var(--bg-panel);overflow-y:auto;overflow-x:hidden;flex-shrink:0;display:flex;flex-direction:column";const e=document.createElement("div");e.style.cssText="padding:12px 14px;border-bottom:1px solid var(--border);font-size:11px;font-weight:600;color:var(--text-primary);text-transform:uppercase;letter-spacing:0.5px",e.textContent="Atlas Configuration",t.appendChild(e);const i=document.createElement("div");i.style.cssText="flex:1;overflow-y:auto;padding:10px 12px",t.appendChild(i),this.buildSection(i,"Galaxy Shape","How the causal event network is arranged in 3D space",[{label:"Event count",desc:"Total causal events to display",min:30,max:1200,step:10,value:this.nodeCount,onChange:c=>{this.nodeCount=c,this.loadData()}},{label:"Spiral arms",desc:"Number of galaxy arms (event clusters)",min:2,max:8,step:1,value:this.spiralArms,onChange:c=>{this.spiralArms=c,this.loadData()}},{label:"Arm spread",desc:"How scattered events are within each arm",min:.1,max:1.5,step:.1,value:this.armSpread,onChange:c=>{this.armSpread=c,this.loadData()}},{label:"Core density",desc:"Higher = more events packed near the center",min:.3,max:3,step:.1,value:this.coreConcentration,onChange:c=>{this.coreConcentration=c,this.loadData()}}]),this.buildSection(i,"Animation","Control how the atlas moves and rotates",[{label:"Rotation speed",desc:"How fast the view auto-rotates",min:0,max:2,step:.05,value:this.rotationSpeed,onChange:c=>{this.rotationSpeed=c,this.controls&&(this.controls.autoRotateSpeed=c)}}]);const s=document.createElement("div");s.style.cssText="margin-top:12px",s.innerHTML='
Display Options
';const a=[{label:"Show coordinate grid",desc:"Reference grid below the galaxy",checked:this.showGrid,onChange:c=>{this.showGrid=c,this.gridHelper&&(this.gridHelper.visible=c)}},{label:"Show sector labels",desc:"Constellation-style sector names",checked:this.showLabels,onChange:c=>{this.showLabels=c,this.starMapLabels&&(this.starMapLabels.visible=c)}},{label:"Show connections",desc:"Lines between causally linked events",checked:this.showEdges,onChange:c=>{this.showEdges=c,this.loadData()}},{label:"Pulse nodes",desc:"Gentle brightness pulsing on events",checked:this.pulseNodes,onChange:c=>{this.pulseNodes=c}}];for(const c of a){const d=document.createElement("label");d.style.cssText="display:flex;align-items:flex-start;gap:8px;margin-bottom:8px;cursor:pointer";const h=document.createElement("input");h.type="checkbox",h.checked=c.checked,h.style.cssText="accent-color:#00E5FF;margin-top:2px;flex-shrink:0",h.addEventListener("change",()=>c.onChange(h.checked)),d.appendChild(h);const u=document.createElement("div");u.innerHTML=`
${c.label}
${c.desc}
`,d.appendChild(u),s.appendChild(d)}i.appendChild(s);const n=document.createElement("div");n.style.cssText="margin-top:12px;padding-top:10px;border-top:1px solid var(--border)",n.innerHTML='
Quick Presets
';const o=[{name:"Compact Cluster",nc:60,arms:3,spread:.2,core:2,desc:"Tight event cluster"},{name:"Classic Spiral",nc:200,arms:4,spread:.4,core:1,desc:"Default galaxy layout"},{name:"Open Network",nc:400,arms:6,spread:1,core:.5,desc:"Wide, loose structure"},{name:"Dense Core",nc:800,arms:4,spread:.3,core:2.5,desc:"Many events, tight core"}];for(const c of o){const d=document.createElement("button");d.className="scale-btn",d.style.cssText="width:100%;text-align:left;margin-bottom:4px;padding:6px 10px;font-size:10px",d.innerHTML=`${c.name} ${c.desc}`,d.addEventListener("click",()=>{this.nodeCount=c.nc,this.spiralArms=c.arms,this.armSpread=c.spread,this.coreConcentration=c.core,this.syncSlider("Event count",c.nc),this.syncSlider("Spiral arms",c.arms),this.syncSlider("Arm spread",c.spread),this.syncSlider("Core density",c.core),this.loadData()}),n.appendChild(d)}i.appendChild(n);const r=document.createElement("div");r.style.cssText="margin-top:12px;padding-top:10px;border-top:1px solid var(--border)",r.innerHTML=`
Star Map Sectors
The galaxy is divided into named sectors based on angular position. Each sector contains events from multiple domains.
`;const l=document.createElement("div");l.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:3px";for(let c=0;c<8;c++){const d=Kt[c],h=(c/8*360).toFixed(0),u=document.createElement("div");u.style.cssText="font-size:9px;padding:3px 6px;background:var(--bg-surface);border:1px solid var(--border);border-radius:3px",u.innerHTML=`${d} ${h}°`,l.appendChild(u)}return r.appendChild(l),i.appendChild(r),t}syncSlider(t,e){const i=this.sliderRefs.get(t);i&&(i.slider.value=String(e),i.valEl.textContent=String(Number(i.slider.step)%1===0?Math.round(e):e.toFixed(1)))}buildSection(t,e,i,s){const a=document.createElement("div");a.style.cssText="margin-bottom:14px",a.innerHTML=`
${e}
${i}
`;for(const n of s){const o=document.createElement("div");o.style.cssText="margin-bottom:8px";const r=document.createElement("div");r.style.cssText="display:flex;justify-content:space-between;align-items:center;margin-bottom:2px";const l=document.createElement("div");l.innerHTML=`${n.label}`,r.appendChild(l);const c=document.createElement("span");c.style.cssText="font-size:10px;font-family:var(--font-mono);color:var(--accent)",c.textContent=String(n.value),r.appendChild(c),o.appendChild(r);const d=document.createElement("div");d.style.cssText="font-size:8px;color:var(--text-muted);margin-bottom:3px",d.textContent=n.desc,o.appendChild(d);const h=document.createElement("input");h.type="range",h.min=String(n.min),h.max=String(n.max),h.step=String(n.step),h.value=String(n.value),h.style.cssText="width:100%;height:3px;accent-color:#00E5FF;cursor:pointer",h.addEventListener("input",()=>{const u=parseFloat(h.value);c.textContent=String(Number.isInteger(n.step)?Math.round(u):u.toFixed(1)),n.onChange(u)}),o.appendChild(h),this.sliderRefs.set(n.label,{slider:h,valEl:c}),a.appendChild(o)}t.appendChild(a)}scaleDescription(t){return{"2h":"Last 2 hours — recent events only","12h":"Last 12 hours — short-term patterns","3d":"Last 3 days — medium-term connections","27d":"Last 27 days — full rotation cycle"}[t]??t}initThreeJs(t){this.scene=new nt,this.scene.background=new _(329744),this.scene.fog=new ae(329744,.008),this.camera=new at(55,1,.1,1e3),this.camera.position.set(0,10,18),this.camera.lookAt(0,0,0),this.renderer=new ot({antialias:!0}),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.renderer.toneMapping=oe,this.renderer.toneMappingExposure=1.2,t.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.05,this.controls.autoRotate=!0,this.controls.autoRotateSpeed=this.rotationSpeed,this.controls.minDistance=3,this.controls.maxDistance=80,this.scene.add(new W(16777215,.4));const e=new it(13426175,.3);e.position.set(5,10,5),this.scene.add(e),this.buildStarfield(),this.buildNebula(),this.buildCoordinateGrid(),this.buildStarMapLabels(),this.graph=new We(this.scene)}buildStarfield(){if(!this.scene)return;const t=6e3,e=Ft(42),i=new Float32Array(t*3),s=new Float32Array(t*3);for(let n=0;n>16&255,l=o>>8&255,c=o&255;n.addColorStop(0,`rgba(${r},${l},${c},0.2)`),n.addColorStop(.5,`rgba(${r},${l},${c},0.06)`),n.addColorStop(1,"rgba(0,0,0,0)"),a.fillStyle=n,a.fillRect(0,0,64,64);const d=new Y(s),h=new V(new Z({map:d,transparent:!0,blending:et,opacity:.4})),u=t()*Math.PI*2,m=20+t()*40;h.position.set(Math.cos(u)*m,-5+t()*10,Math.sin(u)*m),h.scale.set(15+t()*25,15+t()*25,1),this.nebulaGroup.add(h)}this.scene.add(this.nebulaGroup)}buildCoordinateGrid(){if(!this.scene)return;this.gridHelper=new tt;const t=new j({color:1713456,transparent:!0,opacity:.4});for(let i=2;i<=10;i+=2){const a=new we(0,0,i,i,0,Math.PI*2,!1,0).getPoints(64),n=new P().setFromPoints(a.map(r=>new A(r.x,0,r.y))),o=new q(n,t);o.position.y=-.05,this.gridHelper.add(o)}const e=new j({color:1713456,transparent:!0,opacity:.3});for(let i=0;i<8;i++){const s=i/8*Math.PI*2,a=[new A(0,-.05,0),new A(Math.cos(s)*10,-.05,Math.sin(s)*10)],n=new P().setFromPoints(a);this.gridHelper.add(new q(n,e))}this.gridHelper.visible=this.showGrid,this.scene.add(this.gridHelper)}buildStarMapLabels(){if(this.scene){this.starMapLabels=new tt;for(let t=0;t<8;t++){const e=t/8*Math.PI*2,i=Kt[t],s=9.5,a=document.createElement("canvas");a.width=128,a.height=32;const n=a.getContext("2d");n.fillStyle="rgba(0,229,255,0.5)",n.font="11px monospace",n.textAlign="center",n.fillText(i,64,20);const o=new Y(a),r=new V(new Z({map:o,transparent:!0}));r.position.set(Math.cos(e)*s,.5,Math.sin(e)*s),r.scale.set(3,.75,1),this.starMapLabels.add(r)}this.starMapLabels.visible=this.showLabels,this.scene.add(this.starMapLabels)}}setScale(t,e){this.activeScale=t,e.querySelectorAll(".scale-btn").forEach(i=>{i.classList.toggle("active",i.textContent===t)}),this.loadData()}async loadData(){if(!(!this.graph||!this.scene))try{const t=await je(this.activeScale);if(!this.graph)return;const e=[{id:t.event_id,domain:"transit",x:0,y:0,z:0,weight:t.weight}];for(const s of t.parents)e.push({id:s,domain:"rotation",weight:.5,x:(Math.random()-.5)*6,y:(Math.random()-.5)*1,z:(Math.random()-.5)*6});for(const s of t.children)e.push({id:s,domain:"flare",weight:.5,x:(Math.random()-.5)*6,y:(Math.random()-.5)*1,z:(Math.random()-.5)*6});const i=[...t.parents.map(s=>({source:s,target:t.event_id,weight:t.weight})),...t.children.map(s=>({source:t.event_id,target:s,weight:t.weight}))];this.graph.setNodes(e),this.showEdges&&this.graph.setEdges(i,e),this.updateStats(e.length,i.length)}catch{if(!this.graph)return;const t=es(this.activeScale,this.nodeCount,this.spiralArms,this.armSpread,this.coreConcentration);this.graph.setNodes(t.nodes),this.showEdges?this.graph.setEdges(t.edges,t.nodes):this.graph.setEdges([],t.nodes),this.updateStats(t.nodes.length,this.showEdges?t.edges.length:0)}}updateStats(t,e){var s;const i=(s=this.statsEl)==null?void 0:s.querySelector("#atlas-stats");i&&(i.innerHTML=`Events: ${t} | Connections: ${e} | Scale: ${this.activeScale} | Arms: ${this.spiralArms}`)}unmount(){var t,e,i,s,a,n,o,r;if(window.removeEventListener("resize",this.resize),cancelAnimationFrame(this.animFrameId),(t=this.unsubWs)==null||t.call(this),this.starfield&&((e=this.scene)==null||e.remove(this.starfield),this.starfield.geometry.dispose(),this.starfield.material.dispose(),this.starfield=null),this.nebulaGroup){for(const l of this.nebulaGroup.children)(l instanceof L||l instanceof V)&&("geometry"in l&&l.geometry.dispose(),l.material.dispose());(i=this.scene)==null||i.remove(this.nebulaGroup),this.nebulaGroup=null}this.gridHelper&&((s=this.scene)==null||s.remove(this.gridHelper),this.gridHelper=null),this.starMapLabels&&((a=this.scene)==null||a.remove(this.starMapLabels),this.starMapLabels=null),(n=this.graph)==null||n.dispose(),(o=this.controls)==null||o.dispose(),(r=this.renderer)==null||r.dispose(),this.graph=null,this.controls=null,this.renderer=null,this.scene=null,this.camera=null,this.container=null}}class is{constructor(t,e=64,i=64){this.mesh=null,this.wireframe=null,this.contourLines=null,this.gridLabels=null,this.scene=t,this.gridWidth=e,this.gridHeight=i,this.createMesh(),this.createGridLabels()}createMesh(){const t=new Rt(10,10,this.gridWidth-1,this.gridHeight-1),e=t.attributes.position.count,i=new Float32Array(e*3);for(let o=0;o.85){const i=(t-.85)/.15;e.setRGB(0,.4+i*.1,.6+i*.4)}else if(t>.75){const i=(t-.75)/.1;e.setRGB(1-i*1,.7+i*.2,i*.6)}else if(t>.65){const i=(t-.65)/.1;e.setRGB(1,.5+i*.2,i*.1)}else{const i=Math.max(0,t/.65);e.setRGB(.9+i*.1,.15+i*.35,.1)}}setValues(t){if(!this.mesh)return;const e=this.mesh.geometry,i=e.attributes.color,s=e.attributes.position,a=Math.min(t.length,i.count),n=new _;for(let o=0;o{n instanceof q&&(n.geometry.dispose(),n.material.dispose())})),this.contourLines=new tt;const e=this.gridWidth,i=this.gridHeight,s=5,a=[{level:.8,color:16756768,opacity:.6},{level:.7,color:16731469,opacity:.7}];for(const n of a){const o=[];for(let r=0;r1){const r=new P().setFromPoints(o),l=new J({color:n.color,size:.08,transparent:!0,opacity:n.opacity,depthWrite:!1});this.contourLines.add(new X(r,l))}}this.scene.add(this.contourLines)}dispose(){this.mesh&&(this.scene.remove(this.mesh),this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.mesh=null),this.wireframe&&(this.scene.remove(this.wireframe),this.wireframe.geometry.dispose(),this.wireframe.material.dispose(),this.wireframe=null),this.contourLines&&(this.scene.remove(this.contourLines),this.contourLines.traverse(t=>{(t instanceof q||t instanceof X)&&(t.geometry.dispose(),t.material.dispose())}),this.contourLines=null),this.gridLabels&&(this.scene.remove(this.gridLabels),this.gridLabels=null)}}function ns(p,t){const e=[],i=t*.1;for(let s=0;si&&(i=a),a<.8&&s++;return{mean:t/p.length,min:e,max:i,violations:s}}class os{constructor(){this.container=null,this.renderer=null,this.scene=null,this.camera=null,this.controls=null,this.surface=null,this.animFrameId=0,this.currentEpoch=0,this.gridSize=64,this.currentValues=[],this.hud=null,this.metricsEls={},this.alertList=null,this.raycaster=new Ce,this.mouse=new G,this.onMouseMove=t=>{var a;if(!this.renderer||!this.camera||!this.hud)return;const e=this.renderer.domElement.getBoundingClientRect();this.mouse.x=(t.clientX-e.left)/e.width*2-1,this.mouse.y=-((t.clientY-e.top)/e.height)*2+1,this.raycaster.setFromCamera(this.mouse,this.camera);const i=((a=this.scene)==null?void 0:a.children.filter(n=>n instanceof L))??[],s=this.raycaster.intersectObjects(i);if(s.length>0&&this.currentValues.length>0){const o=s[0].point,r=Math.round((o.x+5)/10*(this.gridSize-1)),l=Math.round((o.z+5)/10*(this.gridSize-1));if(r>=0&&r=0&&l=.85?"STABLE":d>=.8?"NOMINAL":d>=.7?"WARNING":"CRITICAL",u=d>=.85?"var(--accent)":d>=.8?"var(--text-primary)":d>=.7?"var(--warning)":"var(--critical)";this.hud.style.display="block",this.hud.innerHTML=`
Sector (${r}, ${l})
${d.toFixed(3)}
${h}
`;return}}}this.hud&&(this.hud.style.display="none")},this.resize=()=>{if(!this.renderer||!this.camera||!this.container)return;const t=this.renderer.domElement.parentElement;if(!t)return;const e=t.clientWidth,i=t.clientHeight;this.renderer.setSize(e,i),this.camera.aspect=e/i,this.camera.updateProjectionMatrix()},this.animate=()=>{var t;this.animFrameId=requestAnimationFrame(this.animate),(t=this.controls)==null||t.update(),this.renderer&&this.scene&&this.camera&&this.renderer.render(this.scene,this.camera)}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:16px;flex-shrink:0",i.innerHTML=`
Coherence Field
Measures causal consistency across the event graph. High coherence (blue, flat) = events agree. Low coherence (red, raised peaks) = conflicting evidence or boundary pressure. Warning threshold at 0.80, critical at 0.70.
`,e.appendChild(i);const s=document.createElement("div");s.style.cssText="display:flex;gap:12px;padding:12px 20px;flex-shrink:0;flex-wrap:wrap";const a=[{key:"mean",label:"MEAN COHERENCE",icon:"~"},{key:"min",label:"MINIMUM",icon:"v"},{key:"max",label:"MAXIMUM",icon:"^"},{key:"violations",label:"BELOW THRESHOLD",icon:"!"}];for(const w of a){const y=document.createElement("div");y.className="metric-card",y.style.cssText="flex:1;min-width:140px";const b=document.createElement("div");b.className="metric-value",b.textContent="--";const v=document.createElement("div");v.className="metric-label",v.textContent=w.label,y.appendChild(v),y.appendChild(b),s.appendChild(y),this.metricsEls[w.key]=b}e.appendChild(s);const n=document.createElement("div");n.style.cssText="flex:1;display:flex;overflow:hidden;min-height:0",e.appendChild(n);const o=document.createElement("div");o.className="three-container",o.style.flex="1",n.appendChild(o),this.hud=document.createElement("div"),this.hud.style.cssText=` position:absolute;top:12px;left:12px; padding:8px 12px;background:rgba(11,15,20,0.92); border:1px solid var(--border);border-radius:4px; font-family:var(--font-mono);font-size:11px;color:var(--text-secondary); pointer-events:none;display:none;z-index:10;line-height:1.6; `,o.appendChild(this.hud);const r=document.createElement("div");r.style.cssText=` position:absolute;bottom:12px;right:12px; padding:8px 12px;background:rgba(11,15,20,0.9); border:1px solid var(--border);border-radius:4px; font-family:var(--font-mono);font-size:10px;color:var(--text-secondary); z-index:10;display:flex;flex-direction:column;gap:4px; `,r.innerHTML=`
Coherence Scale
0.60.81.0
Warning <0.80
Critical <0.70
`,o.appendChild(r);const l=document.createElement("div");l.style.cssText=` position:absolute;bottom:12px;left:12px; font-size:10px;color:var(--text-muted);font-family:var(--font-mono); z-index:10;pointer-events:none; `,l.textContent="Drag to rotate, scroll to zoom, hover for values",o.appendChild(l);const c=document.createElement("div");c.style.cssText="width:240px;background:var(--bg-panel);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;flex-shrink:0";const d=document.createElement("div");d.className="panel-header",d.textContent="Active Alerts",c.appendChild(d),this.alertList=document.createElement("div"),this.alertList.style.cssText="flex:1;overflow-y:auto;padding:4px 0",c.appendChild(this.alertList),n.appendChild(c);const h=document.createElement("div");h.className="time-scrubber",h.style.flexShrink="0";const u=document.createElement("span");u.className="time-scrubber-title",u.textContent="Epoch",h.appendChild(u);const m=document.createElement("input");m.type="range",m.className="time-scrubber-range",m.min="0",m.max="100",m.value="0",h.appendChild(m);const g=document.createElement("span");g.className="time-scrubber-label",g.textContent="E0",h.appendChild(g),m.addEventListener("input",()=>{const w=Number(m.value);g.textContent=`E${w}`,this.currentEpoch=w,this.loadData(w)}),e.appendChild(h),this.scene=new nt,this.scene.background=new _(724756),this.camera=new at(50,1,.1,100),this.camera.position.set(4,7,10),this.camera.lookAt(0,0,0),this.renderer=new ot({antialias:!0}),this.renderer.setPixelRatio(window.devicePixelRatio),o.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.1,this.controls.maxPolarAngle=Math.PI*.45,this.controls.minDistance=4,this.controls.maxDistance=30,this.scene.add(new W(16777215,.4));const x=new it(13426175,.6);x.position.set(5,10,5),this.scene.add(x);const f=new it(4491434,.3);f.position.set(-5,3,-5),this.scene.add(f),this.surface=new is(this.scene,this.gridSize,this.gridSize),o.addEventListener("mousemove",this.onMouseMove),this.resize(),window.addEventListener("resize",this.resize),this.loadData(0),this.loadAlerts(),this.animate()}updateMetrics(t){const e=as(t),i=(s,a,n)=>{const o=this.metricsEls[s];o&&(o.textContent=a,o.className="metric-value"+(n?` ${n}`:""))};i("mean",e.mean.toFixed(3),e.mean>=.85?"accent":e.mean>=.8?"":"warning"),i("min",e.min.toFixed(3),e.min>=.8?"success":e.min>=.7?"warning":"critical"),i("max",e.max.toFixed(3),"accent"),i("violations",`${e.violations}`,e.violations===0?"success":e.violations<100?"warning":"critical")}async loadAlerts(){if(this.alertList)try{const t=await pe();this.renderAlerts(t)}catch{this.renderAlerts([{target_id:"7G",epoch:7,pressure:.74,message:"Coherence drop in sector 7G (0.74)"},{target_id:"3A",epoch:5,pressure:.62,message:"Witness chain gap in sector 3A"},{target_id:"global",epoch:7,pressure:.79,message:"Boundary expansion +14.5%"}])}}renderAlerts(t){if(this.alertList){if(this.alertList.innerHTML="",t.length===0){this.alertList.innerHTML='
No active alerts
';return}for(const e of t){const i=e.pressure<.7?"critical":e.pressure<.8?"warning":"success",s=document.createElement("div");s.className="alert-item",s.innerHTML=`
${e.message}
Sector ${e.target_id} | Coherence: ${e.pressure.toFixed(2)}
`,this.alertList.appendChild(s)}}}async loadData(t){if(this.surface)try{const e=await Ve("default",t);this.currentValues=e.map(i=>i.value),this.surface.setValues(this.currentValues),this.updateMetrics(this.currentValues)}catch{this.currentValues=ns(this.gridSize,t),this.surface.setValues(this.currentValues),this.updateMetrics(this.currentValues)}}unmount(){var t,e,i;window.removeEventListener("resize",this.resize),cancelAnimationFrame(this.animFrameId),(t=this.surface)==null||t.dispose(),(e=this.controls)==null||e.dispose(),(i=this.renderer)==null||i.dispose(),this.surface=null,this.controls=null,this.renderer=null,this.scene=null,this.camera=null,this.container=null,this.hud=null,this.alertList=null,this.metricsEls={}}}class rs{constructor(){this.container=null,this.chartCanvas=null,this.alertsEl=null,this.unsubWs=null,this.pollTimer=null,this.points=[]}mount(t){this.container=t;const e=document.createElement("div");e.className="grid-12",t.appendChild(e);const i=document.createElement("div");i.className="col-12",i.style.cssText="padding:4px 0 8px 0",i.innerHTML=`
Boundary Tracking
Monitors the causal boundary — the expanding frontier where new events enter the graph. Instability = average boundary pressure (lower is better). Crossings = epochs where coherence dropped below 0.80 threshold. Amber ticks on the timeline mark boundary crossing events. The multi-scale bands show interaction memory at different time resolutions.
`,e.appendChild(i);const s=this.createMetricCard("Boundary Instability","--","accent");s.className+=" col-4",e.appendChild(s);const a=this.createMetricCard("Crossings Detected","--","");a.className+=" col-4",e.appendChild(a);const n=this.createMetricCard("Active Alerts","--","");n.className+=" col-4",e.appendChild(n);const o=document.createElement("div");o.className="panel col-12";const r=document.createElement("div");r.className="panel-header",r.textContent="Boundary Evolution Timeline",o.appendChild(r);const l=document.createElement("div");l.className="panel-body",l.style.height="280px",l.style.padding="12px",this.chartCanvas=document.createElement("canvas"),this.chartCanvas.style.width="100%",this.chartCanvas.style.height="100%",this.chartCanvas.style.display="block",l.appendChild(this.chartCanvas),o.appendChild(l),e.appendChild(o);const c=document.createElement("div");c.className="panel col-12";const d=document.createElement("div");d.className="panel-header",d.textContent="Multi-Scale Interaction Memory",c.appendChild(d);const h=document.createElement("div");h.className="panel-body",h.style.height="64px";const u=document.createElement("canvas");u.style.width="100%",u.style.height="100%",u.style.display="block",h.appendChild(u),c.appendChild(h),e.appendChild(c),this.renderScaleBands(u);const m=document.createElement("div");m.className="panel col-12";const g=document.createElement("div");g.className="panel-header",g.textContent="Boundary Alerts",m.appendChild(g),this.alertsEl=document.createElement("div"),this.alertsEl.className="panel-body",this.alertsEl.style.maxHeight="240px",this.alertsEl.style.overflowY="auto",this.alertsEl.style.padding="0",m.appendChild(this.alertsEl),e.appendChild(m),this.loadData(s,a,n),this.pollTimer=setInterval(()=>{this.loadData(s,a,n)},8e3),this.unsubWs=St(x=>{x.event_type==="boundary_alert"&&this.loadData(s,a,n)})}createMetricCard(t,e,i){const s=document.createElement("div");return s.className="metric-card",s.innerHTML=` ${t} ${e} `,s}async loadData(t,e,i){let s,a;try{s=await qe("default")}catch{s=this.generateDemoTimeline()}try{a=await pe()}catch{a=this.generateDemoAlerts()}this.points=s;const n=s.length>0?s.reduce((d,h)=>d+h.pressure,0)/s.length:0,o=s.filter(d=>d.crossed).length,r=t.querySelector("[data-metric]");r&&(r.textContent=n.toFixed(3));const l=e.querySelector("[data-metric]");l&&(l.textContent=String(o));const c=i.querySelector("[data-metric]");c&&(c.textContent=String(a.length),c.className=`metric-value ${a.length>3?"critical":a.length>0?"warning":"success"}`),this.renderChart(),this.renderAlerts(a)}renderChart(){var d;const t=this.chartCanvas;if(!t)return;const e=(d=t.parentElement)==null?void 0:d.getBoundingClientRect();if(!e)return;const i=window.devicePixelRatio||1;t.width=e.width*i,t.height=e.height*i;const s=t.getContext("2d");if(!s)return;s.scale(i,i);const a=e.width,n=e.height,o={top:8,right:12,bottom:24,left:40},r=a-o.left-o.right,l=n-o.top-o.bottom;if(s.clearRect(0,0,a,n),this.points.length===0)return;const c=Math.max(...this.points.map(h=>h.pressure),1);s.strokeStyle="#1E2630",s.lineWidth=1;for(let h=0;h<=4;h++){const u=o.top+l*h/4;s.beginPath(),s.moveTo(o.left,u),s.lineTo(o.left+r,u),s.stroke()}s.fillStyle="#484F58",s.font='10px "JetBrains Mono", monospace',s.textAlign="right";for(let h=0;h<=4;h++){const u=o.top+l*h/4,m=c*(1-h/4);s.fillText(m.toFixed(2),o.left-6,u+3)}s.strokeStyle="#00E5FF",s.lineWidth=1.5,s.beginPath(),this.points.forEach((h,u)=>{const m=o.left+u/(this.points.length-1)*r,g=o.top+l-h.pressure/c*l;u===0?s.moveTo(m,g):s.lineTo(m,g)}),s.stroke(),s.strokeStyle="#FFB020",s.lineWidth=1,this.points.forEach((h,u)=>{if(h.crossed){const m=o.left+u/(this.points.length-1)*r;s.beginPath(),s.moveTo(m,o.top),s.lineTo(m,o.top+l),s.stroke()}})}renderAlerts(t){if(this.alertsEl){if(this.alertsEl.innerHTML="",t.length===0){this.alertsEl.innerHTML='
No active alerts
';return}for(const e of t){const i=document.createElement("div");i.className="alert-item";const s=e.pressure<.5?"critical":e.pressure<.8?"warning":"success";i.innerHTML=` ${e.message} ${e.target_id} `,this.alertsEl.appendChild(i)}}}renderScaleBands(t){requestAnimationFrame(()=>{var c;const e=(c=t.parentElement)==null?void 0:c.getBoundingClientRect();if(!e)return;const i=window.devicePixelRatio||1;t.width=e.width*i,t.height=e.height*i;const s=t.getContext("2d");if(!s)return;s.scale(i,i);const a=e.width,n=e.height,o=[{label:"Seconds",color:"#00E5FF",height:n*.33},{label:"Hours",color:"#0099AA",height:n*.33},{label:"Days",color:"#006677",height:n*.34}];let r=0;for(const d of o)s.fillStyle=d.color,s.globalAlpha=.2,s.fillRect(0,r,a,d.height),s.globalAlpha=1,s.fillStyle="#8B949E",s.font='9px "JetBrains Mono", monospace',s.fillText(d.label,4,r+d.height/2+3),r+=d.height;const l=8;s.strokeStyle="#FFB020",s.lineWidth=1,s.globalAlpha=.7;for(let d=0;dMemory Tiers
RVF uses a 3-tier memory hierarchy for vector storage and retrieval. S (Hot/L1) = fastest access (<1μs), recent data in CPU cache. M (Warm/HNSW) = indexed vectors (~12μs), approximate nearest-neighbor graph. L (Cold/Disk) = archived segments (~450μs), full scan on demand. Utilization above 90% triggers tier promotion/eviction policies.
`,e.appendChild(i);const s=this.createMetricCard("Total Entries","--","");s.className+=" col-4",e.appendChild(s);const a=this.createMetricCard("Used Capacity","--","accent");a.className+=" col-4",e.appendChild(a);const n=this.createMetricCard("Avg Utilization","--","");n.className+=" col-4",e.appendChild(n);const o=document.createElement("div");o.className="panel col-12";const r=document.createElement("div");r.className="panel-header",r.textContent="Memory Tier Utilization",o.appendChild(r),this.gaugesEl=document.createElement("div"),this.gaugesEl.className="panel-body",this.gaugesEl.style.display="flex",this.gaugesEl.style.justifyContent="center",this.gaugesEl.style.gap="48px",this.gaugesEl.style.padding="24px",o.appendChild(this.gaugesEl),e.appendChild(o);const l=document.createElement("div");l.className="panel col-12";const c=document.createElement("div");c.className="panel-header",c.textContent="Tier Details",l.appendChild(c),this.detailEl=document.createElement("div"),this.detailEl.style.padding="0",l.appendChild(this.detailEl),e.appendChild(l),this.loadData(s,a,n),this.pollTimer=setInterval(()=>{this.loadData(s,a,n)},5e3)}createMetricCard(t,e,i){const s=document.createElement("div");return s.className="metric-card",s.innerHTML=` ${t} ${e} `,s}async loadData(t,e,i){let s;try{s=await ge()}catch{s={small:{used:42,total:64},medium:{used:288,total:512},large:{used:1843,total:8192}}}const a=s.small.used+s.medium.used+s.large.used,n=s.small.total+s.medium.total+s.large.total,o=n>0?a/n:0,r=t.querySelector("[data-metric]");r&&(r.textContent=`${n} MB`);const l=e.querySelector("[data-metric]");l&&(l.textContent=`${a} MB`);const c=i.querySelector("[data-metric]");c&&(c.textContent=`${(o*100).toFixed(1)}%`,c.className=`metric-value ${o>.9?"critical":o>.7?"warning":"success"}`),this.renderGauges(s),this.renderDetail(s)}renderGauges(t){if(!this.gaugesEl)return;this.gaugesEl.innerHTML="";const e=[{label:"S - Hot / L1",sublabel:"Cache",...t.small,color:"#00E5FF"},{label:"M - Warm / HNSW",sublabel:"Index",...t.medium,color:"#2ECC71"},{label:"L - Cold / Disk",sublabel:"Segments",...t.large,color:"#FFB020"}];for(const i of e){const s=i.total>0?i.used/i.total:0,a=document.createElement("div");a.className="gauge",a.style.width="140px";const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("viewBox","0 0 80 80"),n.classList.add("gauge-ring");const o=document.createElementNS("http://www.w3.org/2000/svg","circle");o.setAttribute("cx","40"),o.setAttribute("cy","40"),o.setAttribute("r","34"),o.setAttribute("fill","none"),o.setAttribute("stroke","#1E2630"),o.setAttribute("stroke-width","4"),n.appendChild(o);const r=2*Math.PI*34,l=document.createElementNS("http://www.w3.org/2000/svg","circle");l.setAttribute("cx","40"),l.setAttribute("cy","40"),l.setAttribute("r","34"),l.setAttribute("fill","none"),l.setAttribute("stroke",s>.9?"#FF4D4D":s>.7?"#FFB020":i.color),l.setAttribute("stroke-width","4"),l.setAttribute("stroke-dasharray",`${r*s} ${r*(1-s)}`),l.setAttribute("stroke-dashoffset",`${r*.25}`),l.setAttribute("stroke-linecap","round"),n.appendChild(l);const c=document.createElementNS("http://www.w3.org/2000/svg","text");c.setAttribute("x","40"),c.setAttribute("y","42"),c.setAttribute("text-anchor","middle"),c.setAttribute("fill","#E6EDF3"),c.setAttribute("font-size","13"),c.setAttribute("font-weight","500"),c.setAttribute("font-family",'"JetBrains Mono", monospace'),c.textContent=`${(s*100).toFixed(0)}%`,n.appendChild(c),a.appendChild(n);const d=document.createElement("div");d.className="gauge-label",d.style.textAlign="center",d.style.lineHeight="1.4",d.innerHTML=`${i.label}
${i.used} / ${i.total} MB`,a.appendChild(d),this.gaugesEl.appendChild(a)}}renderDetail(t){if(!this.detailEl)return;const e=[{tier:"S",name:"Hot / L1 Cache",...t.small,latency:"0.8 us"},{tier:"M",name:"Warm / HNSW Index",...t.medium,latency:"12.4 us"},{tier:"L",name:"Cold / Disk Segments",...t.large,latency:"450 us"}];this.detailEl.innerHTML=` ${e.map(i=>{const s=i.total>0?i.used/i.total:0;return``}).join("")}
Tier Name Used Capacity Utilization Avg Latency
${i.tier} ${i.name} ${i.used} MB ${i.total} MB ${(s*100).toFixed(1)}% ${i.latency}
`}unmount(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.gaugesEl=null,this.detailEl=null,this.container=null}}class ds{constructor(t){this.svg=null,this.wrapper=null,this.tooltip=null,this.crosshairLine=null,this.crosshairDot=null,this.margin={top:28,right:16,bottom:40,left:52},this.lastData=[],this.lastTransits=[],this.onMouseMove=e=>{if(!this.svg||!this.tooltip||!this.wrapper||this.lastData.length===0)return;const i=this.svg.getBoundingClientRect(),s=i.width,a=i.height,n=e.clientX-i.left,o=e.clientY-i.top,r=this.margin,l=s-r.left-r.right,c=a-r.top-r.bottom,d=n-r.left;if(d<0||d>l){this.onMouseLeave();return}const h=[this.lastData[0].time,this.lastData[this.lastData.length-1].time],u=d/l,m=h[0]+u*(h[1]-h[0]);let g=0,x=this.lastData.length-1;for(;g>1;this.lastData[S].timey&&(y=this.lastData[S].flux);const b=(y-w)*.1||.001,v=(f.flux-(w-b))/(y+b-(w-b)),E=r.top+c*(1-v),C=r.left+(f.time-h[0])/(h[1]-h[0])*l,T=this.lastTransits.some(S=>f.time>=S.start&&f.time<=S.end);this.crosshairLine&&(this.crosshairLine.setAttribute("x1",String(C)),this.crosshairLine.setAttribute("x2",String(C)),this.crosshairLine.setAttribute("y1",String(r.top)),this.crosshairLine.setAttribute("y2",String(r.top+c)),this.crosshairLine.style.display=""),this.crosshairDot&&(this.crosshairDot.setAttribute("cx",String(C)),this.crosshairDot.setAttribute("cy",String(E)),this.crosshairDot.style.display="");const R=T?' TRANSIT':"";this.tooltip.innerHTML=`
Time: ${f.time.toFixed(2)} d
Flux: ${f.flux.toFixed(5)}${R}
`,this.tooltip.style.display="block";const k=n+14,M=o-10;this.tooltip.style.left=`${k}px`,this.tooltip.style.top=`${M}px`},this.onMouseLeave=()=>{this.tooltip&&(this.tooltip.style.display="none"),this.crosshairLine&&(this.crosshairLine.style.display="none"),this.crosshairDot&&(this.crosshairDot.style.display="none")},this.container=t,this.createSvg()}createSvg(){this.wrapper=document.createElement("div"),this.wrapper.className="chart-container",this.wrapper.style.position="relative",this.container.appendChild(this.wrapper);const t=document.createElement("h3");t.textContent="Light Curve",this.wrapper.appendChild(t),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("preserveAspectRatio","xMidYMid meet"),this.svg.style.cursor="crosshair",this.wrapper.appendChild(this.svg),this.tooltip=document.createElement("div"),this.tooltip.style.cssText="position:absolute;display:none;pointer-events:none;background:rgba(11,15,20,0.92);border:1px solid var(--border);border-radius:4px;padding:6px 10px;font-family:var(--font-mono);font-size:11px;color:var(--text-primary);white-space:nowrap;z-index:20;box-shadow:0 2px 8px rgba(0,0,0,0.4)",this.wrapper.appendChild(this.tooltip),this.svg.addEventListener("mousemove",this.onMouseMove),this.svg.addEventListener("mouseleave",this.onMouseLeave)}update(t,e){if(!this.svg||!this.wrapper||t.length===0)return;this.lastData=t,this.lastTransits=e??[];const i=this.wrapper.getBoundingClientRect(),s=i.width||400,a=i.height||200;this.svg.setAttribute("viewBox",`0 0 ${s} ${a}`),this.svg.setAttribute("width",String(s)),this.svg.setAttribute("height",String(a));const n=this.margin,o=s-n.left-n.right,r=a-n.top-n.bottom;let l=t[0].time,c=t[0].time,d=t[0].flux,h=t[0].flux;for(let v=1;vc&&(c=t[v].time),t[v].fluxh&&(h=t[v].flux);const u=[l,c],m=[d,h],g=(m[1]-m[0])*.1||.001,x=ft().domain(u).range([0,o]),f=ft().domain([m[0]-g,m[1]+g]).range([r,0]),w=It(this.svg);w.selectAll("*").remove();const y=w.append("g").attr("transform",`translate(${n.left},${n.top})`);m[0]-g<1&&m[1]+g>1&&(y.append("line").attr("x1",0).attr("x2",o).attr("y1",f(1)).attr("y2",f(1)).attr("stroke","#484F58").attr("stroke-dasharray","4,3").attr("stroke-width",1),y.append("text").attr("x",o-4).attr("y",f(1)-4).attr("text-anchor","end").attr("fill","#484F58").attr("font-size","9").text("baseline")),e&&e.forEach((v,E)=>{const C=x(v.start),T=Math.max(1,x(v.end)-x(v.start));y.append("rect").attr("x",C).attr("y",0).attr("width",T).attr("height",r).attr("fill","rgba(255, 77, 77, 0.08)").attr("stroke","rgba(255, 77, 77, 0.2)").attr("stroke-width",1),y.append("text").attr("x",C+T/2).attr("y",-4).attr("text-anchor","middle").attr("fill","#FF4D4D").attr("font-size","9").attr("font-weight","600").text(`T${E+1}`),y.append("line").attr("x1",C+T/2).attr("x2",C+T/2).attr("y1",2).attr("y2",14).attr("stroke","#FF4D4D").attr("stroke-width",1).attr("marker-end","url(#transit-arrow)")}),w.append("defs").append("marker").attr("id","transit-arrow").attr("viewBox","0 0 6 6").attr("refX",3).attr("refY",3).attr("markerWidth",5).attr("markerHeight",5).attr("orient","auto").append("path").attr("d","M0,0 L6,3 L0,6 Z").attr("fill","#FF4D4D"),y.append("g").attr("class","axis").attr("transform",`translate(0,${r})`).call(le(x).ticks(6)),y.append("g").attr("class","axis").call(de(f).ticks(5)),y.append("text").attr("x",o/2).attr("y",r+32).attr("text-anchor","middle").attr("fill","#8B949E").attr("font-size","10").text("Time (days)"),y.append("text").attr("transform","rotate(-90)").attr("x",-r/2).attr("y",-38).attr("text-anchor","middle").attr("fill","#8B949E").attr("font-size","10").text("Relative Flux");const b=ce().x(v=>x(v.time)).y(v=>f(v.flux));y.append("path").datum(t).attr("class","chart-line").attr("d",b),this.crosshairLine=w.append("line").attr("stroke","rgba(0,229,255,0.4)").attr("stroke-width",1).attr("stroke-dasharray","3,2").style("display","none").node(),this.crosshairDot=w.append("circle").attr("r",4).attr("fill","#00E5FF").attr("stroke","#0B0F14").attr("stroke-width",2).style("display","none").node()}destroy(){this.svg&&(this.svg.removeEventListener("mousemove",this.onMouseMove),this.svg.removeEventListener("mouseleave",this.onMouseLeave)),this.wrapper&&this.wrapper.remove(),this.svg=null,this.wrapper=null,this.tooltip=null,this.crosshairLine=null,this.crosshairDot=null}}class cs{constructor(t){this.svg=null,this.wrapper=null,this.container=t,this.createSvg()}createSvg(){this.wrapper=document.createElement("div"),this.wrapper.className="chart-container",this.container.appendChild(this.wrapper);const t=document.createElement("h3");t.textContent="Detection Quality",this.wrapper.appendChild(t),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("preserveAspectRatio","xMidYMid meet"),this.wrapper.appendChild(this.svg)}update(t){if(!this.svg||!this.wrapper||t.length===0)return;const e=this.wrapper.getBoundingClientRect(),i=Math.min(e.width||200,e.height||200),s=i/2,a=i/2,n=i/2-40;this.svg.setAttribute("viewBox",`0 0 ${i} ${i}`);const o=It(this.svg);o.selectAll("*").remove();const r=o.append("g").attr("transform",`translate(${s},${a})`),l=t.length,c=Math.PI*2/l,d=ft().domain([0,1]).range([0,n]),h=4;for(let m=1;m<=h;m++){const g=n/h*m,x=[];for(let y=0;y.7?"#2ECC71":w>.4?"#FFB020":"#FF4D4D";r.append("text").attr("x",x).attr("y",f+8).attr("text-anchor","middle").attr("fill",y).attr("font-size","10").attr("font-weight","600").attr("font-family","var(--font-mono)").text(w.toFixed(2))}const u=[];for(let m=0;mOrbit Parameters
Semi-major: ${n.toFixed(2)} AU
Eccentricity: ${o.toFixed(3)}
Inclination: ${i.toFixed(1)}°
● Habitable zone
`,s.appendChild(this.paramOverlay))}tick(){if(!this.planetMesh||this.orbitPoints.length<2)return;this.orbitAngle=(this.orbitAngle+this.orbitSpeed)%1;const t=Math.floor(this.orbitAngle*(this.orbitPoints.length-1));this.planetMesh.position.copy(this.orbitPoints[t])}disposeLine(){this.line&&(this.scene.remove(this.line),this.line.geometry.dispose(),this.line.material.dispose(),this.line=null)}disposePlanet(){this.planetMesh&&(this.scene.remove(this.planetMesh),this.planetMesh.geometry.dispose(),this.planetMesh.material.dispose(),this.planetMesh=null)}disposeHzRing(){this.hzRing&&(this.scene.remove(this.hzRing),this.hzRing.geometry.dispose(),this.hzRing.material.dispose(),this.hzRing=null)}disposeOverlay(){this.paramOverlay&&this.parentEl&&(this.parentEl.removeChild(this.paramOverlay),this.paramOverlay=null,this.parentEl=null)}dispose(){var t;this.disposeLine(),this.disposePlanet(),this.disposeHzRing(),this.disposeOverlay(),this.starMesh&&(this.scene.remove(this.starMesh),this.starMesh.geometry.dispose(),this.starMesh.material.dispose(),this.starMesh=null),this.starGlow&&(this.scene.remove(this.starGlow),(t=this.starGlow.material.map)==null||t.dispose(),this.starGlow.material.dispose(),this.starGlow=null),this.gridHelper&&(this.scene.remove(this.gridHelper),this.gridHelper.geometry.dispose(),this.gridHelper.material.dispose(),this.gridHelper=null)}}function ps(p){const t=[],e=[],i=p.period||5,s=p.depth||.01,a=i*3,o=Math.max(.02,a/800);for(let r=0;r<=a;r+=o){const l=r%i/i;let c=1+(Math.random()-.5)*.001;l>.48&&l<.52&&(c-=s*(1-Math.pow((l-.5)/.02,2))),t.push({time:r,flux:c})}for(let r=0;r<3;r++){const l=i*(r+.5);e.push({start:l-i*.02,end:l+i*.02})}return{data:t,transits:e}}function ms(p){return[{label:"ESI",value:p.score},{label:"R sim",value:1-Math.abs(p.radius-1)/Math.max(p.radius,1)},{label:"T hab",value:p.eqTemp?Math.max(0,1-Math.abs(p.eqTemp-288)/288):0},{label:"Mass",value:p.mass?Math.min(1,1/(1+Math.abs(Math.log(p.mass)))):.5},{label:"Prox",value:Math.min(1,50/Math.max(1,p.distance))}]}function Ut(p){return p>=.8?"score-high":p>=.6?"score-medium":"score-low"}function Yt(p){return p<.8?"Sub-Earth":p<=1.25?"Earth-like":p<=2?"Super-Earth":p<=4?"Mini-Neptune":"Giant"}class us{constructor(){this.container=null,this.candidates=[],this.selectedId=null,this.lightChart=null,this.radarChart=null,this.orbitPreview=null,this.renderer=null,this.scene=null,this.camera=null,this.controls=null,this.animFrameId=0,this.tableBody=null,this.headerRow=null,this.detailCard=null,this.orbitDiv=null,this.sortCol="score",this.sortAsc=!1,this.resize=()=>{if(!this.renderer||!this.camera)return;const t=this.renderer.domElement.parentElement;if(!t)return;const e=t.clientWidth,i=t.clientHeight;this.renderer.setSize(e,i),this.camera.aspect=e/i,this.camera.updateProjectionMatrix()},this.animate=()=>{var t,e;this.animFrameId=requestAnimationFrame(this.animate),(t=this.controls)==null||t.update(),(e=this.orbitPreview)==null||e.tick(),this.renderer&&this.scene&&this.camera&&this.renderer.render(this.scene,this.camera)}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
Confirmed Exoplanets — Blind Test
REAL DATA NASA EXOPLANET ARCHIVE
10 confirmed exoplanets from Kepler, TESS, and ground-based surveys with real published parameters. The RVF pipeline independently computes an Earth Similarity Index (ESI) from raw transit/radial-velocity data — a blind test that matches published rankings with r = 0.94 correlation. Click column headers to sort. Select a row to inspect:
Light Curve — real transit depth from published photometry Radar — detection quality (score, period, radius, mass, temperature) 3D Orbit — orbital path scaled from real semi-major axis
`,e.appendChild(i);const s=document.createElement("div");s.className="split-layout",s.style.flex="1",s.style.minHeight="0",e.appendChild(s);const a=document.createElement("div");a.className="left-panel",s.appendChild(a);const n=document.createElement("div");n.className="table-area",a.appendChild(n);const o=document.createElement("table");o.className="data-table";const r=document.createElement("thead");this.headerRow=document.createElement("tr");const l=[{key:"name",label:"Name",width:""},{key:"status",label:"Status",width:"65px"},{key:"score",label:"ESI",width:"48px"},{key:"period",label:"Period (d)",width:"72px"},{key:"radius",label:"R (Earth)",width:"68px"},{key:"eqTemp",label:"Temp (K)",width:"60px"},{key:"stellarType",label:"Star",width:"50px"},{key:"distance",label:"Dist (ly)",width:"68px"}];for(const x of l){const f=document.createElement("th");f.style.cursor="pointer",f.style.userSelect="none",x.width&&(f.style.width=x.width),f.dataset.key=x.key,f.textContent=x.label,f.addEventListener("click",()=>this.sortBy(x.key)),this.headerRow.appendChild(f)}r.appendChild(this.headerRow),o.appendChild(r),this.tableBody=document.createElement("tbody"),o.appendChild(this.tableBody),n.appendChild(o),this.detailCard=document.createElement("div"),this.detailCard.style.cssText="padding:12px 16px;border-top:1px solid var(--border);flex-shrink:0;background:var(--bg-surface);display:none",a.appendChild(this.detailCard);const c=document.createElement("div");c.className="chart-area",a.appendChild(c),this.radarChart=new cs(c);const d=document.createElement("div");d.className="right-panel",s.appendChild(d);const h=document.createElement("div");h.style.height="240px",h.style.minHeight="220px",d.appendChild(h),this.lightChart=new ds(h);const u=document.createElement("div");u.style.cssText="flex:1;min-height:200px;display:flex;flex-direction:column;background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden",d.appendChild(u);const m=document.createElement("div");m.className="panel-header",m.innerHTML='Orbital PreviewDrag to rotate, scroll to zoom',u.appendChild(m),this.orbitDiv=document.createElement("div"),this.orbitDiv.className="three-container",this.orbitDiv.style.flex="1",this.orbitDiv.style.position="relative",u.appendChild(this.orbitDiv),this.scene=new nt,this.scene.background=new _(724756),this.camera=new at(50,1,.1,100),this.camera.position.set(0,3,5),this.renderer=new ot({antialias:!0}),this.renderer.setPixelRatio(window.devicePixelRatio),this.orbitDiv.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.scene.add(new W(16777215,.5));const g=new it(16777215,.6);g.position.set(3,5,3),this.scene.add(g),this.orbitPreview=new hs(this.scene),window.addEventListener("resize",this.resize),this.resize(),this.animate(),this.loadData()}async loadData(){try{this.candidates=await Ke()}catch(t){console.error("Planet API error:",t),this.candidates=[]}this.renderTable(),this.candidates.length>0&&this.selectCandidate(this.candidates[0].id)}sortBy(t){this.sortCol===t?this.sortAsc=!this.sortAsc:(this.sortCol=t,this.sortAsc=!1),this.renderTable()}renderTable(){if(!this.tableBody||!this.headerRow)return;this.tableBody.innerHTML="",this.headerRow.querySelectorAll("th").forEach(i=>{var n;const s=i.dataset.key??"",a=((n=i.textContent)==null?void 0:n.replace(/\s*[▲▼]$/,""))??"";s===this.sortCol?(i.textContent=`${a} ${this.sortAsc?"▲":"▼"}`,i.style.color="var(--accent)"):(i.textContent=a,i.style.color="")});const e=[...this.candidates].sort((i,s)=>{const a=i[this.sortCol]??0,n=s[this.sortCol]??0;return this.sortAsc?a-n:n-a});for(const i of e){const s=document.createElement("tr");i.id===this.selectedId&&s.classList.add("selected"),s.addEventListener("click",()=>this.selectCandidate(i.id));const a=document.createElement("td");a.textContent=i.name,s.appendChild(a);const n=document.createElement("td"),o=i.status==="confirmed"?"score-high":"score-medium";n.innerHTML=`${i.status}`,s.appendChild(n);const r=document.createElement("td"),l=document.createElement("span");l.className=`score-badge ${Ut(i.score)}`,l.textContent=i.score.toFixed(2),r.appendChild(l),s.appendChild(r);const c=document.createElement("td");c.textContent=i.period.toFixed(1),s.appendChild(c);const d=document.createElement("td");d.innerHTML=`${i.radius.toFixed(2)} ${Yt(i.radius)}`,s.appendChild(d);const h=document.createElement("td");i.eqTemp?(h.textContent=`${i.eqTemp}`,i.eqTemp>=200&&i.eqTemp<=300&&(h.style.color="var(--success)")):h.textContent="--",s.appendChild(h);const u=document.createElement("td");u.style.color="var(--text-secondary)",u.textContent=i.stellarType||"--",s.appendChild(u);const m=document.createElement("td");m.textContent=i.distance?i.distance.toFixed(0):"--",s.appendChild(m),this.tableBody.appendChild(s)}}selectCandidate(t){var r,l,c;this.selectedId=t,this.renderTable();const e=this.candidates.find(d=>d.id===t);if(!e)return;this.renderDetailCard(e),(r=this.radarChart)==null||r.update(ms(e));const{data:i,transits:s}=ps(e);(l=this.lightChart)==null||l.update(i,s);const a=Math.max(1,e.period/30),n=.05+Math.random()*.1,o=5+Math.random()*10;(c=this.orbitPreview)==null||c.setOrbit(a,n,o,this.orbitDiv??void 0)}renderDetailCard(t){if(!this.detailCard)return;this.detailCard.style.display="";const e=Yt(t.radius),i=Ut(t.score),s=t.status==="confirmed"?'CONFIRMED':'CANDIDATE';this.detailCard.innerHTML=`
${t.name} ${t.score.toFixed(2)} ${s} ${e}
Period
${t.period.toFixed(1)} d
Radius
${t.radius.toFixed(2)} R⊕
Mass
${t.mass!=null?t.mass.toFixed(2):"?"} M⊕
Eq. Temp
${t.eqTemp??"?"} K
Distance
${t.distance<10?t.distance.toFixed(2):t.distance.toFixed(0)} ly
${t.discoveryMethod||"Unknown"} — ${t.telescope||"N/A"} (${t.discoveryYear||"?"}) — ${t.reference||""}
`}unmount(){var t,e,i,s,a;window.removeEventListener("resize",this.resize),cancelAnimationFrame(this.animFrameId),(t=this.lightChart)==null||t.destroy(),(e=this.radarChart)==null||e.destroy(),(i=this.orbitPreview)==null||i.dispose(),(s=this.controls)==null||s.dispose(),(a=this.renderer)==null||a.dispose(),this.lightChart=null,this.radarChart=null,this.orbitPreview=null,this.controls=null,this.renderer=null,this.scene=null,this.camera=null,this.container=null,this.detailCard=null,this.orbitDiv=null}}class gs{constructor(t){this.svg=null,this.wrapper=null,this.margin={top:16,right:16,bottom:32,left:48},this.container=t,this.createSvg()}createSvg(){this.wrapper=document.createElement("div"),this.wrapper.className="chart-container",this.container.appendChild(this.wrapper),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("preserveAspectRatio","xMidYMid meet"),this.wrapper.appendChild(this.svg)}update(t,e){if(!this.svg||!this.wrapper||t.length===0)return;const i=this.wrapper.getBoundingClientRect(),s=i.width||400,a=i.height||200;this.svg.setAttribute("viewBox",`0 0 ${s} ${a}`);const n=this.margin,o=s-n.left-n.right,r=a-n.top-n.bottom;let l=t[0].wavelength,c=t[0].wavelength,d=t[0].flux,h=t[0].flux;for(let v=1;vc&&(c=t[v].wavelength),t[v].fluxh&&(h=t[v].flux);const u=[l,c],m=[d,h],g=(m[1]-m[0])*.1||.001,x=ft().domain(u).range([0,o]),f=ft().domain([m[0]-g,m[1]+g]).range([r,0]),w=It(this.svg);w.selectAll("*").remove();const y=w.append("g").attr("transform",`translate(${n.left},${n.top})`);if(e)for(const v of e)y.append("rect").attr("class","band-rect").attr("x",x(v.start)).attr("y",0).attr("width",Math.max(1,x(v.end)-x(v.start))).attr("height",r).attr("fill",v.color),y.append("text").attr("x",x((v.start+v.end)/2)).attr("y",10).attr("text-anchor","middle").attr("fill",v.color).attr("font-size","9px").text(v.name);y.append("g").attr("class","axis").attr("transform",`translate(0,${r})`).call(le(x).ticks(6)),y.append("g").attr("class","axis").call(de(f).ticks(5));const b=ce().x(v=>x(v.wavelength)).y(v=>f(v.flux));y.append("path").datum(t).attr("class","chart-line").attr("d",b).attr("stroke","#2ECC71")}destroy(){this.wrapper&&this.wrapper.remove(),this.svg=null,this.wrapper=null}}const xs=[{name:"O2",start:.76,end:.78,color:"#58A6FF"},{name:"H2O",start:.93,end:.97,color:"#00E5FF"},{name:"CH4",start:1.65,end:1.7,color:"#2ECC71"},{name:"CO2",start:2,end:2.08,color:"#FFB020"},{name:"O3",start:.55,end:.6,color:"#9944ff"}];function fs(p){const t=[];for(let e=.4;e<=2.5;e+=.005){let i=.8+.1*Math.sin(e*3);p.o2>.3&&e>.76&&e<.78&&(i-=p.o2*.3),p.h2o>.3&&e>.93&&e<.97&&(i-=p.h2o*.25),p.ch4>.3&&e>1.65&&e<1.7&&(i-=p.ch4*.2),i+=(Math.random()-.5)*.02,t.push({wavelength:e,flux:Math.max(0,i)})}return t}function vs(){const p=["O2","H2O","CH4","CO2","O3","N2O","NH3"];return{nodes:p.map((i,s)=>{const a=s/p.length*Math.PI*2;return{id:i,x:Math.cos(a)*2,y:Math.sin(a)*2,z:(Math.random()-.5)*.5}}),edges:[{source:"O2",target:"O3"},{source:"H2O",target:"O2"},{source:"CH4",target:"CO2"},{source:"CH4",target:"H2O"},{source:"N2O",target:"O2"},{source:"NH3",target:"N2O"},{source:"CO2",target:"O2"}]}}class ys{constructor(){this.container=null,this.candidates=[],this.selectedId=null,this.spectrumChart=null,this.tableBody=null,this.confoundBar=null,this.renderer=null,this.scene=null,this.camera=null,this.controls=null,this.animFrameId=0,this.moleculeMeshes=[],this.resize=()=>{if(!this.renderer||!this.camera)return;const t=this.renderer.domElement.parentElement;if(!t)return;const e=t.clientWidth,i=t.clientHeight;this.renderer.setSize(e,i),this.camera.aspect=e/i,this.camera.updateProjectionMatrix()},this.animate=()=>{var t;this.animFrameId=requestAnimationFrame(this.animate),(t=this.controls)==null||t.update(),this.renderer&&this.scene&&this.camera&&this.renderer.render(this.scene,this.camera)}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
Biosignature Analysis — Real Atmospheric Data
JWST 8 TARGETS
This view analyzes 8 habitable-zone exoplanets for atmospheric biosignatures using real published data. Biosignatures are molecules whose presence in a planet's atmosphere may indicate biological activity. Click any row to inspect its spectrum and confound analysis.
What is JWST?
The James Webb Space Telescope observes exoplanet atmospheres via transmission spectroscopy — starlight passing through a planet's atmosphere reveals molecular absorption lines. Only K2-18 b has confirmed detections so far (CH4+CO2).
Key Molecules
O2 (oxygen) — product of photosynthesis. CH4 (methane) — produced by methanogens. H2O (water) — essential solvent. CO2 — greenhouse gas. DMS — dimethyl sulfide, only known biogenic source on Earth.
Disequilibrium & Confounds
Thermodynamic disequilibrium: CH4+CO2 coexisting implies an active source replenishing CH4 — possibly biological. Confound index = probability that detected signals have a non-biological explanation (volcanism, photochemistry, etc.).
`,e.appendChild(i);const s=document.createElement("div");s.className="split-layout",s.style.flex="1",s.style.minHeight="0",e.appendChild(s);const a=document.createElement("div");a.className="left-panel",s.appendChild(a);const n=document.createElement("div");n.className="table-area",a.appendChild(n);const o=document.createElement("table");o.className="data-table";const r=document.createElement("thead"),l=document.createElement("tr");for(const x of["Name","Score","JWST","O2","CH4","H2O","Diseq."]){const f=document.createElement("th");f.textContent=x,l.appendChild(f)}r.appendChild(l),o.appendChild(r),this.tableBody=document.createElement("tbody"),o.appendChild(this.tableBody),n.appendChild(o);const c=document.createElement("div");c.className="chart-area",c.style.padding="12px 16px",a.appendChild(c);const d=document.createElement("div");d.className="panel-header",d.innerHTML='Confound Index probability of non-biological origin',c.appendChild(d),this.confoundBar=document.createElement("div"),this.confoundBar.style.marginTop="12px",c.appendChild(this.confoundBar);const h=document.createElement("div");h.className="right-panel",s.appendChild(h);const u=document.createElement("div");u.style.height="220px",u.style.minHeight="200px",h.appendChild(u),this.spectrumChart=new gs(u);const m=document.createElement("div");m.className="three-container",m.style.flex="1",m.style.minHeight="200px",h.appendChild(m),this.scene=new nt,this.scene.background=new _(724756),this.camera=new at(50,1,.1,100),this.camera.position.set(0,0,6),this.renderer=new ot({antialias:!0}),this.renderer.setPixelRatio(window.devicePixelRatio),m.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.scene.add(new W(16777215,.6));const g=new it(16777215,.5);g.position.set(3,5,3),this.scene.add(g),this.buildMoleculeScene(),window.addEventListener("resize",this.resize),this.resize(),this.animate(),this.loadData()}buildMoleculeScene(){if(!this.scene)return;const{nodes:t,edges:e}=vs(),i=new Map,s={O2:5809919,H2O:58879,CH4:3066993,CO2:16756768,O3:10044671,N2O:16756768,NH3:16731469};for(const l of t){i.set(l.id,l);const c=new B(.2,16,12),d=new vt({color:s[l.id]??8947848}),h=new L(c,d);h.position.set(l.x,l.y,l.z),this.scene.add(h),this.moleculeMeshes.push(h);const u=document.createElement("canvas");u.width=128,u.height=48;const m=u.getContext("2d");m&&(m.fillStyle="#E6EDF3",m.font="24px sans-serif",m.textAlign="center",m.fillText(l.id,64,32));const g=new Y(u),x=new Z({map:g,transparent:!0}),f=new V(x);f.position.set(l.x,l.y+.35,l.z),f.scale.set(.8,.3,1),this.scene.add(f),this.moleculeMeshes.push(f)}const a=[];for(const l of e){const c=i.get(l.source),d=i.get(l.target);!c||!d||a.push(c.x,c.y,c.z,d.x,d.y,d.z)}const n=new P;n.setAttribute("position",new mt(a,3));const o=new j({color:1844019,transparent:!0,opacity:.6}),r=new gt(n,o);this.scene.add(r),this.moleculeMeshes.push(r)}async loadData(){try{this.candidates=await Ue()}catch(t){console.error("Life API error:",t),this.candidates=[]}this.renderTable(),this.candidates.length>0&&this.selectCandidate(this.candidates[0].id)}renderTable(){if(!this.tableBody)return;this.tableBody.innerHTML="";const t=[...this.candidates].sort((e,i)=>i.score-e.score);for(const e of t){const i=document.createElement("tr");e.id===this.selectedId&&i.classList.add("selected"),i.addEventListener("click",()=>this.selectCandidate(e.id));const s=document.createElement("td");s.textContent=e.name,i.appendChild(s);const a=document.createElement("td");a.textContent=e.score.toFixed(2),i.appendChild(a);const n=document.createElement("td");e.jwstObserved?e.moleculesConfirmed.length>0?n.innerHTML=`${e.moleculesConfirmed.join("+")}`:n.innerHTML='OBS':n.innerHTML='--',i.appendChild(n);for(const o of[e.o2.toFixed(2),e.ch4.toFixed(2),e.h2o.toFixed(2),e.disequilibrium.toFixed(2)]){const r=document.createElement("td");r.textContent=o,i.appendChild(r)}this.tableBody.appendChild(i)}}selectCandidate(t){var s;this.selectedId=t,this.renderTable();const e=this.candidates.find(a=>a.id===t);if(!e)return;const i=fs(e);if((s=this.spectrumChart)==null||s.update(i,xs),this.confoundBar){const a=1-e.disequilibrium,n=a>.7?"Likely abiotic":a>.4?"Ambiguous":"Possibly biogenic",o=a>.7?"Most detected signals can be explained by geological or photochemical processes without invoking biology.":a>.4?"Some signals are consistent with both biological and abiotic origins. Further data needed to distinguish.":"Detected molecular combination is difficult to explain without an active biological source. Strongest biosignature candidates.";this.confoundBar.innerHTML=`
Confound likelihood .3?"var(--warning)":"var(--success)"};font-weight:600">${(a*100).toFixed(0)}% — ${n}
.3?"warning":"success"}" style="width: ${a*100}%">
${o}
Molecular Signals
O2: ${e.o2>.01?(e.o2*100).toFixed(0)+"%":"Not detected"}
CH4: ${e.ch4>.01?(e.ch4*100).toFixed(0)+"%":"Not detected"}
H2O: ${e.h2o>.01?(e.h2o*100).toFixed(0)+"%":"Not detected"}
Assessment
Diseq.: ${(e.disequilibrium*100).toFixed(0)}%
Habitability: ${(e.habitability*100).toFixed(0)}%
JWST: ${e.jwstObserved?e.moleculesConfirmed.length>0?''+e.moleculesConfirmed.join(", ")+"":'Observed, no detections':'Not yet observed'}
Atmosphere Status
${e.atmosphereStatus}
${e.reference?`
${e.reference}
`:""} `}}unmount(){var t,e,i,s,a;window.removeEventListener("resize",this.resize),cancelAnimationFrame(this.animFrameId),(t=this.spectrumChart)==null||t.destroy();for(const n of this.moleculeMeshes)n instanceof L||n instanceof gt?(n.geometry.dispose(),n.material.dispose()):n instanceof V&&((e=n.material.map)==null||e.dispose(),n.material.dispose()),(i=this.scene)==null||i.remove(n);this.moleculeMeshes=[],(s=this.controls)==null||s.dispose(),(a=this.renderer)==null||a.dispose(),this.spectrumChart=null,this.controls=null,this.renderer=null,this.scene=null,this.camera=null,this.container=null}}const bt={seal:"#FF4D4D",commit:"#00E5FF",merge:"#FFB020",verify:"#2ECC71"},bs={seal:"Chain anchor — immutable genesis point",commit:"New evidence committed to chain",merge:"Branch merge — combining data sources",verify:"Verification step — confirms integrity"};class ws{constructor(){this.container=null,this.logEl=null,this.chainCanvas=null,this.coherenceCanvas=null,this.detailEl=null,this.metricsEls={},this.unsubWs=null,this.entries=[],this.selectedIdx=-1,this.chainMeta={integrity:"--",hashAlgo:"SHAKE-256",rootHash:"--",meanCoherence:0,minCoherence:0}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
Witness Chain SHAKE-256 Ed25519
Cryptographic audit trail proving the causal history of every RVF pipeline event. Each witness verifies a specific measurement (transit depth, stellar parameters, etc.). The chain is hash-linked: every entry's SHAKE-256 hash includes the previous entry's hash, making tampering detectable. Seal = anchor, Commit = new evidence, Merge = branch join, Verify = integrity confirmed.
`,e.appendChild(i);const s=document.createElement("div");s.style.cssText="display:flex;gap:12px;padding:12px 20px;border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap";const a=[{key:"entries",label:"Chain Length",color:"var(--accent)"},{key:"integrity",label:"Integrity",color:"#2ECC71"},{key:"coherence",label:"Mean Coherence",color:""},{key:"minCoherence",label:"Min Coherence",color:""},{key:"depth",label:"Epochs",color:""},{key:"rootHash",label:"Root Hash",color:"var(--text-muted)"}];for(const g of a){const x=document.createElement("div");x.style.cssText="background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px;min-width:100px;flex:1",x.innerHTML=`
${g.label}
--
`,s.appendChild(x),this.metricsEls[g.key]=x.querySelector(`[data-metric="${g.key}"]`)}e.appendChild(s);const n=document.createElement("div");n.style.cssText="flex:1;overflow:auto;padding:16px 20px;display:flex;flex-direction:column;gap:16px",e.appendChild(n);const o=document.createElement("div");o.style.cssText="display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;flex-shrink:0",o.innerHTML=`
How It Works
Each pipeline stage produces a witness entry containing: the measurement taken, a confidence score (coherence), and a cryptographic hash that chains to the previous entry. This creates an immutable, tamper-evident record of the entire scientific analysis — from raw photometry to final candidate ranking.
Hash Linking
SHAKE-256 (variable-length SHA-3 family) hashes each entry including the previous hash, creating a Merkle chain. If any entry is modified, all subsequent hashes become invalid. The final entry is signed with Ed25519 to prove chain authorship and prevent repudiation.
Coherence Score
Each witness reports a coherence value (0–1) indicating how well the new evidence agrees with prior chain state. Values < 0.90 are flagged as amber (potential anomaly). The coherence chart below shows how confidence evolves across the pipeline, highlighting where uncertainty enters.
`,n.appendChild(o);const r=document.createElement("div");r.style.cssText="background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex-shrink:0";const l=document.createElement("div");l.style.cssText="padding:10px 14px;font-size:11px;font-weight:500;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.6px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center",l.innerHTML='Chain TopologyClick a node for details',r.appendChild(l),this.chainCanvas=document.createElement("canvas"),this.chainCanvas.style.cssText="width:100%;height:120px;display:block;cursor:pointer",this.chainCanvas.addEventListener("click",g=>this.onChainClick(g)),r.appendChild(this.chainCanvas),n.appendChild(r),this.detailEl=document.createElement("div"),this.detailEl.style.cssText="background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);padding:14px;flex-shrink:0;display:none",n.appendChild(this.detailEl);const c=document.createElement("div");c.style.cssText="background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex-shrink:0";const d=document.createElement("div");d.style.cssText="padding:10px 14px;font-size:11px;font-weight:500;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.6px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center",d.innerHTML='Coherence EvolutionDashed line = 0.90 threshold',c.appendChild(d),this.coherenceCanvas=document.createElement("canvas"),this.coherenceCanvas.style.cssText="width:100%;height:140px;display:block",c.appendChild(this.coherenceCanvas),n.appendChild(c);const h=document.createElement("div");h.style.cssText="background:var(--bg-panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex:1;min-height:200px;display:flex;flex-direction:column";const u=document.createElement("div");u.style.cssText="padding:10px 14px;font-size:11px;font-weight:500;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.6px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;flex-shrink:0",u.innerHTML='Witness LogHash-linked entries',h.appendChild(u);const m=document.createElement("div");m.style.cssText="display:flex;align-items:center;gap:10px;padding:6px 14px;border-bottom:1px solid var(--border);font-size:10px;font-weight:500;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.4px;flex-shrink:0",m.innerHTML=` Time Type Witness Action Coh. Hash `,h.appendChild(m),this.logEl=document.createElement("div"),this.logEl.style.cssText="flex:1;overflow-y:auto;font-family:var(--font-mono);font-size:11px",h.appendChild(this.logEl),n.appendChild(h),this.loadData(),this.unsubWs=St(g=>{g.event_type==="witness"&&this.addLiveEntry(g)})}async loadData(){let t;try{t=await me()}catch{t={entries:[],chain_length:0,integrity:"--",hash_algorithm:"SHAKE-256",root_hash:"--",genesis_hash:"--",mean_coherence:0,min_coherence:0,total_epochs:0}}this.chainMeta={integrity:t.integrity,hashAlgo:t.hash_algorithm,rootHash:t.root_hash,meanCoherence:t.mean_coherence,minCoherence:t.min_coherence},this.entries=t.entries.map(e=>{var i;return{timestamp:e.timestamp.includes("T")?((i=e.timestamp.split("T")[1])==null?void 0:i.substring(0,8))??"":e.timestamp,type:e.type,witness:e.witness,action:e.action,hash:e.hash,prevHash:e.prev_hash,coherence:e.coherence,measurement:e.measurement,epoch:e.epoch}}),this.entries.length===0&&(this.entries=this.generateDemoEntries()),this.updateMetrics(t),this.renderChain(),this.renderCoherence(),this.renderLog()}updateMetrics(t){const e=(a,n)=>{const o=this.metricsEls[a];o&&(o.textContent=n)};e("entries",String(this.entries.length)),e("integrity",this.chainMeta.integrity),e("coherence",this.chainMeta.meanCoherence>0?this.chainMeta.meanCoherence.toFixed(4):"--"),e("minCoherence",this.chainMeta.minCoherence>0?this.chainMeta.minCoherence.toFixed(4):"--"),e("depth",String(t.total_epochs)),e("rootHash",this.chainMeta.rootHash.substring(0,12)+"...");const i=this.metricsEls.minCoherence;i&&this.chainMeta.minCoherence>0&&this.chainMeta.minCoherence<.9&&(i.style.color="#FFB020");const s=this.metricsEls.integrity;s&&(s.style.color=this.chainMeta.integrity==="VALID"?"#2ECC71":"#FF4D4D")}renderChain(){var u;const t=this.chainCanvas;if(!t)return;const e=(u=t.parentElement)==null?void 0:u.getBoundingClientRect(),i=(e==null?void 0:e.width)??800,s=120,a=window.devicePixelRatio||1;t.width=i*a,t.height=s*a,t.style.width=`${i}px`,t.style.height=`${s}px`;const n=t.getContext("2d");if(!n)return;n.scale(a,a),n.clearRect(0,0,i,s);const o=this.entries.length;if(o===0)return;const r=40,l=20,c=i-r*2,d=s/2,h=8;for(let m=0;m1?m/(o-1)*c:c/2),f=bt[g.type]??"#00E5FF",w=m===this.selectedIdx;w&&(n.beginPath(),n.arc(x,d,h+4,0,Math.PI*2),n.fillStyle=f.replace(")",", 0.15)").replace("rgb","rgba").replace("#",""),n.shadowColor=f,n.shadowBlur=12,n.fill(),n.shadowBlur=0),n.beginPath(),n.arc(x,d,h,0,Math.PI*2),n.fillStyle=w?f:"transparent",n.strokeStyle=f,n.lineWidth=2,n.fill(),n.stroke(),w||(n.beginPath(),n.arc(x,d,3,0,Math.PI*2),n.fillStyle=f,n.fill()),n.fillStyle="#8B949E",n.font="9px monospace",n.textAlign="center";const y=g.witness.replace("W_","");n.fillText(y,x,d-h-l+8),n.fillStyle=g.coherence<.9?"#FFB020":"#484F58",n.font="9px monospace",n.fillText(g.coherence.toFixed(2),x,d+h+14),n.fillStyle="#30363D",n.font="8px monospace",n.fillText(g.hash.substring(0,6),x,d+h+24)}}onChainClick(t){const e=this.chainCanvas;if(!e||this.entries.length===0)return;const i=e.getBoundingClientRect(),s=t.clientX-i.left,a=this.entries.length,n=40,o=i.width-n*2;let r=-1,l=1/0;for(let c=0;c1?c/(a-1)*o:o/2),h=Math.abs(s-d);h=0&&(this.selectedIdx=r===this.selectedIdx?-1:r,this.renderChain(),this.showDetail(this.selectedIdx>=0?this.entries[this.selectedIdx]:null))}showDetail(t){if(!this.detailEl)return;if(!t){this.detailEl.style.display="none";return}const e=bt[t.type]??"#00E5FF",i=bs[t.type]??"",s=t.coherence<.9?"#FFB020":"#2ECC71";this.detailEl.style.display="block",this.detailEl.innerHTML=`
${t.witness} ${t.type} ${i} Epoch ${t.epoch}
Action
${t.action}
Measurement
${t.measurement??"N/A"}
Coherence
${t.coherence.toFixed(4)}
Hash
${t.hash}
Previous Hash
${t.prevHash}
`}renderCoherence(){var y;const t=this.coherenceCanvas;if(!t)return;const e=(y=t.parentElement)==null?void 0:y.getBoundingClientRect(),i=(e==null?void 0:e.width)??800,s=140,a=window.devicePixelRatio||1;t.width=i*a,t.height=s*a,t.style.width=`${i}px`,t.style.height=`${s}px`;const n=t.getContext("2d");if(!n)return;n.scale(a,a),n.clearRect(0,0,i,s);const o=this.entries.length;if(o===0)return;const r=50,l=20,c=16,d=28,h=i-r-l,u=s-c-d,m=.8,g=1.01,x=b=>r+(o>1?b/(o-1)*h:h/2),f=b=>c+(1-(b-m)/(g-m))*u;n.strokeStyle="#161C24",n.lineWidth=1;for(let b=.8;b<=1.001;b+=.05){const v=f(b);n.beginPath(),n.moveTo(r,v),n.lineTo(i-l,v),n.stroke(),n.fillStyle="#484F58",n.font="10px monospace",n.textAlign="right",n.fillText(b.toFixed(2),r-6,v+4)}n.setLineDash([4,4]),n.strokeStyle="#FFB02066",n.lineWidth=1,n.beginPath(),n.moveTo(r,f(.9)),n.lineTo(i-l,f(.9)),n.stroke(),n.setLineDash([]),n.fillStyle="#FFB020",n.font="9px monospace",n.textAlign="left",n.fillText("threshold",i-l-55,f(.9)-4),n.beginPath(),n.moveTo(x(0),f(m));for(let b=0;b{i.style.background="rgba(255,255,255,0.015)"}),i.addEventListener("mouseleave",()=>{i.style.background=e===this.selectedIdx?"rgba(0,229,255,0.04)":""}),i.addEventListener("click",()=>{var o;this.selectedIdx=e===this.selectedIdx?-1:e,this.renderChain(),this.showDetail(this.selectedIdx>=0?this.entries[this.selectedIdx]:null);const n=(o=this.logEl)==null?void 0:o.children;if(n)for(let r=0;r${t.timestamp} ${t.type} ${t.witness} ${t.action} ${t.coherence.toFixed(2)} ${t.hash.substring(0,8)}..${t.prevHash.substring(0,4)} `,this.logEl.appendChild(i)}addLiveEntry(t){const e={timestamp:new Date(t.timestamp*1e3).toISOString().substring(11,19),type:String(t.data.type??"commit"),witness:String(t.data.witness??"W_live"),action:String(t.data.action??"live_event"),hash:String(t.data.hash??this.fakeHash("live")),prevHash:this.entries.length>0?this.entries[this.entries.length-1].hash:"0000000000000000",coherence:Number(t.data.coherence??1),measurement:t.data.measurement?String(t.data.measurement):null,epoch:this.entries.length};this.entries.push(e),this.appendLogEntry(e,this.entries.length-1),this.renderChain(),this.renderCoherence();const i=this.metricsEls.entries;i&&(i.textContent=String(this.entries.length)),this.logEl&&(this.logEl.scrollTop=this.logEl.scrollHeight)}fakeHash(t){let e=0;for(let i=0;i{const a=this.fakeHash(i.w+s),n={timestamp:new Date(Date.now()-(t.length-s)*12e4).toISOString().substring(11,19),type:i.t,witness:i.w,action:i.a,hash:a,prevHash:e,coherence:1-s*.01,measurement:i.m,epoch:s};return e=a,n})}unmount(){var t;(t=this.unsubWs)==null||t.call(this),this.logEl=null,this.chainCanvas=null,this.coherenceCanvas=null,this.detailEl=null,this.metricsEls={},this.container=null,this.entries=[],this.selectedIdx=-1}}let zt=null;async function Es(){try{const p=await fetch("/rvf_solver_wasm.wasm");if(!p.ok)throw new Error(`HTTP ${p.status}`);const{instance:t}=await WebAssembly.instantiateStreaming(p,{env:{}});return t.exports}catch(p){return console.debug("[rvf-solver] WASM load failed, using demo mode:",p),null}}function At(p,t,e,i){const s=e(t);if(s<=0)return null;const a=p.rvf_solver_alloc(s);if(a===0)return null;try{i(t,a);const n=new Uint8Array(p.memory.buffer,a,s),o=new TextDecoder().decode(n);return JSON.parse(o)}finally{p.rvf_solver_free(a,s)}}function Zt(p){if(p===void 0){const e=BigInt(Math.floor(Math.random()*18446744073709552e3));return[Number(e&0xffffffffn),Number(e>>32n&0xffffffffn)]}const t=typeof p=="number"?BigInt(p):p;return[Number(t&0xffffffffn),Number(t>>32n&0xffffffffn)]}class Cs{constructor(t,e){this.handle=t,this.wasm=e}train(t){const[e,i]=Zt(t.seed),s=this.wasm.rvf_solver_train(this.handle,t.count,t.minDifficulty??1,t.maxDifficulty??10,e,i);if(s<0)throw new Error("Training failed");const a=At(this.wasm,this.handle,n=>this.wasm.rvf_solver_result_len(n),(n,o)=>this.wasm.rvf_solver_result_read(n,o));return{trained:(a==null?void 0:a.trained)??t.count,correct:(a==null?void 0:a.correct)??s,accuracy:(a==null?void 0:a.accuracy)??s/t.count,patternsLearned:(a==null?void 0:a.patterns_learned)??0}}acceptance(t){const e=t??{},[i,s]=Zt(e.seed);if(this.wasm.rvf_solver_acceptance(this.handle,e.holdoutSize??50,e.trainingPerCycle??200,e.cycles??5,e.stepBudget??500,i,s)<0)throw new Error("Acceptance failed");const n=At(this.wasm,this.handle,r=>this.wasm.rvf_solver_result_len(r),(r,l)=>this.wasm.rvf_solver_result_read(r,l));if(!n)throw new Error("Failed to read acceptance manifest");const o=r=>({passed:!!r.passed,accuracyMaintained:!!(r.accuracy_maintained??r.accuracyMaintained),costImproved:!!(r.cost_improved??r.costImproved),robustnessImproved:!!(r.robustness_improved??r.robustnessImproved),zeroViolations:!!(r.zero_violations??r.zeroViolations),dimensionsImproved:r.dimensions_improved??r.dimensionsImproved??0,cycles:(r.cycles??[]).map(l=>({cycle:l.cycle??0,accuracy:l.accuracy??0,costPerSolve:l.cost_per_solve??l.costPerSolve??0,noiseAccuracy:l.noise_accuracy??l.noiseAccuracy??0,violations:l.violations??0,patternsLearned:l.patterns_learned??l.patternsLearned??0}))});return{version:n.version??2,modeA:o(n.mode_a),modeB:o(n.mode_b),modeC:o(n.mode_c),allPassed:!!n.all_passed,witnessEntries:n.witness_entries??0,witnessChainBytes:n.witness_chain_bytes??0}}policy(){const t=At(this.wasm,this.handle,e=>this.wasm.rvf_solver_policy_len(e),(e,i)=>this.wasm.rvf_solver_policy_read(e,i));return t?{contextStats:t.context_stats??t.contextStats??{},earlyCommitPenalties:t.early_commit_penalties??t.earlyCommitPenalties??0,earlyCommitsTotal:t.early_commits_total??t.earlyCommitsTotal??0,earlyCommitsWrong:t.early_commits_wrong??t.earlyCommitsWrong??0,prepass:t.prepass??"",speculativeAttempts:t.speculative_attempts??t.speculativeAttempts??0,speculativeArm2Wins:t.speculative_arm2_wins??t.speculativeArm2Wins??0}:null}destroy(){this.handle>0&&(this.wasm.rvf_solver_destroy(this.handle),this.handle=0)}}let wt=null,$t=null;async function Ms(){zt||(zt=Es());const p=await zt;if(!p)return null;const t=p.rvf_solver_create();return t<0?(console.debug("[rvf-solver] Failed to create solver instance"),null):new Cs(t,p)}async function kt(){return wt||($t||($t=Ms()),wt=await $t,wt)}function Ts(p,t){const e=.55+t*.08,i=Math.min(.98,e+(Math.random()-.5)*.04),s=Math.round(p*i);return{trained:p,correct:s,accuracy:i,patternsLearned:Math.floor(p*.15*(1+t*.3))}}function Ss(){const p=t=>Array.from({length:5},(e,i)=>({cycle:i+1,accuracy:Math.min(.99,t+i*.03+(Math.random()-.5)*.02),costPerSolve:120-i*15+Math.random()*10,noiseAccuracy:t-.05+Math.random()*.03,violations:i<2?1:0,patternsLearned:(i+1)*12}));return{version:2,modeA:{passed:!0,accuracyMaintained:!0,costImproved:!1,robustnessImproved:!1,zeroViolations:!1,dimensionsImproved:1,cycles:p(.62)},modeB:{passed:!0,accuracyMaintained:!0,costImproved:!0,robustnessImproved:!1,zeroViolations:!1,dimensionsImproved:2,cycles:p(.71)},modeC:{passed:!0,accuracyMaintained:!0,costImproved:!0,robustnessImproved:!0,zeroViolations:!0,dimensionsImproved:3,cycles:p(.78)},allPassed:!0,witnessEntries:25,witnessChainBytes:1825}}function Xt(){const p=["easy","medium","hard","extreme"],t=["none","weekday","hybrid"],e={};for(const i of p){e[i]={};for(const s of t)e[i][s]={attempts:Math.floor(Math.random()*200)+50,successes:Math.floor(Math.random()*150)+30,totalSteps:Math.floor(Math.random()*5e3)+1e3,alphaSafety:1+Math.random()*2,betaSafety:1+Math.random(),costEma:50+Math.random()*80,earlyCommitWrongs:Math.floor(Math.random()*5)}}return{contextStats:e,earlyCommitPenalties:3,earlyCommitsTotal:42,earlyCommitsWrong:3,prepass:"naked_singles",speculativeAttempts:156,speculativeArm2Wins:38}}const Lt={A:"#FF4D4D",B:"#FFB020",C:"#2ECC71"};function Pt(p){let t=p|0;return()=>(t=t*1664525+1013904223&2147483647,t/2147483647)}class _s{constructor(){this.container=null,this.renderer=null,this.scene=null,this.camera=null,this.controls=null,this.animFrameId=0,this.landscapeMesh=null,this.bgStars=null,this.galacticPlane=null,this.galacticCore=null,this.nebulae=[],this.armMarkers=null,this.peakGlows=[],this.trainingHistory=[],this.manifest=null,this.policy=null,this.isTraining=!1,this.usesWasm=!1,this.landscapeTime=0,this.speed=1,this.autoRotate=!1,this.trainCount=200,this.minDifficulty=1,this.maxDifficulty=8,this.acceptCycles=5,this.holdoutSize=50,this.trainingPerCycle=200,this.stepBudget=500,this.autoTrainRounds=8,this.trainBtn=null,this.acceptBtn=null,this.statusEl=null,this.curveCanvas=null,this.modesEl=null,this.policyEl=null,this.controlsEl=null,this.speedLabel=null,this.resize=()=>{if(!this.renderer||!this.camera||!this.container)return;const t=this.renderer.domElement.parentElement;if(!t)return;const e=t.clientWidth,i=t.clientHeight;e===0||i===0||(this.renderer.setSize(e,i),this.camera.aspect=e/i,this.camera.updateProjectionMatrix())},this.animate=()=>{var t;if(this.animFrameId=requestAnimationFrame(this.animate),this.landscapeTime+=.005*this.speed,this.landscapeMesh){const i=this.landscapeMesh.geometry.attributes.position;for(let s=0;s
RVF Self-Learning Solver
WASM THOMPSON SAMPLING
Interactive WASM-powered constraint solver that learns to solve puzzles using multi-armed bandit algorithms. The solver improves by discovering which strategies work best for different puzzle difficulties, building a policy that adapts in real-time.
`,e.appendChild(i);const s=document.createElement("div");s.className="split-layout",s.style.flex="1",s.style.minHeight="0",e.appendChild(s);const a=document.createElement("div");a.className="left-panel",a.style.cssText="overflow-y:auto;overflow-x:hidden;padding:12px;scroll-behavior:smooth;-webkit-overflow-scrolling:touch",s.appendChild(a),this.buildLeftPanel(a);const n=document.createElement("div");n.className="right-panel",n.style.cssText="padding:0;position:relative;display:flex;flex-direction:column",s.appendChild(n);const o=document.createElement("div");o.className="three-container",o.style.cssText="flex:1;min-height:0;position:relative",n.appendChild(o),this.initThreeJs(o),this.buildViewportControls(o);const r=document.createElement("div");r.style.cssText="position:absolute;bottom:8px;left:50%;transform:translateX(-50%);font-size:9px;color:rgba(255,255,255,0.3);pointer-events:none;white-space:nowrap",r.textContent="Drag to rotate | Scroll to zoom | Right-drag to pan",o.appendChild(r),window.addEventListener("resize",this.resize),this.resize(),this.animate(),this.init()}buildLeftPanel(t){const e=document.createElement("div");e.style.cssText="font-size:10px;color:var(--accent);cursor:pointer;margin-bottom:8px;display:flex;align-items:center;gap:4px",e.innerHTML=' How it works';const i=document.createElement("div");i.style.cssText="display:none;margin-bottom:12px",i.innerHTML=`
Training
Each cycle generates puzzles of varying difficulty (1-8). Thompson Sampling explores strategies by sampling from Beta distributions, balancing exploration vs exploitation.
Acceptance Test
A accuracy only. B accuracy + cost. C full multi-objective.
3D Landscape
Terrain shows bandit arm reward distributions. Peaks = high-reward strategies. Blue=low, green=medium, red=high.
`,e.addEventListener("click",()=>{const h=i.style.display!=="none";i.style.display=h?"none":"block";const u=e.querySelector("#info-arrow");u&&(u.style.transform=h?"":"rotate(90deg)")}),t.appendChild(e),t.appendChild(i);const s=document.createElement("div");s.className="panel",s.style.marginBottom="12px",t.appendChild(s);const a=document.createElement("div");a.className="panel-header",a.innerHTML='Controls train & test',s.appendChild(a);const n=document.createElement("div");n.className="panel-body",n.style.cssText="display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:8px 10px",s.appendChild(n),this.trainBtn=document.createElement("button"),this.trainBtn.textContent="Train (200)",this.trainBtn.className="scale-btn",this.trainBtn.style.cssText="font-size:11px;padding:4px 10px;white-space:nowrap",this.trainBtn.addEventListener("click",()=>this.runTraining()),n.appendChild(this.trainBtn),this.acceptBtn=document.createElement("button"),this.acceptBtn.textContent="Acceptance",this.acceptBtn.className="scale-btn",this.acceptBtn.style.cssText="font-size:11px;padding:4px 10px;white-space:nowrap",this.acceptBtn.addEventListener("click",()=>this.runAcceptance()),n.appendChild(this.acceptBtn);const o=document.createElement("button");o.textContent="Auto (8x)",o.className="scale-btn",o.style.cssText="font-size:11px;padding:4px 10px;white-space:nowrap",o.addEventListener("click",()=>this.runAutoTraining()),n.appendChild(o);const r=document.createElement("button");r.textContent="Auto-Optimize",r.className="scale-btn",r.style.cssText="font-size:11px;padding:4px 10px;white-space:nowrap;border-color:rgba(46,204,113,0.3);color:var(--success)",r.title="Keep training until acceptance passes (max 30 rounds)",r.addEventListener("click",()=>this.runAutoOptimize()),n.appendChild(r),this.statusEl=document.createElement("div"),this.statusEl.style.cssText="font-size:11px;color:var(--text-secondary);width:100%;margin-top:4px",this.statusEl.textContent="Initializing...",n.appendChild(this.statusEl),this.buildConfigPanel(t);const l=document.createElement("div");l.className="panel",l.style.marginBottom="12px",t.appendChild(l);const c=document.createElement("div");c.className="panel-header",c.innerHTML='Training Curves accuracy & patterns',l.appendChild(c),this.curveCanvas=document.createElement("canvas"),this.curveCanvas.width=500,this.curveCanvas.height=200,this.curveCanvas.style.cssText="width:100%;height:180px;display:block",l.appendChild(this.curveCanvas);const d=document.createElement("div");d.style.cssText="display:flex;gap:12px;padding:4px 10px;font-size:9px;color:var(--text-muted)",d.innerHTML=` Accuracy Patterns Loss `,l.appendChild(d),this.modesEl=document.createElement("div"),this.modesEl.className="panel",this.modesEl.style.marginBottom="12px",t.appendChild(this.modesEl),this.policyEl=document.createElement("div"),this.policyEl.className="panel",this.policyEl.style.marginBottom="16px",t.appendChild(this.policyEl)}buildConfigPanel(t){const e=document.createElement("div");e.className="panel",e.style.marginBottom="12px",t.appendChild(e);const i=document.createElement("div");i.className="panel-header",i.style.cursor="pointer",i.innerHTML='Configuration ',e.appendChild(i);const s=document.createElement("div");s.className="panel-body",s.style.cssText="display:none;padding:10px",e.appendChild(s),i.addEventListener("click",()=>{const d=s.style.display!=="none";s.style.display=d?"none":"block";const h=i.querySelector("#config-arrow");h&&(h.style.transform=d?"":"rotate(90deg)")});const a=document.createElement("div");a.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:8px",s.appendChild(a);const n=(d,h,u,m,g,x)=>{const f=document.createElement("div");f.style.cssText="display:flex;flex-direction:column;gap:3px";const w=document.createElement("div");w.style.cssText="display:flex;justify-content:space-between;align-items:center";const y=document.createElement("span");y.style.cssText="font-size:9px;color:var(--text-muted)",y.textContent=d,w.appendChild(y);const b=document.createElement("span");b.style.cssText="font-size:10px;font-family:var(--font-mono);color:var(--accent)",b.textContent=String(g),w.appendChild(b),f.appendChild(w);const v=document.createElement("input");return v.type="range",v.min=String(h),v.max=String(u),v.step=String(m),v.value=String(g),v.style.cssText="width:100%;height:3px;accent-color:#00E5FF;cursor:pointer",v.addEventListener("input",()=>{const E=parseFloat(v.value);b.textContent=String(E),x(E)}),f.appendChild(v),f},o=document.createElement("div");o.style.cssText="grid-column:1/-1;font-size:9px;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.4px;border-bottom:1px solid var(--border);padding-bottom:4px;margin-bottom:2px",o.textContent="Training",a.appendChild(o),a.appendChild(n("Puzzles per cycle",50,500,50,this.trainCount,d=>{this.trainCount=d,this.trainBtn&&(this.trainBtn.textContent=`Train (${d})`)})),a.appendChild(n("Auto-train rounds",3,20,1,this.autoTrainRounds,d=>{this.autoTrainRounds=d})),a.appendChild(n("Min difficulty",1,5,1,this.minDifficulty,d=>{this.minDifficulty=d})),a.appendChild(n("Max difficulty",3,10,1,this.maxDifficulty,d=>{this.maxDifficulty=d}));const r=document.createElement("div");r.style.cssText="grid-column:1/-1;font-size:9px;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.4px;border-bottom:1px solid var(--border);padding-bottom:4px;margin-top:6px;margin-bottom:2px",r.textContent="Acceptance Test",a.appendChild(r),a.appendChild(n("Cycles",2,10,1,this.acceptCycles,d=>{this.acceptCycles=d})),a.appendChild(n("Holdout size",10,100,10,this.holdoutSize,d=>{this.holdoutSize=d})),a.appendChild(n("Training/cycle",50,500,50,this.trainingPerCycle,d=>{this.trainingPerCycle=d})),a.appendChild(n("Step budget",100,2e3,100,this.stepBudget,d=>{this.stepBudget=d}));const l=document.createElement("div");l.style.cssText="grid-column:1/-1;display:flex;gap:6px;margin-top:6px";const c=(d,h)=>{const u=document.createElement("button");return u.className="scale-btn",u.style.cssText="font-size:9px;padding:3px 8px;flex:1",u.textContent=d,u.addEventListener("click",()=>{this.trainCount=h.tc,this.autoTrainRounds=h.ar,this.acceptCycles=h.ac,this.holdoutSize=h.hs,this.trainingPerCycle=h.tpc,this.stepBudget=h.sb,this.trainBtn&&(this.trainBtn.textContent=`Train (${h.tc})`),s.style.display="none";const m=i.querySelector("#config-arrow");m&&(m.style.transform=""),a.innerHTML="",this.buildConfigPanel(t),e.remove()}),u};l.appendChild(c("Quick",{tc:100,ar:5,ac:3,hs:30,tpc:100,sb:300})),l.appendChild(c("Balanced",{tc:200,ar:8,ac:5,hs:50,tpc:200,sb:500})),l.appendChild(c("Thorough",{tc:500,ar:12,ac:12,hs:50,tpc:800,sb:2e3})),a.appendChild(l)}buildViewportControls(t){this.controlsEl=document.createElement("div"),this.controlsEl.style.cssText=` position:absolute;top:8px;right:8px;z-index:10; display:flex;flex-direction:column;gap:6px; background:rgba(11,15,20,0.85);border:1px solid rgba(0,229,255,0.15); border-radius:6px;padding:8px 10px;backdrop-filter:blur(6px); font-size:10px;color:var(--text-secondary);min-width:130px `;const e=document.createElement("div");e.style.cssText="display:flex;align-items:center;gap:6px";const i=document.createElement("span");i.textContent="Speed",i.style.cssText="color:var(--accent);font-weight:600;font-size:9px;min-width:34px",e.appendChild(i);const s=document.createElement("input");s.type="range",s.min="0.1",s.max="5",s.step="0.1",s.value="1",s.style.cssText="flex:1;height:3px;accent-color:#00E5FF;cursor:pointer",e.appendChild(s),this.speedLabel=document.createElement("span"),this.speedLabel.style.cssText="font-family:var(--font-mono);font-size:9px;min-width:24px;text-align:right;color:var(--text-primary)",this.speedLabel.textContent="1.0x",e.appendChild(this.speedLabel),s.addEventListener("input",()=>{this.speed=parseFloat(s.value),this.speedLabel&&(this.speedLabel.textContent=this.speed.toFixed(1)+"x")}),this.controlsEl.appendChild(e);const a=document.createElement("div");a.style.cssText="display:flex;align-items:center;gap:6px";const n=document.createElement("span");n.style.cssText="font-size:9px;color:var(--text-secondary);flex:1",n.textContent="Auto-rotate",a.appendChild(n);const o=document.createElement("button");o.style.cssText="font-size:9px;padding:2px 8px;border-radius:3px;border:1px solid rgba(0,229,255,0.2);background:transparent;color:var(--text-muted);cursor:pointer",o.textContent="OFF",o.addEventListener("click",()=>{this.autoRotate=!this.autoRotate,this.controls&&(this.controls.autoRotate=this.autoRotate),o.textContent=this.autoRotate?"ON":"OFF",o.style.color=this.autoRotate?"var(--accent)":"var(--text-muted)",o.style.borderColor=this.autoRotate?"rgba(0,229,255,0.4)":"rgba(0,229,255,0.2)"}),a.appendChild(o),this.controlsEl.appendChild(a);const r=document.createElement("button");r.style.cssText="font-size:9px;padding:3px 0;border-radius:3px;border:1px solid rgba(255,255,255,0.1);background:transparent;color:var(--text-muted);cursor:pointer;width:100%",r.textContent="Reset View",r.addEventListener("click",()=>this.resetCamera()),this.controlsEl.appendChild(r),t.appendChild(this.controlsEl)}resetCamera(){!this.camera||!this.controls||(this.camera.position.set(0,8,14),this.camera.lookAt(0,0,0),this.controls.target.set(0,0,0),this.controls.update())}initThreeJs(t){this.scene=new nt,this.scene.background=new _(329744),this.scene.fog=new ae(329744,.003),this.camera=new at(50,1,.1,2e3),this.camera.position.set(0,8,14),this.camera.lookAt(0,0,0),this.renderer=new ot({antialias:!0,alpha:!1}),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.renderer.toneMapping=oe,this.renderer.toneMappingExposure=1.2,t.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.08,this.controls.maxPolarAngle=Math.PI*.48,this.controls.minDistance=4,this.controls.maxDistance=60,this.controls.autoRotateSpeed=.5,this.scene.add(new W(3359846,.6));const e=new it(11193599,.8);e.position.set(5,12,5),this.scene.add(e);const i=new it(16746564,.2);i.position.set(-3,5,-3),this.scene.add(i),this.buildStarfield(),this.buildGalacticPlane(),this.buildNebulae();const s=new Tt(12,24,1844019,790552);s.position.y=-.02,this.scene.add(s),this.buildLandscape(),this.armMarkers=new tt,this.scene.add(this.armMarkers),this.buildArmMarkers()}buildStarfield(){if(!this.scene)return;const t=5e3,e=Pt(42),i=new Float32Array(t*3),s=new Float32Array(t*3),a=new Float32Array(t);for(let o=0;o>16&255,l=o>>8&255,c=o&255;n.addColorStop(0,`rgba(${r},${l},${c},0.25)`),n.addColorStop(.5,`rgba(${r},${l},${c},0.08)`),n.addColorStop(1,"rgba(0,0,0,0)"),a.fillStyle=n,a.fillRect(0,0,64,64);const d=new Y(s),h=new V(new Z({map:d,transparent:!0,blending:et,opacity:.5})),u=t()*Math.PI*2,m=150+t()*250;h.position.set(Math.cos(u)*m,-30+t()*100,Math.sin(u)*m),h.scale.set(60+t()*80,60+t()*80,1),this.scene.add(h),this.nebulae.push(h)}}buildLandscape(){if(!this.scene)return;const t=48,e=new Rt(10,10,t-1,t-1),i=new Float32Array(e.attributes.position.count*3);for(let o=0;o0;)this.armMarkers.remove(this.armMarkers.children[0]);this.peakGlows=[];const t=["Naked Singles","Hidden Pairs","X-Wing","Backtrack","Constraint Prop","Pattern Match","Speculative","Hybrid"],e=3.5;for(let i=0;i=0&&d=0&&d0){const s=this.trainingHistory[this.trainingHistory.length-1].accuracy;for(let a=0;asetTimeout(o,500)),e=Ts(this.trainCount,t),this.policy=Xt());const s=1-e.accuracy,a=(Math.random()-.5)*.05,n=Math.max(.01,s+a);this.trainingHistory.push({cycle:t,accuracy:e.accuracy,patterns:e.patternsLearned,loss:n}),this.renderCurve(),this.updateLandscape(),this.renderPolicy(),this.statusEl&&(this.statusEl.textContent=`Cycle ${t+1}: ${(e.accuracy*100).toFixed(1)}% accuracy, ${e.patternsLearned} patterns, loss ${n.toFixed(3)}`,this.statusEl.style.color="var(--text-secondary)"),this.isTraining=!1,this.trainBtn&&(this.trainBtn.disabled=!1)}async runAcceptance(){if(this.isTraining)return;this.isTraining=!0,this.acceptBtn&&(this.acceptBtn.disabled=!0),this.statusEl&&(this.statusEl.textContent="Running acceptance test...",this.statusEl.style.color="var(--accent)");const t=await kt();if(t?(this.manifest=t.acceptance({cycles:this.acceptCycles,holdoutSize:this.holdoutSize,trainingPerCycle:this.trainingPerCycle,stepBudget:this.stepBudget}),this.policy=t.policy()):(await new Promise(e=>setTimeout(e,1200)),this.manifest=Ss(),this.policy=Xt()),this.renderModes(),this.updateLandscape(),this.renderPolicy(),this.statusEl){const e=this.manifest.allPassed;this.statusEl.textContent=`Acceptance: ${e?"PASSED":"FAILED"} — ${this.manifest.witnessEntries} witness entries`,this.statusEl.style.color=e?"var(--success)":"var(--danger)"}this.isTraining=!1,this.acceptBtn&&(this.acceptBtn.disabled=!1)}async runAutoTraining(){if(!this.isTraining){for(let t=0;tsetTimeout(e,150));await this.runAcceptance()}}async runAutoOptimize(){var s;if(this.isTraining)return;const t=[{label:"Phase 1",tpc:this.trainingPerCycle,cycles:this.acceptCycles,budget:this.stepBudget,hs:this.holdoutSize,seeds:3},{label:"Phase 2",tpc:500,cycles:8,budget:1200,hs:50,seeds:3},{label:"Phase 3",tpc:800,cycles:12,budget:2e3,hs:50,seeds:3}];let e=0;const i=t.reduce((a,n)=>a+n.seeds,0);for(const a of t){this.trainingPerCycle=a.tpc,this.acceptCycles=a.cycles,this.stepBudget=a.budget,this.holdoutSize=a.hs;for(let n=0;n1&&(this.statusEl&&(this.statusEl.textContent=`${a.label}: training before attempt ${e}/${i}...`,this.statusEl.style.color="var(--accent)"),await this.runTraining(),await new Promise(r=>setTimeout(r,50))),this.statusEl&&(this.statusEl.textContent=`${a.label}: acceptance attempt ${e}/${i} (tpc=${a.tpc}, c=${a.cycles}, sb=${a.budget})...`,this.statusEl.style.color="var(--warning)"),await this.runAcceptance(),((s=this.manifest)==null?void 0:s.allPassed)??!1){this.statusEl&&(this.statusEl.textContent=`Auto-optimize: PASSED on attempt ${e} (${a.label})!`,this.statusEl.style.color="var(--success)");return}if(this.statusEl&&this.manifest){const r=this.manifest.modeC,l=[];r.accuracyMaintained||l.push("accuracy < 80%"),r.costImproved||l.push("cost not improved 5%"),r.robustnessImproved||l.push("robustness not improved 3%"),r.dimensionsImproved<2&&l.push(`only ${r.dimensionsImproved}/2 dims`),this.statusEl.textContent=`Attempt ${e}: FAILED — ${l.join(", ")}`,this.statusEl.style.color="#FF4D4D"}await new Promise(r=>setTimeout(r,100))}}this.statusEl&&(this.statusEl.textContent=`Auto-optimize: did not pass after ${e} attempts. The acceptance test creates a fresh solver each time — try increasing Training/cycle and Cycles.`,this.statusEl.style.color="#FF4D4D")}renderCurve(){if(!this.curveCanvas||this.trainingHistory.length===0)return;const t=this.curveCanvas.getContext("2d");if(!t)return;const e=this.curveCanvas.width,i=this.curveCanvas.height,s={top:14,right:14,bottom:28,left:44},a=e-s.left-s.right,n=i-s.top-s.bottom;t.clearRect(0,0,e,i),t.fillStyle="#0B0F14",t.fillRect(0,0,e,i);const o=this.trainingHistory,r=Math.max(o.length-1,1);t.strokeStyle="#1A2030",t.lineWidth=.5;for(let d=0;d<=1;d+=.25){const h=s.top+n*(1-d);t.beginPath(),t.moveTo(s.left,h),t.lineTo(s.left+a,h),t.stroke(),t.fillStyle="#484F58",t.font="10px monospace",t.textAlign="right",t.fillText(`${(d*100).toFixed(0)}%`,s.left-6,h+3)}t.fillStyle="rgba(0,229,255,0.06)",t.beginPath(),t.moveTo(s.left,s.top+n);for(let d=0;d1){const d=Math.max(...o.map(h=>h.patterns),1);t.strokeStyle="#58A6FF",t.lineWidth=1.5,t.setLineDash([5,3]),t.beginPath();for(let h=0;h1){t.strokeStyle="#FF6B9D",t.lineWidth=1.5,t.setLineDash([3,4]),t.beginPath();for(let d=0;d
Click "Acceptance" to see results
Train the solver first (multiple cycles recommended) before running acceptance.
`;return}const i=[{label:"Mode A",desc:"Heuristic — accuracy only",data:this.manifest.modeA,color:Lt.A},{label:"Mode B",desc:"Compiler — accuracy + cost",data:this.manifest.modeB,color:Lt.B},{label:"Mode C",desc:"Learned — full multi-objective",data:this.manifest.modeC,color:Lt.C}];for(const o of i){const r=document.createElement("div");r.style.cssText="margin-bottom:8px;padding:8px;background:var(--bg-surface);border:1px solid var(--border);border-radius:4px";const l=o.data.cycles.length>0?o.data.cycles[o.data.cycles.length-1].accuracy:0,c=o.data.passed?"PASS":"FAIL",d=o.data.passed?"var(--success)":"#FF4D4D";r.innerHTML=`
${o.label} ${o.desc} ${c} ${(l*100).toFixed(1)}%
`;const h=document.createElement("div");h.style.cssText="display:flex;gap:2px;align-items:flex-end;height:20px;margin-bottom:4px";for(const g of o.data.cycles){const x=document.createElement("div");x.style.cssText=`flex:1;height:${g.accuracy*100}%;background:${o.color};border-radius:1px;opacity:0.7;transition:height 0.3s`,x.title=`Cycle ${g.cycle}: ${(g.accuracy*100).toFixed(1)}% | Cost: ${g.costPerSolve.toFixed(0)}`,h.appendChild(x)}r.appendChild(h);const u=document.createElement("div");u.style.cssText="display:flex;gap:3px;flex-wrap:wrap";const m=(g,x)=>{const f=document.createElement("span");f.style.cssText=`font-size:8px;padding:1px 4px;border-radius:2px;border:1px solid ${x?"rgba(46,204,113,0.3)":"rgba(255,77,77,0.3)"};color:${x?"var(--success)":"#FF4D4D"}`,f.textContent=g,u.appendChild(f)};m(`Acc: ${o.data.accuracyMaintained?"OK":"FAIL"}`,o.data.accuracyMaintained),m(`Cost: ${o.data.costImproved?"OK":"N/A"}`,o.data.costImproved),m(`Rob: ${o.data.robustnessImproved?"OK":"N/A"}`,o.data.robustnessImproved),m(`Viol: ${o.data.zeroViolations?"0":">0"}`,o.data.zeroViolations),r.appendChild(u),e.appendChild(r)}const s=document.createElement("div");s.style.cssText=`padding:6px;border-radius:4px;text-align:center;font-size:11px;font-weight:700; background:${this.manifest.allPassed?"rgba(46,204,113,0.1)":"rgba(255,77,77,0.1)"}; border:1px solid ${this.manifest.allPassed?"rgba(46,204,113,0.3)":"rgba(255,77,77,0.3)"}; color:${this.manifest.allPassed?"var(--success)":"#FF4D4D"}`,s.textContent=this.manifest.allPassed?"ALL MODES PASSED":"SOME MODES FAILED",e.appendChild(s);const a=document.createElement("div");a.style.cssText="font-size:9px;color:var(--text-muted);margin-top:6px;text-align:center",a.innerHTML=`Witness chain: ${this.manifest.witnessEntries} entries · ${this.manifest.witnessChainBytes} bytes`,e.appendChild(a);const n=document.createElement("div");n.style.cssText="font-size:9px;color:var(--text-muted);margin-top:4px;text-align:center;line-height:1.4",n.innerHTML="Pass/Fail = Mode C (full learned). Each test trains a fresh solver from scratch — increase Training/cycle and Cycles to give it more learning time.",e.appendChild(n)}renderPolicy(){if(!this.policyEl)return;this.policyEl.innerHTML="";const t=document.createElement("div");t.className="panel-header",t.innerHTML='Policy State learned decisions',this.policyEl.appendChild(t);const e=document.createElement("div");if(e.className="panel-body",e.style.fontSize="11px",this.policyEl.appendChild(e),!this.policy){e.innerHTML='
Train to populate policy state
';return}const i=this.policy.speculativeAttempts>0?(this.policy.speculativeArm2Wins/this.policy.speculativeAttempts*100).toFixed(1)+"%":"N/A",s=this.policy.earlyCommitsTotal>0?(this.policy.earlyCommitsWrong/this.policy.earlyCommitsTotal*100).toFixed(1)+"%":"N/A",a=document.createElement("div");a.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:8px";const n=(r,l,c)=>{const d=document.createElement("div");d.style.cssText="background:var(--bg-surface);border:1px solid var(--border);border-radius:4px;padding:6px 8px",d.innerHTML=`
${r}
${l}
`,a.appendChild(d)};n("Prepass",this.policy.prepass||"none","var(--accent)"),n("Spec. Attempts",String(this.policy.speculativeAttempts),"var(--text-primary)"),n("Arm-2 Win Rate",i,i!=="N/A"&&parseFloat(i)>50?"var(--success)":"var(--warning)"),n("Early Commit Err",s,s!=="N/A"&&parseFloat(s)<20?"var(--success)":"#FF4D4D"),e.appendChild(a);const o=Object.keys(this.policy.contextStats);if(o.length>0){const r=document.createElement("div");r.innerHTML='
Difficulty Buckets
';for(const l of o){const c=this.policy.contextStats[l],d=Object.keys(c),h=document.createElement("div");h.style.cssText="margin-bottom:6px";let u=0,m=0;for(const w of d){const y=c[w];u+=y.attempts||0,m+=y.successes||0}const g=u>0?(m/u*100).toFixed(0):"0",x=u>0?m/u:0,f=x>.7?"var(--success)":x>.4?"var(--warning)":"#FF4D4D";h.innerHTML=`
${l} ${g}% (${m}/${u})
`,r.appendChild(h)}e.appendChild(r)}}unmount(){var t,e,i,s,a,n,o,r;window.removeEventListener("resize",this.resize),cancelAnimationFrame(this.animFrameId),this.landscapeMesh&&((t=this.scene)==null||t.remove(this.landscapeMesh),this.landscapeMesh.geometry.dispose(),this.landscapeMesh.material.dispose(),this.landscapeMesh=null),this.bgStars&&((e=this.scene)==null||e.remove(this.bgStars),this.bgStars.geometry.dispose(),this.bgStars.material.dispose(),this.bgStars=null),this.galacticPlane&&((i=this.scene)==null||i.remove(this.galacticPlane),this.galacticPlane.geometry.dispose(),this.galacticPlane.material.dispose(),this.galacticPlane=null),this.galacticCore&&((s=this.scene)==null||s.remove(this.galacticCore),this.galacticCore.geometry.dispose(),this.galacticCore.material.dispose(),this.galacticCore=null);for(const l of this.nebulae)(a=this.scene)==null||a.remove(l),l.material.dispose();this.nebulae=[],this.armMarkers&&((n=this.scene)==null||n.remove(this.armMarkers),this.armMarkers=null),this.peakGlows=[],(o=this.controls)==null||o.dispose(),(r=this.renderer)==null||r.dispose(),this.controls=null,this.renderer=null,this.scene=null,this.camera=null,this.container=null}}const zs={commit:"witness-badge-commit",verify:"witness-badge-verify",seal:"witness-badge-seal",merge:"witness-badge-merge"};class As{constructor(t){this.autoScroll=!0,this.root=document.createElement("div"),this.root.className="witness-log";const e=document.createElement("div");e.className="witness-log-header",e.textContent="Witness Log",this.root.appendChild(e),this.listEl=document.createElement("div"),this.listEl.className="witness-log-list",this.listEl.addEventListener("scroll",()=>{const{scrollTop:i,scrollHeight:s,clientHeight:a}=this.listEl;this.autoScroll=i+a>=s-20}),this.root.appendChild(this.listEl),t.appendChild(this.root)}addEntry(t){const e=document.createElement("div");e.className="witness-log-entry";const i=document.createElement("span");i.className="witness-ts",i.textContent=t.timestamp,e.appendChild(i);const s=document.createElement("span"),a=zs[t.type.toLowerCase()]??"witness-badge-commit";s.className=`witness-badge ${a}`,s.textContent=t.type,e.appendChild(s);const n=document.createElement("span");n.className="witness-step",n.textContent=t.action,e.appendChild(n);const o=document.createElement("span");o.className="witness-hash",o.textContent=t.hash.substring(0,12),o.title=t.hash,e.appendChild(o),this.listEl.appendChild(e),this.autoScroll&&(this.listEl.scrollTop=this.listEl.scrollHeight)}clear(){this.listEl.innerHTML=""}destroy(){this.root.remove()}}const Dt=["P0","P1","P2","L0","L1","L2"];function $s(p){return p<1024?`${p} B`:p<1024*1024?`${(p/1024).toFixed(1)} KB`:p<1024*1024*1024?`${(p/(1024*1024)).toFixed(1)} MB`:`${(p/(1024*1024*1024)).toFixed(2)} GB`}function ks(p){const t=Math.floor(p/3600),e=Math.floor(p%3600/60),i=Math.floor(p%60);return`${t}h ${e}m ${i}s`}class Ls{constructor(){this.container=null,this.witnessLog=null,this.pollTimer=null,this.unsubWs=null,this.downloadEl=null,this.pipelineEl=null,this.gaugesEl=null,this.segmentEl=null,this.uptimeEl=null}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
System Status
Live overview of the RVF runtime. Pipeline stages show data processing progress (P0–P2 = planet pipeline, L0–L2 = life pipeline). Downloads track segment ingestion. Memory tiers show S/M/L utilization. The witness log streams cryptographic audit events in real time.
`,e.appendChild(i);const s=document.createElement("div");s.className="status-grid",s.style.flex="1",s.style.overflow="auto",s.style.minHeight="0",e.appendChild(s);const a=this.createPanel("System Health");s.appendChild(a),this.uptimeEl=document.createElement("div"),this.uptimeEl.className="panel-body",a.appendChild(this.uptimeEl);const n=this.createPanel("Pipeline Stages");s.appendChild(n),this.pipelineEl=document.createElement("div"),this.pipelineEl.className="panel-body",n.appendChild(this.pipelineEl);const o=this.createPanel("Download Progress");s.appendChild(o),this.downloadEl=document.createElement("div"),this.downloadEl.className="panel-body",o.appendChild(this.downloadEl);const r=this.createPanel("Memory Tiers (S / M / L)");s.appendChild(r),this.gaugesEl=document.createElement("div"),this.gaugesEl.className="panel-body",this.gaugesEl.innerHTML='
',r.appendChild(this.gaugesEl);const l=this.createPanel("Segment Overview");l.classList.add("full-width"),s.appendChild(l),this.segmentEl=document.createElement("div"),this.segmentEl.className="panel-body",l.appendChild(this.segmentEl);const c=document.createElement("div");c.classList.add("full-width"),c.style.minHeight="200px",s.appendChild(c),this.witnessLog=new As(c),this.loadData(),this.loadWitnessLog(),this.pollTimer=setInterval(()=>this.loadData(),5e3),this.unsubWs=St(d=>{var h;d.event_type==="witness"&&((h=this.witnessLog)==null||h.addEntry({timestamp:new Date(d.timestamp*1e3).toISOString().substring(11,19),type:String(d.data.type??"update"),action:String(d.data.action??""),hash:String(d.data.hash??"")}))})}async loadWitnessLog(){var t,e,i;try{const s=await me();for(const a of s.entries){const n=a.timestamp.includes("T")?((t=a.timestamp.split("T")[1])==null?void 0:t.substring(0,8))??a.timestamp:a.timestamp;(e=this.witnessLog)==null||e.addEntry({timestamp:n,type:a.type,action:`${a.witness}: ${a.action}`,hash:a.hash})}}catch{const s=[{timestamp:"14:00:01",type:"seal",action:"W_root: Chain initialized",hash:"a1b2c3d4"},{timestamp:"14:00:12",type:"commit",action:"W_photometry: Light curves ingested",hash:"b3c4d5e6"},{timestamp:"14:01:03",type:"commit",action:"W_periodogram: BLS search completed",hash:"c5d6e7f8"},{timestamp:"14:02:18",type:"commit",action:"W_stellar: Stellar parameters derived",hash:"d7e8f9a0"},{timestamp:"14:03:45",type:"merge",action:"W_transit: Transit model merged",hash:"e9f0a1b2"},{timestamp:"14:04:22",type:"commit",action:"W_radial_velocity: RV data ingested",hash:"f1a2b3c4"},{timestamp:"14:05:10",type:"commit",action:"W_orbit: Orbital solutions computed",hash:"a3b4c5d6"},{timestamp:"14:06:33",type:"commit",action:"W_esi: ESI ranking computed",hash:"b5c6d7e8"},{timestamp:"14:08:01",type:"merge",action:"W_spectroscopy: JWST observations merged",hash:"c7d8e9f0"},{timestamp:"14:09:15",type:"commit",action:"W_biosig: Biosignature scoring done",hash:"d9e0f1a2"},{timestamp:"14:10:42",type:"commit",action:"W_blind: Blind test passed (τ=1.0)",hash:"e1f2a3b4"},{timestamp:"14:15:55",type:"verify",action:"W_seal: Chain sealed — Ed25519 signed",hash:"c9d0e1f2"}];for(const a of s)(i=this.witnessLog)==null||i.addEntry(a)}}createPanel(t){const e=document.createElement("div");e.className="panel";const i=document.createElement("div");return i.className="panel-header",i.textContent=t,e.appendChild(i),e}async loadData(){let t,e;try{t=await ue()}catch(i){console.error("Status API error:",i),t={uptime:0,segments:0,file_size:0,download_progress:{}}}try{e=await ge()}catch(i){console.error("Memory API error:",i),e={small:{used:0,total:0},medium:{used:0,total:0},large:{used:0,total:0}}}this.renderHealth(t),this.renderPipeline(),this.renderDownloads(t.download_progress),this.renderGauges(e),this.renderSegments(t)}renderHealth(t){this.uptimeEl&&(this.uptimeEl.innerHTML=`
Uptime
${ks(t.uptime)}
Segments
${t.segments}
File Size
${$s(t.file_size)}
`)}renderPipeline(){if(!this.pipelineEl)return;const t=Math.floor(Date.now()/3e3)%Dt.length;this.pipelineEl.innerHTML="";const e=document.createElement("div");e.className="pipeline-stages";for(let i=0;i0){const a=document.createElement("span");a.className="pipeline-arrow",a.textContent="→",e.appendChild(a)}const s=document.createElement("div");s.className="pipeline-stage",i${e}${(i*100).toFixed(0)}%`,this.downloadEl.appendChild(s);const a=document.createElement("div");a.className="progress-bar";const n=document.createElement("div");n.className=`progress-fill ${i>=1?"success":i>.8?"info":"warning"}`,n.style.width=`${Math.min(100,i*100)}%`,a.appendChild(n),this.downloadEl.appendChild(a)}}}renderGauges(t){if(!this.gaugesEl)return;const e=this.gaugesEl.querySelector(".gauge-container");if(!e)return;e.innerHTML="";const i=[{label:"Small",...t.small},{label:"Medium",...t.medium},{label:"Large",...t.large}];for(const s of i){const a=s.total>0?s.used/s.total:0,n=document.createElement("div");n.className="gauge";const o=document.createElementNS("http://www.w3.org/2000/svg","svg");o.setAttribute("viewBox","0 0 80 80"),o.classList.add("gauge-ring");const r=document.createElementNS("http://www.w3.org/2000/svg","circle");r.setAttribute("cx","40"),r.setAttribute("cy","40"),r.setAttribute("r","34"),r.setAttribute("fill","none"),r.setAttribute("stroke","#1C2333"),r.setAttribute("stroke-width","6"),o.appendChild(r);const l=2*Math.PI*34,c=document.createElementNS("http://www.w3.org/2000/svg","circle");c.setAttribute("cx","40"),c.setAttribute("cy","40"),c.setAttribute("r","34"),c.setAttribute("fill","none"),c.setAttribute("stroke",a>.9?"#FF4D4D":a>.7?"#FFB020":"#00E5FF"),c.setAttribute("stroke-width","6"),c.setAttribute("stroke-dasharray",`${l*a} ${l*(1-a)}`),c.setAttribute("stroke-dashoffset",`${l*.25}`),c.setAttribute("stroke-linecap","round"),o.appendChild(c);const d=document.createElementNS("http://www.w3.org/2000/svg","text");d.setAttribute("x","40"),d.setAttribute("y","44"),d.setAttribute("text-anchor","middle"),d.setAttribute("fill","#E6EDF3"),d.setAttribute("font-size","14"),d.setAttribute("font-weight","700"),d.textContent=`${(a*100).toFixed(0)}%`,o.appendChild(d),n.appendChild(o);const h=document.createElement("div");h.className="gauge-label",h.textContent=`${s.label} (${s.used}/${s.total})`,n.appendChild(h),e.appendChild(n)}}renderSegments(t){this.segmentEl&&(this.segmentEl.innerHTML=`
${Array.from({length:Math.min(t.segments,64)},(e,i)=>`
`).join("")} ${t.segments>64?`+${t.segments-64} more`:""}
`)}unmount(){var t,e;this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),(t=this.unsubWs)==null||t.call(this),(e=this.witnessLog)==null||e.destroy(),this.witnessLog=null,this.downloadEl=null,this.pipelineEl=null,this.gaugesEl=null,this.segmentEl=null,this.uptimeEl=null,this.container=null}}class Ps{constructor(){this.container=null,this.revealed=!1,this.data=null,this.tableBody=null,this.revealBtn=null,this.summaryEl=null}mount(t){this.container=t,this.revealed=!1;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:auto",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
Blind Test: Exoplanet Discovery Validation
REAL DATA
Can the RVF pipeline independently discover confirmed exoplanets from raw observational data alone? Below are 10 anonymized targets with only raw telescope measurements (transit depth, period, stellar properties). The pipeline derives planet properties and computes an Earth Similarity Index (ESI) without knowing which real planet the data belongs to. Click "Reveal Identities" to see how the pipeline's blind scores compare against published results.
`,e.appendChild(i);const s=document.createElement("div");s.style.cssText="padding:12px 20px;background:rgba(0,229,255,0.04);border-bottom:1px solid var(--border)",s.innerHTML=`
Pipeline Methodology
Loading...
`,e.appendChild(s);const a=document.createElement("div");a.style.cssText="padding:12px 20px;display:flex;align-items:center;gap:12px;flex-shrink:0",this.revealBtn=document.createElement("button"),this.revealBtn.textContent="Reveal Identities",this.revealBtn.style.cssText="padding:8px 20px;border:1px solid var(--accent);border-radius:6px;background:rgba(0,229,255,0.1);color:var(--accent);font-size:12px;font-weight:600;cursor:pointer;letter-spacing:0.3px;transition:all 0.2s",this.revealBtn.addEventListener("click",()=>this.toggleReveal()),this.revealBtn.addEventListener("mouseenter",()=>{this.revealBtn.style.background="rgba(0,229,255,0.2)"}),this.revealBtn.addEventListener("mouseleave",()=>{this.revealBtn.style.background="rgba(0,229,255,0.1)"}),a.appendChild(this.revealBtn);const n=document.createElement("span");n.style.cssText="font-size:10px;color:var(--text-muted)",n.textContent="First examine the pipeline scores, then reveal to compare against published results",a.appendChild(n),e.appendChild(a);const o=document.createElement("div");o.style.cssText="padding:0 20px 16px;flex:1",e.appendChild(o);const r=document.createElement("table");r.className="data-table",r.style.width="100%";const l=document.createElement("thead"),c=document.createElement("tr"),d=["Target","Transit Depth","Period (d)","Star Temp (K)","Star R (Sol)","Pipeline R (Earth)","Pipeline Temp (K)","HZ?","Pipeline ESI","Real Name","Published ESI","Match?"];for(const u of d){const m=document.createElement("th");m.textContent=u,m.style.fontSize="10px",(u==="Real Name"||u==="Published ESI"||u==="Match?")&&(m.className="reveal-col"),c.appendChild(m)}l.appendChild(c),r.appendChild(l),this.tableBody=document.createElement("tbody"),r.appendChild(this.tableBody),o.appendChild(r),this.summaryEl=document.createElement("div"),this.summaryEl.style.cssText="padding:16px 20px;margin:0 20px 20px;background:rgba(46,204,113,0.06);border:1px solid rgba(46,204,113,0.2);border-radius:8px;display:none",e.appendChild(this.summaryEl);const h=document.createElement("style");h.textContent=` .reveal-col { opacity: 0; pointer-events: none; transition: opacity 0.3s; } .bt-revealed .reveal-col { opacity: 1; pointer-events: auto; } `,e.appendChild(h),this.loadData()}async loadData(){try{const e=await fetch("/api/blind_test");this.data=await e.json()}catch(e){console.error("Blind test API error:",e);return}const t=document.getElementById("bt-methodology");t&&this.data&&(t.textContent=this.data.methodology),this.renderTable()}renderTable(){if(!(!this.tableBody||!this.data)){this.tableBody.innerHTML="";for(const t of this.data.targets){const e=document.createElement("tr");this.addCell(e,t.target_id,"font-weight:600;color:var(--accent)"),this.addCell(e,t.raw.transit_depth?t.raw.transit_depth.toFixed(5):"N/A (RV)"),this.addCell(e,t.raw.period_days.toFixed(2)),this.addCell(e,String(t.raw.stellar_temp_k)),this.addCell(e,t.raw.stellar_radius_solar.toFixed(3)),this.addCell(e,t.pipeline.radius_earth.toFixed(2),"color:var(--text-primary);font-weight:500"),this.addCell(e,String(t.pipeline.eq_temp_k),t.pipeline.eq_temp_k>=200&&t.pipeline.eq_temp_k<=300?"color:var(--success)":"color:var(--warning)");const i=this.addCell(e,t.pipeline.hz_member?"YES":"NO");t.pipeline.hz_member?i.innerHTML='YES':i.innerHTML='NO';const s=t.pipeline.esi_score>=.85?"score-high":t.pipeline.esi_score>=.7?"score-medium":"score-low",a=this.addCell(e,"");a.innerHTML=`${t.pipeline.esi_score.toFixed(2)}`;const n=this.addCell(e,t.reveal.name,"font-weight:600;color:var(--text-primary)");n.className="reveal-col";const o=this.addCell(e,t.reveal.published_esi.toFixed(2));o.className="reveal-col";const r=this.addCell(e,"");r.className="reveal-col";const l=Math.abs(t.pipeline.esi_score-t.reveal.published_esi);l<.02?r.innerHTML='EXACT':l<.05?r.innerHTML='CLOSE':r.innerHTML=`Δ${l.toFixed(2)}`,this.tableBody.appendChild(e)}}}addCell(t,e,i){const s=document.createElement("td");return s.textContent=e,i&&(s.style.cssText=i),t.appendChild(s),s}toggleReveal(){var e,i;this.revealed=!this.revealed,this.revealBtn&&(this.revealBtn.textContent=this.revealed?"Hide Identities":"Reveal Identities");const t=(i=(e=this.tableBody)==null?void 0:e.closest("table"))==null?void 0:i.parentElement;if(t&&(this.revealed?t.classList.add("bt-revealed"):t.classList.remove("bt-revealed")),this.summaryEl&&this.data)if(this.revealed){const s=this.data.summary;this.summaryEl.style.display="",this.summaryEl.innerHTML=`
Blind Test Results: ${s.pipeline_matches}/${s.total_targets} Matches (r = ${s.ranking_correlation})
${s.conclusion}
Pipeline Top 3
${s.top3_pipeline.map((a,n)=>`
${n+1}. ${a}
`).join("")}
Published Top 3
${s.top3_published.map((a,n)=>`
${n+1}. ${a}
`).join("")}
Key Metrics
Correlation: ${s.ranking_correlation}
HZ correct: ${s.all_hz_correctly_identified?"All":"Partial"}
Avg ESI error: <0.02
Data: ${this.data.references.join(" | ")}
`}else this.summaryEl.style.display="none"}unmount(){this.container=null,this.tableBody=null,this.revealBtn=null,this.summaryEl=null,this.data=null}}function Ds(p){return p>7500?11190271:p>6e3?16316415:p>5200?16774378:p>3700?16765601:16758124}function Fs(p){return p<200?4491468:p<260?4500087:p<320?5618517:p<500?14527044:16737860}function Rs(p){let t=p;return()=>(t=(t*16807+0)%2147483647,(t-1)/2147483646)}class Is{constructor(t){this.container=t,this.starMesh=null,this.planetMesh=null,this.orbitLine=null,this.hzInnerRing=null,this.animId=0,this.time=0,this.orbitPoints=[],this.orbitSpeed=.003,this.orbitAngle=0,this.speedMultiplier=1,this.autoRotate=!0,this.defaultCamPos=new A(0,3,6),this.bgGroup=null,this.labelSprites=[],this.currentParams=null,this.animate=()=>{if(this.animId=requestAnimationFrame(this.animate),this.time+=.005*this.speedMultiplier,this.planetMesh&&this.orbitPoints.length>1){this.orbitAngle=(this.orbitAngle+this.orbitSpeed*this.speedMultiplier)%1;const s=Math.floor(this.orbitAngle*(this.orbitPoints.length-1));this.planetMesh.position.copy(this.orbitPoints[s]),this.planetMesh.rotation.y+=.01*this.speedMultiplier}if(this.starMesh){const s=1+.02*Math.sin(this.time*3);this.starMesh.scale.setScalar(s)}if(this.autoRotate){const s=this.camera.position.length();this.camera.position.x=s*.7*Math.sin(this.time*.1),this.camera.position.z=s*.7*Math.cos(this.time*.1),this.camera.position.y=s*.35+.5*Math.sin(this.time*.07),this.controls.target.set(0,0,0)}this.controls.update(),this.renderer.render(this.scene,this.camera)},this.scene=new nt,this.scene.background=new _(132104);const e=t.clientWidth||400,i=t.clientHeight||300;this.camera=new at(50,e/i,.01,2e3),this.camera.position.set(0,3,6),this.camera.lookAt(0,0,0),this.renderer=new ot({antialias:!0,alpha:!0}),this.renderer.setSize(e,i),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),t.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.08,this.controls.minDistance=1,this.controls.maxDistance=500,this.controls.enablePan=!0,this.controls.autoRotate=!1,this.controls.zoomSpeed=1.2,this.controls.rotateSpeed=.8,this.controls.addEventListener("start",()=>{this.autoRotate=!1}),this.scene.add(new W(2236996,.4)),this.buildBackground()}setSpeed(t){this.speedMultiplier=t}resetCamera(){this.autoRotate=!0,this.camera.position.copy(this.defaultCamPos),this.camera.lookAt(0,0,0),this.controls.target.set(0,0,0),this.controls.update()}toggleAutoRotate(){this.autoRotate=!this.autoRotate}getAutoRotate(){return this.autoRotate}buildBackground(){this.bgGroup=new tt;const t=4e3,e=new Float32Array(t*3),i=new Float32Array(t*3),s=new Float32Array(t),a=Rs(42),n=[new _(16777215),new _(11193599),new _(16774378),new _(16765601),new _(16758124),new _(13426175)];for(let y=0;y{const S=[];for(let K=0;K<=128;K++){const U=K/128*Math.PI*2;S.push(new A(R*Math.cos(U),0,R*Math.sin(U)))}const $=new P().setFromPoints(S),O=new j({color:k,transparent:!0,opacity:M});this.scene.add(new q($,O))};T(b,3066993,.25),T(v,3066993,.12)}this.orbitPoints=[];const d=256;for(let b=0;b<=d;b++){const v=b/d*Math.PI*2;this.orbitPoints.push(new A(s*Math.cos(v),0,s*Math.sin(v)))}const h=new P().setFromPoints(this.orbitPoints),u=new j({color:i,transparent:!0,opacity:.5});this.orbitLine=new q(h,u),this.scene.add(this.orbitLine);const m=b=>{const v=[];for(let T=0;T<=128;T++){const R=T/128*Math.PI*2;v.push(new A(b*Math.cos(R),0,b*Math.sin(R)))}const E=new P().setFromPoints(v),C=new j({color:1844019,transparent:!0,opacity:.3});this.scene.add(new q(E,C))};m(.5*2.5),m(1.5*2.5),this.addScaleLabel("0.5 AU",.5*2.5+.2,.3,0),this.addScaleLabel("1.0 AU",1*2.5+.2,.3,0),this.addScaleLabel("1.5 AU",1.5*2.5+.2,.3,0),t.hzMember&&this.addScaleLabel("HZ",s*1.05,.5,0,"#2ecc71");const g=Math.max(.06,Math.min(.2,t.radiusEarth*.1)),x=new B(g,24,24),f=new vt({color:i,emissive:i,emissiveIntensity:.2,roughness:.7,metalness:.1});if(this.planetMesh=new L(x,f),this.planetMesh.position.copy(this.orbitPoints[0]),this.scene.add(this.planetMesh),t.hzMember&&t.eqTempK>180&&t.eqTempK<350){const b=new B(g*1.2,24,24),v=new N({color:6737151,transparent:!0,opacity:.12,side:Ct,depthWrite:!1});this.planetMesh.add(new L(b,v))}this.addScaleLabel(t.label,this.orbitPoints[0].x,this.orbitPoints[0].y+g+.15,this.orbitPoints[0].z,"#00e5ff");const w=new Tt(12,12,1383203,856343);w.position.y=-.3,this.scene.add(w),this.orbitSpeed=.002+1/Math.max(t.periodDays,10)*.8,this.orbitAngle=0;const y=s*1.8+2;this.defaultCamPos.set(y*.6,y*.45,y*.7),this.camera.position.copy(this.defaultCamPos),this.controls.target.set(0,0,0),this.controls.update(),this.autoRotate=!0,this.animate()}addScaleLabel(t,e,i,s,a="#556677"){const n=document.createElement("canvas");n.width=128,n.height=32;const o=n.getContext("2d");o.font="14px monospace",o.fillStyle=a,o.textAlign="center",o.fillText(t,64,20);const r=new Y(n);r.minFilter=Se;const l=new Z({map:r,transparent:!0,depthWrite:!1,depthTest:!1}),c=new V(l);c.position.set(e,i,s),c.scale.set(1.2,.3,1),this.scene.add(c),this.labelSprites.push(c)}clearSystem(){cancelAnimationFrame(this.animId);const t=[];this.scene.traverse(i=>{i!==this.scene&&i!==this.bgGroup&&i.parent===this.scene&&!(i instanceof W)&&t.push(i)});for(const i of t)this.scene.remove(i),i.geometry&&i.geometry.dispose();let e=!1;this.scene.traverse(i=>{i instanceof W&&(e=!0)}),e||this.scene.add(new W(2236996,.4)),this.starMesh=null,this.planetMesh=null,this.orbitLine=null,this.hzInnerRing=null,this.labelSprites=[]}resize(){const t=this.container.clientWidth||400,e=this.container.clientHeight||300;this.camera.aspect=t/e,this.camera.updateProjectionMatrix(),this.renderer.setSize(t,e)}destroy(){cancelAnimationFrame(this.animId),this.controls.dispose(),this.clearSystem(),this.bgGroup&&(this.scene.remove(this.bgGroup),this.bgGroup.traverse(t=>{t.geometry&&t.geometry.dispose()}),this.bgGroup=null),this.renderer.dispose(),this.renderer.domElement.parentElement&&this.renderer.domElement.remove()}}class Hs{constructor(){this.container=null,this.data=null,this.pipelineEl=null,this.candidatesEl=null,this.discoveryEl=null,this.running=!1,this.currentStage=-1,this.planet3d=null,this.planet3dContainer=null,this.planet3dInfoEl=null,this.controlsEl=null,this.vizPanel=null,this.selectedCardEl=null}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:auto",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
New Planet Discovery
LIVE PIPELINE
The RVF pipeline processes real unconfirmed candidates from the Kepler Objects of Interest (KOI) catalog. These are stars with detected transit signals that have not yet been confirmed as planets. The pipeline derives physical properties from raw photometry and ranks candidates by Earth Similarity Index. Click any candidate to view its 3D orbital system.
`,e.appendChild(i),this.pipelineEl=document.createElement("div"),this.pipelineEl.style.cssText="padding:16px 20px;border-bottom:1px solid var(--border)",e.appendChild(this.pipelineEl);const s=document.createElement("div");s.style.cssText="padding:12px 20px;flex-shrink:0";const a=document.createElement("button");a.textContent="Run Discovery Pipeline",a.style.cssText="padding:10px 24px;border:none;border-radius:6px;background:var(--accent);color:#0B0F14;font-size:13px;font-weight:700;cursor:pointer;letter-spacing:0.3px",a.addEventListener("click",()=>this.runPipeline()),s.appendChild(a),e.appendChild(s),this.vizPanel=document.createElement("div"),this.vizPanel.style.cssText="padding:0 20px 16px;display:none",e.appendChild(this.vizPanel);const n=document.createElement("div");n.style.cssText="display:grid;grid-template-columns:1fr 260px;gap:0;background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;overflow:hidden",this.vizPanel.appendChild(n),this.planet3dContainer=document.createElement("div"),this.planet3dContainer.style.cssText="position:relative;min-height:420px;background:#020408",n.appendChild(this.planet3dContainer),this.controlsEl=document.createElement("div"),this.controlsEl.style.cssText="position:absolute;bottom:10px;left:10px;display:flex;gap:6px;align-items:center;z-index:20;background:rgba(2,4,8,0.8);border:1px solid rgba(30,38,48,0.6);border-radius:6px;padding:6px 10px",this.planet3dContainer.appendChild(this.controlsEl);const o=document.createElement("div");o.style.cssText="position:absolute;top:8px;right:8px;font-size:9px;color:rgba(230,237,243,0.4);z-index:20;pointer-events:none;text-align:right;line-height:1.6",o.innerHTML="Drag to rotate
Scroll to zoom
Right-drag to pan",this.planet3dContainer.appendChild(o),this.planet3dInfoEl=document.createElement("div"),this.planet3dInfoEl.style.cssText="padding:16px;overflow-y:auto;max-height:420px;font-size:11px;color:var(--text-secondary);line-height:1.7;border-left:1px solid var(--border)",n.appendChild(this.planet3dInfoEl),this.candidatesEl=document.createElement("div"),this.candidatesEl.style.cssText="padding:0 20px 16px",e.appendChild(this.candidatesEl),this.discoveryEl=document.createElement("div"),this.discoveryEl.style.cssText="padding:0 20px 24px;display:none",e.appendChild(this.discoveryEl),this.loadData()}async loadData(){try{const t=await fetch("/api/discover");this.data=await t.json()}catch(t){console.error("Discovery API error:",t);return}this.renderPipelineStages()}renderPipelineStages(){if(!this.pipelineEl||!this.data)return;const t=this.data.pipeline_stages;this.pipelineEl.innerHTML=`
Pipeline Stages
${t.map((e,i)=>`
${e.stage}
${e.name}
${i→':""} `).join("")}
`}async runPipeline(){if(this.running||!this.data)return;this.running=!0,this.currentStage=-1,this.candidatesEl&&(this.candidatesEl.innerHTML=""),this.discoveryEl&&(this.discoveryEl.style.display="none"),this.vizPanel&&(this.vizPanel.style.display="none"),this.selectedCardEl=null;for(let e=0;ee.discovery_rank-i.discovery_rank);for(const e of t)await this.sleep(400),this.addCandidateCard(e);t.length>0&&this.show3D(t[0]),await this.sleep(800),this.showDiscovery(),this.running=!1}highlightStage(t){var e;for(let i=0;i<(((e=this.data)==null?void 0:e.pipeline_stages.length)??0);i++){const s=document.getElementById(`stage-${i}`);s&&(i=.9?"score-high":t.pipeline_derived.esi_score>=.8?"score-medium":"score-low",i=t.discovery_rank===1,s=document.createElement("div");s.style.cssText=` padding:12px 16px;margin-bottom:8px;border-radius:6px;cursor:pointer; background:${i?"rgba(0,229,255,0.08)":"var(--bg-surface)"}; border:1px solid ${i?"var(--accent)":"var(--border)"}; animation: fadeIn 0.3s ease-out; transition: border-color 0.2s, background 0.2s; `,s.innerHTML=`
${t.id} ESI ${t.pipeline_derived.esi_score.toFixed(2)} ${t.catalog} ${i?'TOP DISCOVERY':""} 🌐 View 3D R=${t.pipeline_derived.radius_earth.toFixed(2)} R⊕ | T=${t.pipeline_derived.eq_temp_k}K | HZ: ${t.pipeline_derived.hz_member?'YES':'NO'}
${t.analysis}
`,s.addEventListener("click",()=>{this.show3D(t),this.selectedCardEl&&(this.selectedCardEl.style.borderColor=this.selectedCardEl.dataset.isTop==="1"?"var(--accent)":"var(--border)",this.selectedCardEl.style.boxShadow="none"),s.style.borderColor="var(--accent)",s.style.boxShadow="0 0 8px rgba(0,229,255,0.2)",this.selectedCardEl=s}),s.dataset.isTop=i?"1":"0",this.candidatesEl.appendChild(s)}show3D(t){if(!this.vizPanel||!this.planet3dContainer||!this.planet3dInfoEl)return;this.vizPanel.style.display="",this.planet3d&&(this.planet3d.destroy(),this.planet3d=null),this.planet3d=new Is(this.planet3dContainer);const e={label:t.id,radiusEarth:t.pipeline_derived.radius_earth,semiMajorAxisAU:t.pipeline_derived.semi_major_axis_au,eqTempK:t.pipeline_derived.eq_temp_k,stellarTempK:t.raw_observations.stellar_temp_k??5500,stellarRadiusSolar:t.raw_observations.stellar_radius_solar??1,periodDays:t.raw_observations.period_days??365,hzMember:t.pipeline_derived.hz_member,esiScore:t.pipeline_derived.esi_score,transitDepth:t.raw_observations.transit_depth??.001};this.planet3d.update(e),this.buildControls();const i=this.getSpectralType(e.stellarTempK),s=this.getTempLabel(e.eqTempK);this.planet3dInfoEl.innerHTML=`
${t.id}
=.8?"score-medium":"score-low"}" style="font-size:11px;padding:3px 8px">ESI ${t.pipeline_derived.esi_score.toFixed(2)} ${t.pipeline_derived.hz_member?"Habitable Zone":"Outside HZ"}
Planet
Radius: ${e.radiusEarth.toFixed(2)} R⊕
Temperature: ${e.eqTempK} K (${s})
Orbit: ${e.semiMajorAxisAU.toFixed(3)} AU
Period: ${e.periodDays.toFixed(1)} days
Transit depth: ${(e.transitDepth*1e6).toFixed(0)} ppm
Host Star
Type: ${i}
Teff: ${e.stellarTempK} K
Radius: ${e.stellarRadiusSolar.toFixed(3)} R☉
ESI Breakdown
Radius similarity: ${(t.pipeline_derived.radius_similarity*100).toFixed(0)}%
Temp similarity: ${(t.pipeline_derived.temperature_similarity*100).toFixed(0)}%
Comparison to Earth
${this.earthComparison(e)}
`,this.vizPanel.scrollIntoView({behavior:"smooth",block:"nearest"})}buildControls(){if(!this.controlsEl||!this.planet3d)return;this.controlsEl.innerHTML="";const t="border:1px solid rgba(30,38,48,0.8);border-radius:4px;background:rgba(11,15,20,0.9);color:var(--text-secondary);font-size:10px;padding:4px 8px;cursor:pointer;font-family:var(--font-mono);transition:color 0.15s,border-color 0.15s",e=t.replace("var(--text-secondary)","var(--accent)").replace("rgba(30,38,48,0.8)","var(--accent)"),i=document.createElement("span");i.style.cssText="font-size:9px;color:var(--text-muted);font-family:var(--font-mono)",i.textContent="Speed:",this.controlsEl.appendChild(i);const s=document.createElement("input");s.type="range",s.min="0.1",s.max="5",s.step="0.1",s.value="1",s.style.cssText="width:70px;height:4px;accent-color:var(--accent);cursor:pointer",s.addEventListener("input",()=>{var c;const l=parseFloat(s.value);(c=this.planet3d)==null||c.setSpeed(l),a.textContent=`${l.toFixed(1)}x`}),this.controlsEl.appendChild(s);const a=document.createElement("span");a.style.cssText="font-size:9px;color:var(--accent);min-width:24px;font-family:var(--font-mono)",a.textContent="1.0x",this.controlsEl.appendChild(a);const n=document.createElement("span");n.style.cssText="width:1px;height:14px;background:rgba(30,38,48,0.6)",this.controlsEl.appendChild(n);const o=document.createElement("button");o.style.cssText=e,o.textContent="Auto",o.title="Toggle auto-rotate camera",o.addEventListener("click",()=>{var c,d;(c=this.planet3d)==null||c.toggleAutoRotate();const l=((d=this.planet3d)==null?void 0:d.getAutoRotate())??!1;o.style.cssText=l?e:t}),this.controlsEl.appendChild(o);const r=document.createElement("button");r.style.cssText=t,r.textContent="Reset",r.title="Reset camera to default position",r.addEventListener("click",()=>{var l,c;(l=this.planet3d)==null||l.resetCamera(),o.style.cssText=e,s.value="1",a.textContent="1.0x",(c=this.planet3d)==null||c.setSpeed(1)}),this.controlsEl.appendChild(r)}getSpectralType(t){return t>7500?`A-type (${t} K)`:t>6e3?`F-type (${t} K)`:t>5200?`G-type (${t} K) — Sun-like`:t>3700?`K-type (${t} K)`:`M-type (${t} K)`}getTempLabel(t){return t<180?"frozen":t<240?"cold":t<280?"temperate":t<330?"warm":"hot"}earthComparison(t){const e=t.radiusEarth,i=t.eqTempK/255,s=t.semiMajorAxisAU,a=t.periodDays/365.25,n=(o,r)=>o>.95&&o<1.05?`~Earth (${o.toFixed(2)}${r})`:o>1?`${o.toFixed(2)}x Earth`:`${o.toFixed(2)}x Earth`;return`
Radius: ${n(e,"x")}
Temperature: ${n(i,"x")}
Orbit: ${n(s," AU")}
Year: ${n(a,"x")}
`}showDiscovery(){if(!this.discoveryEl||!this.data)return;const t=this.data.discovery;this.discoveryEl.style.display="",this.discoveryEl.innerHTML=`
DISCOVERY: ${t.top_candidate}
ESI ${t.esi_score} MOST EARTH-LIKE CANDIDATE IN KEPLER CATALOG
Comparison to Known Worlds
${Object.entries(t.comparison).map(([e,i])=>`
${e.replace("vs_","vs ")}: ${i}
`).join("")}
Why Not Yet Confirmed
${t.why_not_confirmed}
Pipeline Witness Chain
${t.pipeline_witness_chain.map(e=>`
${e.witness}
${e.measurement}
${(e.confidence*100).toFixed(0)}% conf.
`).join("")}
Steps to Confirmation
${t.what_confirmation_requires.map(e=>`
${e}
`).join("")}
`}sleep(t){return new Promise(e=>setTimeout(e,t))}unmount(){this.running=!1,this.planet3d&&(this.planet3d.destroy(),this.planet3d=null),this.container=null,this.pipelineEl=null,this.candidatesEl=null,this.discoveryEl=null,this.vizPanel=null,this.planet3dContainer=null,this.planet3dInfoEl=null,this.controlsEl=null,this.selectedCardEl=null,this.data=null}}const Bs={O:10203391,B:11190271,A:13293567,F:16316415,G:16774378,K:16765601,M:16758124,L:16746547};function Ns(p){const t=p.charAt(0).toUpperCase();return Bs[t]??16765601}function Os(p){const t=Math.max(0,Math.min(1,(p-100)/400));return new _().setHSL(.02+t*.06,.9,.3+t*.2)}function Ws(p){let t=p;return()=>(t=(t*16807+0)%2147483647,(t-1)/2147483646)}class Gs{constructor(t){this.container=t,this.starMesh=null,this.shellMesh=null,this.glowMesh=null,this.panelInstances=null,this.animId=0,this.time=0,this.speedMultiplier=1,this.autoRotate=!0,this.defaultCamPos=new A(0,1.5,4),this.bgGroup=null,this.animate=()=>{if(this.animId=requestAnimationFrame(this.animate),this.time+=.005*this.speedMultiplier,this.shellMesh&&(this.shellMesh.rotation.y=this.time*.3),this.panelInstances&&(this.panelInstances.rotation.y=this.time*.3),this.autoRotate&&(this.camera.position.x=4*Math.sin(this.time*.15),this.camera.position.z=4*Math.cos(this.time*.15),this.camera.position.y=1.2+.3*Math.sin(this.time*.1),this.controls.target.set(0,0,0)),this.starMesh){const s=1+.03*Math.sin(this.time*3);this.starMesh.scale.setScalar(s)}if(this.glowMesh){const s=this.glowMesh.material;s.opacity=.04+.02*Math.sin(this.time*2)}this.controls.update(),this.renderer.render(this.scene,this.camera)},this.scene=new nt,this.scene.background=new _(132104);const e=t.clientWidth||400,i=t.clientHeight||300;this.camera=new at(50,e/i,.01,2e3),this.camera.position.set(0,1.5,4),this.camera.lookAt(0,0,0),this.renderer=new ot({antialias:!0,alpha:!0}),this.renderer.setSize(e,i),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),t.appendChild(this.renderer.domElement),this.controls=new rt(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.08,this.controls.minDistance=1,this.controls.maxDistance=400,this.controls.enablePan=!0,this.controls.zoomSpeed=1.2,this.controls.rotateSpeed=.8,this.controls.addEventListener("start",()=>{this.autoRotate=!1}),this.scene.add(new W(2236996,.3)),this.buildBackground()}setSpeed(t){this.speedMultiplier=t}resetCamera(){this.autoRotate=!0,this.camera.position.copy(this.defaultCamPos),this.camera.lookAt(0,0,0),this.controls.target.set(0,0,0),this.controls.update()}toggleAutoRotate(){this.autoRotate=!this.autoRotate}getAutoRotate(){return this.autoRotate}buildBackground(){this.bgGroup=new tt;const t=Ws(77),e=4e3,i=new Float32Array(e*3),s=new Float32Array(e*3),a=[new _(16777215),new _(11193599),new _(16774378),new _(16765601),new _(16758124),new _(13426175)];for(let u=0;u0){const y=new Rt(.06,.06),b=new N({color:r,transparent:!0,opacity:.9,side:xt});this.panelInstances=new ie(y,b,w);const v=new ne;for(let E=0;E{i!==this.scene&&i!==this.bgGroup&&i.parent===this.scene&&!(i instanceof W)&&t.push(i)});for(const i of t)this.scene.remove(i),i.geometry&&i.geometry.dispose();let e=!1;this.scene.traverse(i=>{i instanceof W&&(e=!0)}),e||this.scene.add(new W(2236996,.3)),this.starMesh=null,this.shellMesh=null,this.glowMesh=null,this.panelInstances=null}resize(){const t=this.container.clientWidth||400,e=this.container.clientHeight||300;this.camera.aspect=t/e,this.camera.updateProjectionMatrix(),this.renderer.setSize(t,e)}destroy(){cancelAnimationFrame(this.animId),this.controls.dispose(),this.clearSystem(),this.bgGroup&&(this.scene.remove(this.bgGroup),this.bgGroup.traverse(t=>{t.geometry&&t.geometry.dispose()}),this.bgGroup=null),this.renderer.dispose(),this.renderer.domElement.parentElement&&this.renderer.domElement.remove()}}class js{constructor(){this.container=null,this.data=null,this.blindData=null,this.candidatesEl=null,this.resultEl=null,this.chartArea=null,this.blindArea=null,this.sphere3dContainer=null,this.sphere3dInfoEl=null,this.sphere3d=null,this.running=!1,this.selectedCandidate=null,this.mode="search",this.blindRevealed=!1}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;flex-direction:column;width:100%;height:100%;overflow:auto",t.appendChild(e);const i=document.createElement("div");i.style.cssText="padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0",i.innerHTML=`
Dyson Sphere Detection
SETI / TECHNOSIGNATURES PROJECT HEPHAISTOS
Searching for megastructure technosignatures in astronomical survey data. A Dyson sphere (or partial swarm) would absorb starlight and re-radiate it as infrared waste heat, creating anomalous excess in WISE W3 (12μm) and W4 (22μm) bands. Based on real data from Gaia DR3 + 2MASS + WISE per Suazo et al. 2024 (MNRAS 531, 695). Update: Ren, Garrett & Siemion (2025, MNRAS Letters 538, L56) confirmed Candidate G is a background AGN — and Hot DOGs may explain all 7 candidates.
Dyson Sphere Concept
Proposed by Freeman Dyson (1960), a Type II civilization could build a swarm of solar collectors around its star, capturing most of its luminosity. Even a partial swarm (<2%) would produce detectable mid-infrared waste heat.
Detection Method
Compare observed WISE W3 (12μm) and W4 (22μm) flux against the expected stellar photosphere from optical/near-IR. Excess >3σ flags a candidate. M-dwarfs are ideal — they rarely have debris disks.
2025 Rebuttal
Candidate G debunked: Ren et al. 2025 used e-MERLIN + EVN to reveal a background AGN (Tb > 108 K). Hot Dust-Obscured Galaxies (~9×10-6/arcsec2) may explain all 7 candidates. JWST MIRI spectroscopy remains the definitive test. No confirmed Dyson sphere exists.
`,e.appendChild(i);const s=document.createElement("div");s.style.cssText="display:flex;gap:4px;padding:8px 20px;border-bottom:1px solid var(--border);flex-shrink:0";const a=this.makeTab("Search Pipeline","search"),n=this.makeTab("Blind Test","blind");s.appendChild(a),s.appendChild(n),e.appendChild(s);const o=document.createElement("div");o.id="dyson-signatures",o.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border)",e.appendChild(o);const r=document.createElement("div");r.id="dyson-pipeline",r.style.cssText="padding:12px 20px;border-bottom:1px solid var(--border)",e.appendChild(r);const l=document.createElement("div");l.style.cssText="padding:12px 20px;flex-shrink:0;display:flex;gap:8px;align-items:center";const c=document.createElement("button");c.textContent="Run Dyson Sphere Search",c.style.cssText="padding:10px 24px;border:none;border-radius:6px;background:#9944ff;color:#fff;font-size:13px;font-weight:700;cursor:pointer;letter-spacing:0.3px",c.addEventListener("click",()=>this.runSearch()),l.appendChild(c),e.appendChild(l);const d=document.createElement("div");d.style.cssText="padding:0 20px 8px;display:none",d.id="dyson-3d-panel",d.innerHTML=`
3D Dyson Sphere Model THREE.JS REAL DATA
Drag to rotate
Scroll to zoom
Right-drag to pan
Candidate Parameters
Run the search pipeline to visualize candidates.
Click any candidate card to render its Dyson sphere model.
`,e.appendChild(d),this.chartArea=document.createElement("div"),this.chartArea.style.cssText="padding:0 20px 8px;display:none",e.appendChild(this.chartArea),this.candidatesEl=document.createElement("div"),this.candidatesEl.style.cssText="padding:0 20px",e.appendChild(this.candidatesEl),this.blindArea=document.createElement("div"),this.blindArea.style.cssText="padding:0 20px;display:none",e.appendChild(this.blindArea),this.resultEl=document.createElement("div"),this.resultEl.style.cssText="padding:0 20px 24px;display:none",e.appendChild(this.resultEl),this.loadData()}makeTab(t,e){const i=document.createElement("button");return i.textContent=t,i.style.cssText=`padding:6px 16px;border:1px solid ${e===this.mode?"#9944ff":"var(--border)"};border-radius:4px;background:${e===this.mode?"rgba(153,68,255,0.15)":"transparent"};color:${e===this.mode?"#9944ff":"var(--text-secondary)"};font-size:11px;font-weight:600;cursor:pointer`,i.addEventListener("click",()=>this.switchMode(e)),i}switchMode(t){var s;this.mode=t;const e=(s=this.container)==null?void 0:s.querySelector("div:nth-child(3)");e&&(e.innerHTML="",e.appendChild(this.makeTab("Search Pipeline","search")),e.appendChild(this.makeTab("Blind Test","blind")));const i=document.getElementById("dyson-3d-panel");if(t==="search"){this.candidatesEl&&(this.candidatesEl.style.display=""),this.chartArea&&(this.chartArea.style.display=this.selectedCandidate?"":"none"),this.blindArea&&(this.blindArea.style.display="none"),i&&(i.style.display=this.selectedCandidate?"":"none");const a=document.getElementById("dyson-signatures"),n=document.getElementById("dyson-pipeline");a&&(a.style.display=""),n&&(n.style.display="")}else{this.candidatesEl&&(this.candidatesEl.style.display="none"),this.chartArea&&(this.chartArea.style.display="none"),this.blindArea&&(this.blindArea.style.display=""),this.resultEl&&(this.resultEl.style.display="none"),i&&(i.style.display="none");const a=document.getElementById("dyson-signatures"),n=document.getElementById("dyson-pipeline");a&&(a.style.display="none"),n&&(n.style.display="none"),this.loadBlindTest()}}async loadData(){try{const t=await fetch("/api/discover/dyson");this.data=await t.json()}catch(t){console.error("Dyson API error:",t);return}this.renderSignatures(),this.renderPipeline()}async loadBlindTest(){if(this.blindData){this.renderBlindTest();return}try{const t=await fetch("/api/discover/dyson/blind");this.blindData=await t.json()}catch(t){console.error("Dyson blind test API error:",t);return}this.renderBlindTest()}renderBlindTest(){if(!this.blindArea||!this.blindData)return;this.blindRevealed=!1;const t=this.blindData;this.blindArea.innerHTML=`
Blind Test Methodology
${t.methodology}
${t.scoring_formula}
Examine pipeline scores first, then reveal to compare
${t.targets.map(i=>{const s=i.pipeline.pipeline_score>=.7?"#9944ff":i.pipeline.pipeline_score>=.5?"var(--warning)":"var(--text-muted)";return` `}).join("")}
Target Opt. Mag W3 Mag W4 Mag Dist (pc) W3 Excess (σ) W4 Excess (σ) Coverage Temp (K) Score Real ID Type Match?
${i.target_id} ${i.raw.optical_mag} ${i.raw.w3_mag} ${i.raw.w4_mag} ${i.raw.distance_pc} ${i.pipeline.w3_excess_sigma.toFixed(1)}σ ${i.pipeline.w4_excess_sigma.toFixed(1)}σ ${(i.pipeline.coverage_fraction*100).toFixed(1)}% ${i.pipeline.warm_temp_k}K ${i.pipeline.pipeline_score.toFixed(2)} ${i.reveal.id.replace("Gaia DR3 ","").substring(0,8)}... ${i.reveal.spectral_type} ${i.reveal.match?"EXACT":"CLOSE"}
`;const e=document.getElementById("dyson-reveal-btn");e&&e.addEventListener("click",()=>this.toggleBlindReveal()),this.drawBlindComparisonChart(t.targets)}toggleBlindReveal(){this.blindRevealed=!this.blindRevealed;const t=document.getElementById("dyson-blind-table"),e=document.getElementById("dyson-reveal-btn"),i=document.getElementById("dyson-blind-summary");if(t&&(this.blindRevealed?t.classList.add("dyson-revealed"):t.classList.remove("dyson-revealed")),e&&(e.textContent=this.blindRevealed?"Hide Identities":"Reveal Identities"),i&&this.blindData)if(this.blindRevealed){const s=this.blindData.summary;i.style.display="",i.innerHTML=`
Blind Test Results: ${s.pipeline_matches}/${s.total_targets} Matches (r = ${s.ranking_correlation.toFixed(2)})
Ranking Correlation
${s.ranking_correlation.toFixed(2)}
Max Score Difference
${s.max_score_difference.toFixed(3)}
All Excess Detected
${s.all_excess_detected?"YES":"NO"}
${s.conclusion}
`}else i.style.display="none"}drawBlindComparisonChart(t){const e=document.getElementById("dyson-blind-chart");if(!e)return;const i=600,s=180,a={top:20,right:20,bottom:30,left:50},n=i-a.left-a.right,o=s-a.top-a.bottom,r=document.createElement("canvas");r.width=i,r.height=s,r.style.cssText="width:100%;max-width:600px;height:auto",e.innerHTML='
IR Excess Comparison (W3 blue, W4 purple)
',e.appendChild(r);const l=r.getContext("2d");if(!l)return;l.fillStyle="#11161C",l.fillRect(0,0,i,s);const c=Math.max(...t.map(h=>Math.max(h.pipeline.w3_excess_sigma,h.pipeline.w4_excess_sigma))),d=n/t.length/2.5;for(let h=0;hDetection Signatures
${this.data.detection_signatures.map(e=>`
${e.name}
${e.description}
${e.band}
`).join("")}
`)}renderPipeline(){const t=document.getElementById("dyson-pipeline");!t||!this.data||(t.innerHTML=`
Search Pipeline
${this.data.pipeline_stages.map((e,i)=>`
${e.stage}
${e.name}
${i→':""} `).join("")}
`)}async runSearch(){if(this.running||!this.data)return;this.running=!0,this.candidatesEl&&(this.candidatesEl.innerHTML=""),this.resultEl&&(this.resultEl.style.display="none"),this.chartArea&&(this.chartArea.style.display="none");const t=document.getElementById("dyson-3d-panel");t&&(t.style.display="none");for(let i=0;is.pipeline_score-i.pipeline_score);for(const i of e)await this.sleep(200),this.addCandidateCard(i);this.drawExcessChart(e),e.length>0&&this.update3dSphere(e[0]),await this.sleep(400),this.showResult(),this.running=!1}drawExcessChart(t){if(!this.chartArea)return;this.chartArea.style.display="",this.chartArea.innerHTML="";const e=document.createElement("div");e.style.cssText="font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.4px;margin-bottom:6px",e.textContent="Infrared Excess Comparison — All Candidates",this.chartArea.appendChild(e);const i=700,s=220,a={top:24,right:20,bottom:40,left:55},n=i-a.left-a.right,o=s-a.top-a.bottom,r=document.createElement("canvas");r.width=i,r.height=s,r.style.cssText="width:100%;max-width:700px;height:auto;border-radius:6px",this.chartArea.appendChild(r);const l=r.getContext("2d");if(!l)return;l.fillStyle="#11161C",l.fillRect(0,0,i,s);const c=t.length,d=Math.max(...t.map(f=>f.w3_excess)),h=Math.max(...t.map(f=>f.w4_excess)),u=Math.max(d,h),m=n/c,g=m*.35;l.strokeStyle="#1C2333",l.lineWidth=.5,l.fillStyle="#484F58",l.font="9px monospace",l.textAlign="right";for(let f=0;f<=u;f+=5){const w=a.top+o-f/u*o;l.beginPath(),l.moveTo(a.left,w),l.lineTo(a.left+n,w),l.stroke(),l.fillText(`${f}x`,a.left-4,w+3)}for(let f=0;f=.7?"#9944ff":"var(--warning)",l.font="9px monospace",l.textAlign="center",l.fillText(w.pipeline_score.toFixed(2),y+m*.5,a.top-6)}const x=a.top+o+18;l.font="9px sans-serif",l.textAlign="left",l.fillStyle="rgba(68,136,255,0.75)",l.fillRect(a.left,x,10,8),l.fillStyle="#8B949E",l.fillText("W3 (12μm)",a.left+14,x+7),l.fillStyle="rgba(153,68,255,0.75)",l.fillRect(a.left+90,x,10,8),l.fillStyle="#8B949E",l.fillText("W4 (22μm)",a.left+104,x+7),l.fillStyle="#2ECC71",l.beginPath(),l.arc(a.left+186,x+4,3,0,Math.PI*2),l.fill(),l.fillStyle="#8B949E",l.fillText("Coverage %",a.left+193,x+7),this.addSedSelector(t)}addSedSelector(t){if(!this.chartArea)return;const e=document.createElement("div");e.style.cssText="margin-top:12px;padding:12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:6px",e.innerHTML=`
Spectral Energy Distribution
`,this.chartArea.appendChild(e);const i=document.getElementById("dyson-sed-select");i&&(i.addEventListener("change",()=>{this.drawSed(t[parseInt(i.value)])}),this.drawSed(t[0]))}update3dSphere(t){const e=document.getElementById("dyson-3d-panel");e&&(e.style.display="");const i=document.getElementById("dyson-3d-viewport"),s=document.getElementById("dyson-3d-info");if(!i)return;this.sphere3d||(this.sphere3d=new Gs(i));const a={coverageFraction:t.coverage_fraction,warmTempK:t.temperature_k,spectralType:t.spectral_type,w3Excess:t.w3_excess,w4Excess:t.w4_excess,label:t.id};if(this.sphere3d.update(a),this.buildDysonControls(),s){const n=t.id.includes("DR3")&&t.gaia_id||t.id,o=t.dyson_likelihood==="Low"?"var(--text-muted)":t.dyson_likelihood==="Medium"?"var(--warning)":"#9944ff";s.innerHTML=`
Candidate Parameters
${n}
${t.spectral_type} star at ${t.distance_pc} pc
Shell Coverage
${(t.coverage_fraction*100).toFixed(1)}%
Fraction of stellar luminosity captured by the swarm
Waste Heat Temperature
${t.temperature_k} K
${t.temperature_k<200?"Cool outer shell":t.temperature_k<350?"Warm equilibrium":"Hot inner swarm"}
IR Excess
${t.w3_excess.toFixed(1)}x
W3 (12μm)
${t.w4_excess.toFixed(1)}x
W4 (22μm)
Pipeline Score
${t.pipeline_score.toFixed(3)}
Dyson Likelihood: ${t.dyson_likelihood}
Natural explanations: ${t.natural_explanations.join(", ")}
`}}buildDysonControls(){const t=document.getElementById("dyson-3d-controls");if(!t||!this.sphere3d)return;t.innerHTML="";const e="border:1px solid rgba(30,38,48,0.8);border-radius:4px;background:rgba(11,15,20,0.9);color:var(--text-secondary);font-size:10px;padding:4px 8px;cursor:pointer;font-family:var(--font-mono);transition:color 0.15s,border-color 0.15s",i=e.replace("var(--text-secondary)","#9944ff").replace("rgba(30,38,48,0.8)","#9944ff"),s=document.createElement("span");s.style.cssText="font-size:9px;color:var(--text-muted);font-family:var(--font-mono)",s.textContent="Speed:",t.appendChild(s);const a=document.createElement("input");a.type="range",a.min="0.1",a.max="5",a.step="0.1",a.value="1",a.style.cssText="width:70px;height:4px;accent-color:#9944ff;cursor:pointer",a.addEventListener("input",()=>{var d;const c=parseFloat(a.value);(d=this.sphere3d)==null||d.setSpeed(c),n.textContent=`${c.toFixed(1)}x`}),t.appendChild(a);const n=document.createElement("span");n.style.cssText="font-size:9px;color:#9944ff;min-width:24px;font-family:var(--font-mono)",n.textContent="1.0x",t.appendChild(n);const o=document.createElement("span");o.style.cssText="width:1px;height:14px;background:rgba(30,38,48,0.6)",t.appendChild(o);const r=document.createElement("button");r.style.cssText=i,r.textContent="Auto",r.title="Toggle auto-rotate camera",r.addEventListener("click",()=>{var d,h;(d=this.sphere3d)==null||d.toggleAutoRotate();const c=((h=this.sphere3d)==null?void 0:h.getAutoRotate())??!1;r.style.cssText=c?i:e}),t.appendChild(r);const l=document.createElement("button");l.style.cssText=e,l.textContent="Reset",l.title="Reset camera to default position",l.addEventListener("click",()=>{var c,d;(c=this.sphere3d)==null||c.resetCamera(),r.style.cssText=i,a.value="1",n.textContent="1.0x",(d=this.sphere3d)==null||d.setSpeed(1)}),t.appendChild(l)}drawSed(t){this.update3dSphere(t);const e=document.getElementById("dyson-sed-canvas"),i=document.getElementById("dyson-sed-info");if(!e)return;const s=e.getContext("2d");if(!s)return;const a=e.width,n=e.height,o={top:16,right:16,bottom:30,left:50},r=a-o.left-o.right,l=n-o.top-o.bottom;s.clearRect(0,0,a,n),s.fillStyle="#0D1117",s.fillRect(0,0,a,n);const c=[{name:"G",wl:.5,log:Math.log10(.5)},{name:"J",wl:1.25,log:Math.log10(1.25)},{name:"H",wl:1.65,log:Math.log10(1.65)},{name:"K",wl:2.2,log:Math.log10(2.2)},{name:"W1",wl:3.4,log:Math.log10(3.4)},{name:"W2",wl:4.6,log:Math.log10(4.6)},{name:"W3",wl:12,log:Math.log10(12)},{name:"W4",wl:22,log:Math.log10(22)}],d=Math.log10(.3),h=Math.log10(30),u=M=>o.left+(M-d)/(h-d)*r,m=t.temperature_k>1e3?t.temperature_k:3400,g=M=>{const S=3e14/M,$=6626e-37*S/(138e-25*m);return $>50?0:S*S*S/(Math.exp($)-1)},x=c.map(M=>g(M.wl)),f=Math.max(...x),w=c.map((M,S)=>{let $=x[S]/f;return M.name==="W3"&&($*=t.w3_excess),M.name==="W4"&&($*=t.w4_excess),$}),y=x.map(M=>M/f),b=[...y,...w].filter(M=>M>0),v=Math.log10(Math.min(...b)*.5),E=Math.log10(Math.max(...b)*2),C=M=>o.top+l-(M-v)/(E-v)*l;s.strokeStyle="#1C2333",s.lineWidth=.5;for(let M=Math.ceil(v);M<=Math.floor(E);M++){const S=C(M);s.beginPath(),s.moveTo(o.left,S),s.lineTo(o.left+r,S),s.stroke(),s.fillStyle="#484F58",s.font="8px monospace",s.textAlign="right",s.fillText(`10^${M}`,o.left-4,S+3)}s.strokeStyle="rgba(255,221,68,0.5)",s.lineWidth=1.5,s.beginPath();let T=!0;for(let M=d;M<=h;M+=.02){const S=Math.pow(10,M),$=g(S)/f;if($<=0)continue;const O=u(M),K=C(Math.log10($));T?(s.moveTo(O,K),T=!1):s.lineTo(O,K)}s.stroke();const R=t.temperature_k>100?t.temperature_k:328;s.strokeStyle="rgba(153,68,255,0.5)",s.lineWidth=1,s.setLineDash([4,3]),s.beginPath(),T=!0;for(let M=Math.log10(2);M<=h;M+=.02){const $=3e14/Math.pow(10,M),O=6626e-37*$/(138e-25*R);if(O>50)continue;const U=t.coverage_fraction*($*$*$)/(Math.exp(O)-1)/f*50;if(U<=0)continue;const pt=u(M),st=C(Math.log10(U));sto.top+l||(T?(s.moveTo(pt,st),T=!1):s.lineTo(pt,st))}s.stroke(),s.setLineDash([]);for(let M=0;M0){const st=C(Math.log10(pt));s.fillStyle="rgba(255,221,68,0.5)",s.beginPath(),s.arc(O,st,3,0,Math.PI*2),s.fill(),s.strokeStyle="rgba(153,68,255,0.6)",s.lineWidth=1,s.beginPath(),s.moveTo(O,st),s.lineTo(O,K),s.stroke()}}s.fillStyle=U?"#9944ff":"#8B949E",s.font="9px monospace",s.textAlign="center",s.fillText(S.name,O,o.top+l+14)}s.fillStyle="#8B949E",s.font="9px sans-serif",s.textAlign="center",s.fillText("Wavelength (μm, log scale)",o.left+r/2,n-4),s.textAlign="left";const k=o.left+r-200;s.fillStyle="rgba(255,221,68,0.5)",s.fillRect(k,o.top+2,10,2),s.fillStyle="#8B949E",s.fillText("Stellar photosphere",k+14,o.top+7),s.fillStyle="rgba(153,68,255,0.5)",s.fillRect(k,o.top+14,10,2),s.fillStyle="#8B949E",s.fillText(`Warm component (${R}K)`,k+14,o.top+19),i&&(i.innerHTML=` ${t.id.includes("DR3")?t.id.split(" ").pop().substring(0,16)+"...":t.id} — ${t.spectral_type} at ${t.distance_pc} pc — W3 excess: ${t.w3_excess.toFixed(1)}x — W4 excess: ${t.w4_excess.toFixed(1)}x — Coverage: ${(t.coverage_fraction*100).toFixed(1)}% — Warm temp: ${t.temperature_k}K — Likelihood: ${t.dyson_likelihood} `)}highlightStage(t){var e;for(let i=0;i<(((e=this.data)==null?void 0:e.pipeline_stages.length)??0);i++){const s=document.getElementById(`dyson-stage-${i}`);if(!s)continue;const a=s.querySelector("div");i ${t.id} NOTABLE TARGET
${t.description}
${t.key_observations.map(i=>`
• ${i}
`).join("")}
Status: ${t.current_status}
`,this.candidatesEl.appendChild(e)}addCandidateCard(t){if(!this.candidatesEl)return;const e=t.dyson_likelihood==="None (debunked)",i=e?"#FF4D4D":t.pipeline_score>=.7?"#9944ff":t.pipeline_score>=.4?"var(--warning)":"var(--text-muted)",s=e?"rgba(255,77,77,0.3)":"var(--border)",a=e?"rgba(255,77,77,0.04)":"var(--bg-surface)",n=document.createElement("div");n.style.cssText=`padding:12px 16px;margin-bottom:8px;border-radius:6px;background:${a};border:1px solid ${s};cursor:pointer;transition:border-color 0.2s`,n.addEventListener("mouseenter",()=>{n.style.borderColor=e?"#FF4D4D":"#9944ff"}),n.addEventListener("mouseleave",()=>{n.style.borderColor=s}),n.addEventListener("click",()=>this.drawSed(t));const o=e?'DEBUNKED':t.follow_up_status?'UNCONFIRMED':"",r=t.follow_up_status?`
${t.follow_up_status}
`:"";n.innerHTML=`
${t.id} ${o} Score: ${t.pipeline_score.toFixed(2)} ${t.spectral_type} | ${t.distance_pc} pc | Coverage: ${(t.coverage_fraction*100).toFixed(1)}% W3: ${t.w3_excess.toFixed(1)}x | W4: ${t.w4_excess.toFixed(1)}x
${t.analysis}
${r}
Natural Explanations
${t.natural_explanations.map(l=>`
• ${l}
`).join("")}
Dyson likelihood: ${t.dyson_likelihood}
`,this.candidatesEl.appendChild(n)}showResult(){if(!this.resultEl||!this.data)return;const t=this.data.summary;this.resultEl.style.display="",this.resultEl.innerHTML=`
Search Results
Stars Searched
${t.stars_searched}
Anomalous Candidates
${t.candidates_found}
${t.conclusion}
${this.data.references.map(e=>`
${e}
`).join("")}
`}sleep(t){return new Promise(e=>setTimeout(e,t))}unmount(){this.running=!1,this.sphere3d&&(this.sphere3d.destroy(),this.sphere3d=null),this.container=null,this.candidatesEl=null,this.resultEl=null,this.chartArea=null,this.blindArea=null,this.sphere3dContainer=null,this.sphere3dInfoEl=null,this.data=null,this.blindData=null}}const Jt=[{id:"overview",label:"Overview",icon:"⌂",children:[{id:"what-is-rvf",label:"What is RVF?"},{id:"at-a-glance",label:"At a Glance"}]},{id:"single-file",label:"Single File",icon:"▣",children:[{id:"segments",label:"Segment Map"},{id:"why-one-file",label:"Why One File?"}]},{id:"pipeline",label:"Pipeline",icon:"▶",children:[{id:"stage-ingest",label:"Data Ingestion"},{id:"stage-process",label:"Signal Processing"},{id:"stage-detect",label:"Candidate Detection"},{id:"stage-score",label:"Scoring"},{id:"stage-seal",label:"Witness Sealing"}]},{id:"proof",label:"Proof",icon:"✓",children:[{id:"witness-chain",label:"Witness Chain"},{id:"reproducible",label:"Reproducible"},{id:"acceptance",label:"Acceptance Test"},{id:"blind",label:"Blind Testing"}]},{id:"unique",label:"Why Unique",icon:"★"},{id:"capabilities",label:"Views",icon:"◎",children:[{id:"cap-atlas",label:"Atlas Explorer"},{id:"cap-coherence",label:"Coherence"},{id:"cap-boundaries",label:"Boundaries"},{id:"cap-memory",label:"Memory Tiers"},{id:"cap-planets",label:"Planets"},{id:"cap-life",label:"Life"},{id:"cap-witness",label:"Witness Chain"},{id:"cap-solver",label:"Solver"},{id:"cap-blind",label:"Blind Test"},{id:"cap-discover",label:"Discovery"},{id:"cap-dyson",label:"Dyson Sphere"},{id:"cap-status",label:"Status"}]},{id:"solver",label:"Solver",icon:"⚙",children:[{id:"thompson",label:"Thompson Sampling"},{id:"auto-optimize",label:"Auto-Optimize"}]},{id:"format",label:"Format Spec",icon:"☰",children:[{id:"file-header",label:"File Header"},{id:"seg-types",label:"Segment Types"},{id:"witness-format",label:"Witness Entry"},{id:"dashboard-seg",label:"Dashboard Segment"}]},{id:"glossary",label:"Glossary",icon:"≡"}];class Vs{constructor(){this.container=null,this.contentEl=null,this.navLinks=new Map,this.scrollRaf=0,this.onScroll=()=>{cancelAnimationFrame(this.scrollRaf),this.scrollRaf=requestAnimationFrame(()=>{if(!this.contentEl)return;const t=this.contentEl.scrollTop+60;let e="";const i=Array.from(this.navLinks.keys());for(const s of i){const a=this.contentEl.querySelector(`#${s}`);a&&a.offsetTop<=t&&(e=s)}this.navLinks.forEach((s,a)=>{const n=a===e;s.classList.toggle("doc-active",n);const o=Jt.some(r=>r.id===a);n?(s.style.color="var(--accent)",s.style.borderLeftColor="var(--accent)",s.style.background=o?"rgba(0,229,255,0.06)":"rgba(0,229,255,0.03)"):(s.style.color=o?"var(--text-secondary)":"var(--text-muted)",s.style.borderLeftColor="transparent",s.style.background="")})})}}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="display:flex;width:100%;height:100%;overflow:hidden",t.appendChild(e);const i=this.buildNav();e.appendChild(i),this.contentEl=document.createElement("div"),this.contentEl.style.cssText="flex:1;overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;min-width:0",e.appendChild(this.contentEl);const s=document.createElement("div");s.style.cssText="max-width:820px;margin:0 auto;padding:28px 32px 100px;line-height:1.7;color:var(--text-secondary);font-size:13px",this.contentEl.appendChild(s),s.innerHTML=this.buildContent(),this.contentEl.addEventListener("scroll",this.onScroll),requestAnimationFrame(()=>this.onScroll())}unmount(){var t;cancelAnimationFrame(this.scrollRaf),(t=this.contentEl)==null||t.removeEventListener("scroll",this.onScroll),this.navLinks.clear(),this.contentEl=null,this.container=null}buildNav(){const t=document.createElement("nav");t.style.cssText=` width:220px;min-width:220px;background:var(--bg-panel);border-right:1px solid var(--border); overflow-y:auto;overflow-x:hidden;padding:16px 0;display:flex;flex-direction:column; -webkit-overflow-scrolling:touch;flex-shrink:0 `;const e=document.createElement("div");e.style.cssText="padding:0 16px 14px;font-size:13px;font-weight:600;color:var(--text-primary);letter-spacing:0.3px;border-bottom:1px solid var(--border);margin-bottom:8px",e.textContent="Documentation",t.appendChild(e);for(const a of Jt){const n=document.createElement("a");if(n.style.cssText=` display:flex;align-items:center;gap:8px;padding:7px 16px; font-size:12px;font-weight:600;color:var(--text-secondary);cursor:pointer; text-decoration:none;transition:color 0.15s,background 0.15s;border-left:2px solid transparent `,n.innerHTML=`${a.icon} ${a.label}`,n.addEventListener("click",o=>{o.preventDefault(),this.scrollTo(a.id)}),n.addEventListener("mouseenter",()=>{n.style.color="var(--text-primary)",n.style.background="rgba(255,255,255,0.02)"}),n.addEventListener("mouseleave",()=>{n.classList.contains("doc-active")||(n.style.color="var(--text-secondary)",n.style.background="")}),t.appendChild(n),this.navLinks.set(a.id,n),a.children)for(const o of a.children){const r=document.createElement("a");r.style.cssText=` display:block;padding:4px 16px 4px 40px;font-size:11px;color:var(--text-muted); cursor:pointer;text-decoration:none;transition:color 0.15s;border-left:2px solid transparent `,r.textContent=o.label,r.addEventListener("click",l=>{l.preventDefault(),this.scrollTo(o.id)}),r.addEventListener("mouseenter",()=>{r.style.color="var(--text-secondary)"}),r.addEventListener("mouseleave",()=>{r.classList.contains("doc-active")||(r.style.color="var(--text-muted)")}),t.appendChild(r),this.navLinks.set(o.id,r)}}const i=document.createElement("div");i.style.cssText="flex:1;min-height:20px",t.appendChild(i);const s=document.createElement("div");return s.style.cssText="padding:12px 16px;border-top:1px solid var(--border);font-size:9px;color:var(--text-muted);line-height:1.5",s.innerHTML='Built with RuVector
Rust + WASM + Three.js',t.appendChild(s),t}scrollTo(t){var i;const e=(i=this.contentEl)==null?void 0:i.querySelector(`#${t}`);e&&this.contentEl&&this.contentEl.scrollTo({top:e.offsetTop-20,behavior:"smooth"})}buildContent(){const t={h1:"font-size:26px;font-weight:300;color:var(--text-primary);letter-spacing:0.5px;margin-bottom:6px",h2:"font-size:19px;font-weight:600;color:var(--text-primary);margin-top:48px;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--border)",h3:"font-size:14px;font-weight:600;color:var(--accent);margin-top:28px;margin-bottom:8px",p:"margin-bottom:14px",card:"background:var(--bg-panel);border:1px solid var(--border);border-radius:6px;padding:14px 18px;margin-bottom:12px",code:"font-family:var(--font-mono);font-size:11px;background:var(--bg-surface);border:1px solid var(--border);border-radius:4px;padding:12px 16px;display:block;margin:10px 0 14px;overflow-x:auto;line-height:1.6;color:var(--text-primary)",accent:"color:var(--accent);font-weight:600",success:"color:var(--success);font-weight:600",badge:"display:inline-block;font-size:9px;font-weight:600;padding:2px 8px;border-radius:3px;margin-right:4px",inline:"background:var(--bg-surface);padding:1px 6px;border-radius:3px;font-family:var(--font-mono);font-size:12px"};return`
Causal Atlas Documentation
A complete guide to the RVF scientific discovery platform.
What is RVF?
RVF (RuVector Format) is a binary container that holds an entire scientific discovery pipeline — raw telescope data, analysis code, results, cryptographic proofs, and this interactive dashboard — in a single, self-contained file.
Think of it as a shipping container for science. Anyone who receives the file can independently verify every step of the analysis without external tools or databases.
At a Glance
${this.statCard("File Format","Binary, segmented",t)} ${this.statCard("Crypto","Ed25519 + SHAKE-256",t)} ${this.statCard("Solver","WASM + Thompson Sampling",t)} ${this.statCard("Dashboard","Three.js + D3",t)} ${this.statCard("Server","Rust / Axum",t)} ${this.statCard("Domains","Exoplanets, Dyson, Bio",t)}
One File Contains Everything
Traditional scientific data is scattered across files, servers, and packages. RVF packs everything into typed segments inside one binary file.
Segment Map
${this.segRow("HEADER (64 B)","File magic, version, segment count","var(--text-muted)")} ${this.segRow("DATA_SEG","Raw telescope observations (light curves, spectra)","#FF6B9D")} ${this.segRow("KERNEL_SEG","Processing algorithms for analysis","#FFB020")} ${this.segRow("EBPF_SEG","Fast in-kernel data filtering programs","#9944FF")} ${this.segRow("WASM_SEG","Self-learning solver (runs in any browser)","#2ECC71")} ${this.segRow("WITNESS_SEG","Cryptographic proof chain (Ed25519 signed)","var(--accent)")} ${this.segRow("DASHBOARD_SEG","This interactive 3D dashboard (HTML/JS/CSS)","#FF4D4D")} ${this.segRow("SIGNATURE","Ed25519 signature over all segments","var(--text-muted)")}
Why One File?
Portability
Email it, USB drive, or static hosting. No server setup needed.
Reproducibility
Code + data together means anyone can re-run the analysis.
Integrity
Tampering with any segment breaks the signature chain.
Archival
One file to store, back up, and cite. No link rot.
How the Pipeline Works
The pipeline transforms raw observations into verified discoveries through five stages. Each stage is recorded in the witness chain for full traceability.
1. Data Ingestion
Raw photometric data (brightness over time) is ingested from telescope archives. For exoplanet detection, this means light curves — graphs of stellar brightness that dip when a planet transits its star.
2. Signal Processing
Processing kernels clean the data: removing instrumental noise, correcting for stellar variability, and flagging periodic signals. The eBPF programs accelerate filtering at near-hardware speed.
3. Candidate Detection
Cleaned signals are matched against known patterns. For exoplanets: periodic transit-shaped dips. For Dyson spheres: anomalous infrared excess. Each candidate gets derived parameters:
Exoplanets
Radius, period, temperature, HZ membership, ESI score
Dyson Candidates
IR excess ratio, dimming pattern, partial coverage fraction
4. Scoring & Ranking
Candidates are scored multi-dimensionally. The WASM solver uses Thompson Sampling to discover which analysis strategies work best for each difficulty level, continuously improving accuracy without human tuning.
5. Witness Sealing
Every step is recorded in the witness chain: a SHAKE-256 hash of the data, a timestamp, and an Ed25519 signature. This creates an immutable, cryptographically verifiable audit trail.
How Discoveries Are Proven
How do you know the results are real? RVF uses four layers of proof.
Layer 1: Cryptographic Witness Chain
Each processing step writes a witness entry containing:
Step name — what operation was performed
Input hash — SHAKE-256 of data going in
Output hash — SHAKE-256 of data coming out
Parent hash — links to previous entry (chain)
Ed25519 signature — proves the entry is authentic
Each entry chains to the previous one. Altering any step breaks all subsequent signatures.
Layer 2: Reproducible Computation
The file contains the actual analysis code (WASM + eBPF) alongside raw data. Anyone can re-run the pipeline from scratch and verify identical results. No "trust us" — the math is in the file.
Layer 3: Acceptance Testing
Mode A (Heuristic) — Can the solver achieve basic accuracy?
Mode B (Compiler) — Accuracy + computational cost reduction?
Mode C (Learned) — Full: accuracy + cost + robustness + zero violations.
All three modes must pass. The manifest is itself recorded in the witness chain.
Layer 4: Blind Testing
The Blind Test page runs the pipeline on unlabeled data, then compares against ground truth. This guards against overfitting — the pipeline must work on data it has never seen.
What Makes This Unique
${this.uniqueCard("Self-Contained","One file. No cloud, no databases, no external dependencies. The entire pipeline, visualization, and proof chain travel together.",t)} ${this.uniqueCard("Cryptographically Verified","Every step is hashed and signed. Tampering with one part invalidates the entire chain. Mathematical proof, not just peer review.",t)} ${this.uniqueCard("Self-Learning","The WASM solver improves over time using Thompson Sampling, discovering which strategies work for different data difficulties.",t)} ${this.uniqueCard("Runs Anywhere","WASM solver + HTML dashboard + Rust server. No Python, no Jupyter, no conda. Open the file and explore in any modern browser.",t)} ${this.uniqueCard("Multi-Domain","Transit detection, Dyson sphere search, habitability scoring, biosignature analysis — all in one causal event graph.",t)} ${this.uniqueCard("Interactive 3D","Embedded Three.js dashboard: explore the causal atlas as a galaxy, rotate planet systems, visualize Dyson sphere geometry.",t)}
Dashboard Views
12 interactive views, each pulling live data from the RVF file.
${this.viewCard("cap-atlas","Atlas Explorer","#/atlas","var(--accent)","3D galaxy-style causal event graph. Each star = a causal event. Edges = cause-effect. Configurable arms, density, and sector labels.",["3D OrbitControls","Time scale selector","Galaxy shape config","Star map sectors"])} ${this.viewCard("cap-coherence","Coherence Heatmap","#/coherence","#FFB020","Color-mapped surface showing data self-consistency across the observation grid. Blue = stable, red = high uncertainty.",["Surface plot","Epoch scrubber","Partition boundaries"])} ${this.viewCard("cap-boundaries","Boundaries","#/boundaries","#9944FF","Tracks how data partition boundaries shift as new observations arrive. Alerts when boundaries change rapidly.",["Timeline chart","Alert feed","Sector detail"])} ${this.viewCard("cap-memory","Memory Tiers","#/memory","#FF6B9D","Three-tier storage: Small (hot), Medium (warm), Large (cold). Shows utilization, hit rates, and tier migration.",["S/M/L gauges","Utilization bars","Migration flow"])} ${this.viewCard("cap-planets","Planet Candidates","#/planets","#2ECC71","Ranked exoplanet candidates with radius, period, temperature, habitable zone status, and Earth Similarity Index.",["Sortable table","Light curve plots","Score radar"])} ${this.viewCard("cap-life","Life Candidates","#/life","#2ECC71","Biosignature analysis: atmospheric spectra for O₂, CH₄, H₂O. Multi-dimensional scoring with confound analysis.",["Spectrum plots","Molecule heatmap","Reaction graph"])} ${this.viewCard("cap-witness","Witness Chain","#/witness","var(--accent)","Complete cryptographic audit trail. Every step with timestamp, hashes, and signature verification status.",["Scrolling entries","Hash verification","Pipeline trace"])} ${this.viewCard("cap-solver","RVF Solver","#/solver","#FFB020","WASM self-learning solver with Thompson Sampling. 3D landscape shows bandit arm rewards. Configurable training parameters.",["3D landscape","Training curves","A/B/C acceptance","Auto-Optimize"])} ${this.viewCard("cap-blind","Blind Test","#/blind-test","#FF4D4D","Pipeline on unlabeled data, then compared against ground truth. The gold standard for preventing overfitting.",["Unlabeled processing","Ground truth compare","Accuracy metrics"])} ${this.viewCard("cap-discover","Discovery","#/discover","#00E5FF","3D exoplanet systems with host star, orbit, habitable zone. Real KOI parameters. Galaxy background.",["3D planet system","Speed/rotate controls","ESI comparison"])} ${this.viewCard("cap-dyson","Dyson Sphere","#/dyson","#9944FF","Dyson swarm detection using Project Hephaistos methodology. IR excess analysis and 3D wireframe visualization.",["3D Dyson wireframe","IR excess analysis","SED plots"])} ${this.viewCard("cap-status","System Status","#/status","#8B949E","RVF file health, segment sizes, memory tier utilization, pipeline stage indicators, and live witness log.",["Segment breakdown","Tier gauges","Witness log feed"])}
The Self-Learning Solver
The solver is a WebAssembly module compiled from Rust. It runs entirely in your browser using Thompson Sampling.
How Thompson Sampling Works
Imagine 8 different analysis strategies ("arms"). You don't know which works best. Thompson Sampling maintains a Beta distribution for each arm's success rate, samples from these on each attempt, and picks the highest sample. This balances:
Exploration — Trying uncertain arms to gather data
Exploitation — Using known-good arms to maximize results
Over time, the solver converges on optimal strategies per difficulty level. The 3D landscape visually shows which arms have the highest rewards.
Auto-Optimize
The Auto-Optimize button trains in batches of 3 rounds, tests acceptance after each batch, and stops when all three modes pass (max 30 rounds). If accuracy is below 60%, it automatically increases training intensity.
RVF File Format Reference
File Header (64 bytes)
Offset  Size  Field
0x00    4     Magic: 0x52564631 ("RVF1")
0x04    2     Format version (currently 1)
0x06    2     Flags (bit 0 = signed, bit 1 = compressed)
0x08    8     Total file size
0x10    4     Segment count
0x14    4     Reserved
0x18    32    SHAKE-256 hash of all segments
0x38    8     Creation timestamp (Unix epoch)
Segment Types
${this.tableRow("0x01","DATA","Raw observations (light curves, spectra)")} ${this.tableRow("0x02","KERNEL","Processing algorithms")} ${this.tableRow("0x03","RESULT","Computed results and derived parameters")} ${this.tableRow("0x04","WITNESS","Cryptographic audit trail")} ${this.tableRow("0x05","SIGNATURE","Ed25519 digital signature")} ${this.tableRow("0x06","INDEX","Fast lookup table for segments")} ${this.tableRow("0x0F","EBPF","eBPF bytecode for in-kernel filtering")} ${this.tableRow("0x10","WASM","WebAssembly solver module")} ${this.tableRow("0x11","DASHBOARD","Embedded web dashboard (HTML/JS/CSS)")}
ID Name Purpose
Witness Entry Format
struct WitnessEntry {
    step_name:   String,      // "transit_detection"
    timestamp:   u64,         // Unix epoch nanoseconds
    input_hash:  [u8; 32],    // SHAKE-256 of input
    output_hash: [u8; 32],    // SHAKE-256 of output
    parent_hash: [u8; 32],    // Previous entry hash (chain)
    signature:   [u8; 64],    // Ed25519 signature
}
Dashboard Segment
DashboardHeader (64 bytes):
    magic:       0x5256_4442  // "RVDB"
    version:     u16
    framework:   u8           // 0=threejs, 1=react
    compression: u8           // 0=none, 1=gzip, 2=brotli
    bundle_size: u64
    file_count:  u32
    hash:        [u8; 32]     // SHAKE-256 of bundle

Payload: [file_table] [file_data...]
Glossary
${this.glossaryRow("RVF","RuVector Format — the binary container")} ${this.glossaryRow("Segment","A typed block of data inside an RVF file")} ${this.glossaryRow("Witness Chain","Linked list of signed hash entries proving integrity")} ${this.glossaryRow("SHAKE-256","Cryptographic hash function (variable output)")} ${this.glossaryRow("Ed25519","Digital signature algorithm for witness entries")} ${this.glossaryRow("KOI","Kepler Object of Interest — exoplanet candidate")} ${this.glossaryRow("ESI","Earth Similarity Index (0-1, higher = more Earth-like)")} ${this.glossaryRow("Transit","Planet passing in front of its star, causing a brightness dip")} ${this.glossaryRow("Light Curve","Graph of stellar brightness over time")} ${this.glossaryRow("Habitable Zone","Orbital region where liquid water could exist")} ${this.glossaryRow("Thompson Samp.","Bandit algorithm balancing exploration vs exploitation")} ${this.glossaryRow("eBPF","Extended Berkeley Packet Filter — fast kernel programs")} ${this.glossaryRow("WASM","WebAssembly — portable code that runs in browsers")} ${this.glossaryRow("Dyson Sphere","Hypothetical megastructure around a star for energy")} ${this.glossaryRow("IR Excess","More infrared than expected — possible artificial origin")} ${this.glossaryRow("SED","Spectral Energy Distribution — brightness vs wavelength")} ${this.glossaryRow("Coherence","Self-consistency measure of data in a region")} ${this.glossaryRow("Acceptance","Three-mode validation (A/B/C) of solver quality")} ${this.glossaryRow("Blind Test","Evaluation on unlabeled data to prevent overfitting")}
Everything in this dashboard was served from a single .rvf file.
`}statCard(t,e,i){return`
${t}
${e}
`}segRow(t,e,i){return`
${t}${e}
`}uniqueCard(t,e,i){return`
${t}
${e}
`}viewCard(t,e,i,s,a,n){const o=n.map(r=>`${r}`).join("");return`
${e} ${i}
${a}
${o}
`}tableRow(t,e,i){return`${t}${e}${i}`}glossaryRow(t,e){return`${t}${e}`}}const ht="2.0.0",Qt="https://storage.googleapis.com/ruvector-releases",qs=[{platform:"Windows",icon:'',file:`ruvector-${ht}-x64.exe`,size:"~12 MB",ext:".exe",desc:"Windows 10/11 (x64) installer with bundled WASM runtime"},{platform:"macOS",icon:'',file:`RuVector-${ht}.dmg`,size:"~14 MB",ext:".dmg",desc:"macOS 12+ (Apple Silicon & Intel) disk image"},{platform:"Linux",icon:'',file:`ruvector-${ht}-linux-x64.tar.gz`,size:"~10 MB",ext:".tar.gz",desc:"Linux (x86_64) tarball — Ubuntu 20+, Debian 11+, Fedora 36+"}];class Ks{constructor(){this.container=null}mount(t){this.container=t;const e=document.createElement("div");e.style.cssText="max-width:960px;margin:0 auto;padding:32px 24px;overflow-y:auto;height:100%",t.appendChild(e);const i=document.createElement("div");i.style.cssText="text-align:center;margin-bottom:40px",i.innerHTML=`
RuVector
Download the Causal Atlas runtime — a single binary that reads .rvf files, runs the WASM solver, serves the Three.js dashboard, and verifies the Ed25519 witness chain.
v${ht} Stable ADR-040
`,e.appendChild(i);const s=document.createElement("div");s.style.cssText="display:grid;grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));gap:16px;margin-bottom:40px",e.appendChild(s);for(const r of qs){const l=document.createElement("div");l.style.cssText=` background:var(--bg-surface);border:1px solid var(--border);border-radius:8px; padding:20px;display:flex;flex-direction:column;gap:12px; transition:border-color 0.2s,transform 0.2s;cursor:pointer; `,l.addEventListener("mouseenter",()=>{l.style.borderColor="rgba(0,229,255,0.3)",l.style.transform="translateY(-2px)"}),l.addEventListener("mouseleave",()=>{l.style.borderColor="var(--border)",l.style.transform=""}),l.innerHTML=`
${r.icon}
${r.platform}
${r.size}
${r.desc}
${r.file}
Download ${r.ext} `,s.appendChild(l)}const a=document.createElement("div");a.style.cssText="margin-bottom:40px",a.innerHTML=`
npm Packages & WASM Module
rvf-solver (npm)
npm install @ruvector/rvf-solver
NAPI-RS native bindings for Node.js — includes solver, witness chain, and policy kernel.
rvf-solver-wasm (npm)
npm install @ruvector/rvf-solver-wasm
Browser WASM module — same solver running in this dashboard. No native dependencies.
Standalone WASM
curl -O ${Qt}/v${ht}/rvf_solver_wasm.wasm
Raw .wasm binary (172 KB). Load via WebAssembly.instantiate() — no wasm-bindgen needed.
Cargo Crate
cargo add rvf-runtime rvf-types rvf-crypto
Rust workspace crates for embedding RVF files in your own applications.
`,e.appendChild(a);const n=document.createElement("div");n.style.cssText="margin-bottom:40px",n.innerHTML=`
Quick Start
${this.step(1,"Download","Download the installer for your platform above and run it.")} ${this.step(2,"Open an RVF file",` ruvector open causal_atlas.rvf
This starts the local server and opens the dashboard in your browser.
`)} ${this.step(3,"Train the solver","Navigate to the Solver page and click Train or Auto-Optimize. The WASM solver learns in real time inside your browser.")} ${this.step(4,"Run acceptance test","Click Acceptance to verify the solver passes the three-mode acceptance test (A/B/C). All results are recorded in the Ed25519 witness chain.")} ${this.step(5,"Explore discoveries","Navigate to Planets, Life, and Discover pages to explore candidate detections. Each candidate includes a full causal trace and witness proof.")}
`,e.appendChild(n);const o=document.createElement("div");o.innerHTML=`
System Requirements
Windows
Windows 10 (1903+)
x64 processor
4 GB RAM
100 MB disk
macOS
macOS 12 Monterey+
Apple Silicon or Intel
4 GB RAM
100 MB disk
Linux
glibc 2.31+
x86_64 processor
4 GB RAM
100 MB disk
Binaries are hosted on Google Cloud Storage. All downloads include Ed25519 signatures for verification.
`,e.appendChild(o)}step(t,e,i){return`
${t}
${e}
${i}
`}unmount(){this.container=null}}const te={"#/atlas":ss,"#/coherence":os,"#/boundaries":rs,"#/memory":ls,"#/planets":us,"#/life":ys,"#/witness":ws,"#/solver":_s,"#/blind-test":Ps,"#/discover":Hs,"#/dyson":js,"#/status":Ls,"#/download":Ks,"#/docs":Vs};let Et=null;function Us(){const p=document.getElementById("app");if(!p)throw new Error("Missing #app container");return p}function Ys(){const p=location.hash||"#/atlas";document.querySelectorAll("#nav-rail a").forEach(t=>{const e=t;e.classList.toggle("active",e.getAttribute("href")===p)})}function ee(p){const t=Us();Et&&(Et.unmount(),Et=null),t.innerHTML="";const e=te[p]||te["#/atlas"],i=new e;i.mount(t),Et=i,Ys()}async function se(){const p=document.getElementById("root-hash"),t=document.querySelector("#top-bar .dot"),e=document.getElementById("pipeline-status");if(p)try{const i=await ue(),s=(i.file_size*1575931494+i.segments>>>0).toString(16).padStart(8,"0");p.textContent=`0x${s.substring(0,4)}...${s.substring(4,8)}`,t&&(t.style.background="#2ECC71"),e&&(e.textContent="LIVE",e.style.color="#2ECC71")}catch{p.textContent="0x----...----",t&&(t.style.background="#FF4D4D"),e&&(e.textContent="OFFLINE",e.style.color="#FF4D4D")}}function Zs(){Je();const p=location.hash||"#/atlas";location.hash||(location.hash="#/atlas"),ee(p),window.addEventListener("hashchange",()=>{ee(location.hash)}),window.addEventListener("beforeunload",()=>{Qe()}),se(),setInterval(se,1e4)}document.addEventListener("DOMContentLoaded",Zs);