Files
gnommoeditor/dist/glitch/glitch_gallery/assets/index-CMvlyyxu.js
T

2 lines
38 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{r as o,j as e}from"./index-CEeZxcxj.js";const F=18,W=F*F,O=1e3,L=12,K=O*L,Q=K+O,J=["orbit","intro","receptor","transition-photon","photon","transition-eventlist","eventlist","transition-binning","binning","transition-flux","flux","transition-periodogram","periodogram","transition-spectrogram","spectrogram","closing"],I=["orbit","intro","receptor","transition-photon","photon","transition-eventlist","eventlist","transition-binning","binning","transition-flux","flux","transition-periodogram","periodogram","transition-spectrogram","spectrogram","closing"],j=[{label:"Red",shortLabel:"R",wavelength:690,hue:2,saturation:100,lightness:66,energy:.44,decay:700,radius:.28},{label:"Orange",shortLabel:"O",wavelength:620,hue:18,saturation:100,lightness:64,energy:.5,decay:760,radius:.3},{label:"Amber",shortLabel:"A",wavelength:590,hue:36,saturation:100,lightness:66,energy:.56,decay:820,radius:.32},{label:"Yellow",shortLabel:"Y",wavelength:570,hue:56,saturation:100,lightness:69,energy:.62,decay:900,radius:.34},{label:"Green",shortLabel:"G",wavelength:530,hue:108,saturation:84,lightness:66,energy:.7,decay:980,radius:.36},{label:"Cyan",shortLabel:"C",wavelength:500,hue:188,saturation:94,lightness:68,energy:.8,decay:1120,radius:.4},{label:"Blue",shortLabel:"B",wavelength:450,hue:232,saturation:100,lightness:71,energy:.92,decay:1300,radius:.45},{label:"Violet",shortLabel:"V",wavelength:410,hue:274,saturation:100,lightness:74,energy:1.08,decay:1540,radius:.52}],ee=[{page:"binning",title:"Count events per second",diagram:"count-time",rule:"Group event rows into 1 second time bins and count how many clicks fall into each bin.",output:"Light curve / count periodogram"},{page:"flux",title:"Sum energy per second",diagram:"energy-time",rule:"Group event rows into 1 second time bins and sum the total photon energy inside each bin.",output:"Flux variability"},{page:"periodogram",title:"Sum energy by wavelength bin",diagram:"energy-wavelength",rule:"Group event rows by wavelength and sum the energy across the recent time window.",output:"Spectrum"},{page:"spectrogram",title:"Count events by wavelength over time",diagram:"count-wavelength-time",rule:"Group event rows into both time bins and wavelength bins, then count clicks in each cell.",output:"Spectrogram"}],U={"transition-photon":{title:"Every photon has energy",body:"Colour tells us something about wavelength and energy. Before we record the hits, it helps to see what that means.",nextPage:"photon",emoji:"😶‍🌫️"},"transition-eventlist":{title:"Now record the hits",body:"Each photon hit becomes one row with a time, an energy, and a CCD position.",nextPage:"eventlist",emoji:"📝"},"transition-binning":{title:"Chart #1 : Brightness over time",body:"We now use the data and make the first chart",nextPage:"binning",emoji:"🫰🏻⏰"},"transition-flux":{title:"Chart #2: Energy over time",body:"Instead of counting clicks equally, we sum up the energy of each phton inside each time bin.",nextPage:"flux",emoji:"🔥⏰"},"transition-periodogram":{title:"Chart #3: Build a spectrum",body:"The same event list can also be grouped by wavelength. Is it lots of low-energy red photons, or high-energy violet ones? Let`s find out.",nextPage:"periodogram",emoji:"🌈"},"transition-spectrogram":{title:"Chart #3 : Let´s mix things up",body:"Now try both time bins, and wavelength/energy bins at the same time!",nextPage:"spectrogram",emoji:"🤪"}},Y=["receptor","photon","eventlist","binning","flux","periodogram","spectrogram"];function se(){return Array.from({length:W},(t,n)=>({id:n,level:0,size:.22,decay:900,tint:"hsla(0 0% 100% / 0)",glow:"hsla(0 0% 100% / 0)"}))}function te(){return Array.from({length:j.length},()=>0)}function ne(){return{cells:se(),eventHistory:[],totalPhotons:0}}function G(t,n,s){return Math.min(s,Math.max(n,t))}function ae(t){const n=Math.floor(t/1e3),s=Math.floor(n/60),a=n%60,c=Math.floor(t%1e3/10);return[s,a].map(r=>String(r).padStart(2,"0")).join(":")+"."+String(c).padStart(2,"0")}function ce(t){const n=t.replace(/^#/,"");return J.includes(n)?n:"orbit"}function z(){return typeof window>"u"?"orbit":ce(window.location.hash)}function B(t,n,s,a){return`hsla(${t} ${n}% ${s}% / ${a})`}function k(t,n){const s=j[t],a=G(.08+n*.88,.08,.96),c=Math.min(84,s.lightness+n*10);return`hsla(${s.hue} ${s.saturation}% ${c}% / ${a})`}function V(t,n,s,a){if(t.length===0)return"";const c=a?.min??Math.min(...t),r=a?.max??Math.max(...t),i=Math.max(r-c,1e-4);return t.map((d,p)=>{const u=t.length===1?n/2:p/(t.length-1)*n,m=s-(d-c)/i*(s-8)-4;return`${p===0?"M":"L"} ${u.toFixed(2)} ${m.toFixed(2)}`}).join(" ")}function re(t,n,s,a){return t.length===0?"":`${V(t,n,s,a)} L ${n} ${s} L 0 ${s} Z`}function ie(t){const s=G(t,0,1)*(j.length-1),a=Math.floor(s),c=Math.min(j.length-1,Math.ceil(s)),r=s-a,i=j[a],d=j[c],p=(u,m)=>u+(m-u)*r;return{label:r<.5?i.label:d.label,wavelength:p(i.wavelength,d.wavelength),energy:p(i.energy,d.energy),hue:p(i.hue,d.hue),saturation:p(i.saturation,d.saturation),lightness:p(i.lightness,d.lightness)}}function le(){return Array.from({length:42},(t,n)=>({x:n*73%100/100,y:(n*37+11)%100/100,size:.8+n*17%7*.22,opacity:.24+n*29%10*.05}))}function oe(t){const n=le(),s=t*24e-5,c=Math.cos(s)*178,r=Math.sin(s*.72)*34,i=Math.sin(s)*132,p=c*.72,u=r*.45,m=T=>1+T/620,N=460+(0-p)*.72,f=264+(0-u)*.42+i*.08,M=G(m(-p*.05),.88,1.14),C=460+(c-p)*.72,y=236+(r-u)*.5-i*.16,v=G(m(i),.82,1.34),h=s*.9;return{earth:{x:N,y:f,scale:M},telescope:{x:C,y,scale:v,rotation:h},stars:n}}function de(){const[t,n]=o.useState(0);o.useEffect(()=>{let a=0;const c=performance.now(),r=i=>{n(i-c),a=window.requestAnimationFrame(r)};return a=window.requestAnimationFrame(r),()=>window.cancelAnimationFrame(a)},[]);const s=oe(t);return e.jsxs("div",{className:"ccd-orbit-screen",children:[e.jsxs("div",{className:"ccd-orbit-copy",children:[e.jsx("span",{className:"ccd-stat-label",children:"Glitch Hunters's guide to telescopes"}),e.jsx("h2",{children:"Orbital telescopes"}),e.jsx("p",{children:"Humanity has launched multiple telescopes into orbit, each designed to observe the universe from different vantage points."})]}),e.jsx("div",{className:"ccd-orbit-stage",children:e.jsxs("svg",{className:"ccd-orbit-svg",viewBox:"0 0 920 520","aria-label":"Telescope orbiting Earth",children:[e.jsxs("defs",{children:[e.jsxs("radialGradient",{id:"orbitEarthGlow",cx:"42%",cy:"34%",r:"68%",children:[e.jsx("stop",{offset:"0%",stopColor:"#6bd3ff"}),e.jsx("stop",{offset:"36%",stopColor:"#2f88d8"}),e.jsx("stop",{offset:"72%",stopColor:"#124180"}),e.jsx("stop",{offset:"100%",stopColor:"#061327"})]}),e.jsxs("linearGradient",{id:"orbitCubeFront",x1:"0",x2:"1",y1:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#fff7e9"}),e.jsx("stop",{offset:"100%",stopColor:"#ff9d77"})]}),e.jsxs("linearGradient",{id:"orbitCubeSide",x1:"0",x2:"1",y1:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#d3caf7"}),e.jsx("stop",{offset:"100%",stopColor:"#7967db"})]})]}),s.stars.map((a,c)=>e.jsx("circle",{cx:a.x*920,cy:a.y*520,fill:"rgba(255,255,255,0.92)",opacity:a.opacity,r:a.size},c)),e.jsx("ellipse",{className:"ccd-orbit-track",cx:s.earth.x,cy:s.earth.y+8,rx:174*s.earth.scale,ry:62*s.earth.scale}),e.jsxs("g",{transform:`translate(${s.earth.x} ${s.earth.y}) scale(${s.earth.scale})`,children:[e.jsx("circle",{className:"ccd-orbit-earth-atmosphere",cx:"0",cy:"0",r:"112"}),e.jsx("circle",{cx:"0",cy:"0",fill:"url(#orbitEarthGlow)",r:"96"}),e.jsx("path",{className:"ccd-orbit-continent",d:"M -38 -20 C -18 -46 8 -44 22 -12 C 36 10 18 26 -4 32 C -20 38 -42 22 -48 0 Z"}),e.jsx("path",{className:"ccd-orbit-continent",d:"M 18 20 C 38 14 54 26 48 48 C 42 62 18 62 10 44 C 6 34 8 24 18 20 Z"}),e.jsx("circle",{className:"ccd-orbit-night-shadow",cx:"30",cy:"4",r:"92"})]}),e.jsx("g",{transform:`translate(${s.telescope.x} ${s.telescope.y}) rotate(${s.telescope.rotation*180/Math.PI}) scale(${s.telescope.scale})`,children:e.jsxs("g",{className:"ccd-orbit-telescope",children:[e.jsx("polygon",{points:"-18,-18 12,-28 12,4 -18,14",fill:"url(#orbitCubeFront)"}),e.jsx("polygon",{points:"12,-28 30,-14 30,18 12,4",fill:"url(#orbitCubeSide)"}),e.jsx("polygon",{points:"-18,-18 0,-4 30,-14 12,-28",fill:"rgba(255,255,255,0.82)"}),e.jsx("rect",{x:"-42",y:"-5",width:"18",height:"10",rx:"2.5",fill:"#d9d2f5"}),e.jsx("rect",{x:"30",y:"-4",width:"22",height:"8",rx:"3",fill:"#ffc66f"}),e.jsx("rect",{x:"-6",y:"18",width:"12",height:"34",rx:"5",fill:"#bdb4e8"}),e.jsx("rect",{x:"-34",y:"30",width:"68",height:"10",rx:"5",fill:"#8e78ff",opacity:"0.88"})]})})]})}),e.jsx("div",{className:"ccd-orbit-actions",children:e.jsx("a",{className:"ccd-experience-button",href:"#intro",children:"Next"})})]})}function q(t,n,s,a){const c=Array.from({length:L},()=>0),r=Math.max(0,s-L);return t.forEach(i=>{const d=Math.floor((i.time-n)/O);d<r||d>=s||(c[d-r]+=a(i))}),c}function he(t,n,s){const a=Array.from({length:j.length},()=>Array.from({length:L},()=>0)),c=Math.max(0,s-L);return t.forEach(r=>{const i=Math.floor((r.time-n)/O);i<c||i>=s||(a[r.photonIndex][i-c]+=1)}),a}function me(t,n,s){const a=te();if(s<=0)return a;const c=Math.max(0,s-L);return t.forEach(r=>{const i=Math.floor((r.time-n)/O);i>=c&&i<s&&(a[r.photonIndex]+=r.energy)}),a}function ue(t){return{x:t%F+1,y:Math.floor(t/F)+1}}function xe(){if(typeof window>"u")return null;const t=window.AudioContext??window.webkitAudioContext;return t?new t:null}function pe(t){const[n,s]=o.useState(()=>ne()),[a,c]=o.useState(0),[r,i]=o.useState(!1),[d,p]=o.useState(!0),[u]=o.useState(()=>Date.now()),m=o.useRef(u),N=o.useRef(null),f=o.useRef(null),M=o.useRef(t),C=o.useRef(null);o.useEffect(()=>{M.current=t},[t]);const y=()=>{const h=C.current??xe();if(!h){p(!1);return}C.current=h,h.resume().then(()=>{p(!0),i(h.state==="running")}).catch(()=>{i(!1)})};o.useEffect(()=>{const h=()=>{y()};return window.addEventListener("pointerdown",h,{passive:!0}),window.addEventListener("keydown",h),()=>{window.removeEventListener("pointerdown",h),window.removeEventListener("keydown",h)}},[]),o.useEffect(()=>()=>{C.current&&C.current.close()},[]);const v=(h,T,R)=>{if(!M.current)return;const E=C.current;if(!E||E.state!=="running")return;const x=E.currentTime+R,b=E.createOscillator(),A=E.createGain(),w=E.createBiquadFilter(),_=j[h],l=820+h*92,g=.006+T*.004,S=.018+T*.02;b.type="triangle",b.frequency.setValueAtTime(l,x),b.frequency.exponentialRampToValueAtTime(l*.74,x+S),w.type="bandpass",w.frequency.setValueAtTime(1400+_.hue*2.4,x),w.Q.setValueAtTime(1.4,x),A.gain.setValueAtTime(1e-4,x),A.gain.exponentialRampToValueAtTime(g,x+.003),A.gain.exponentialRampToValueAtTime(1e-4,x+S),b.connect(w),w.connect(A),A.connect(E.destination),b.start(x),b.stop(x+S+.008)};return o.useEffect(()=>{const h=()=>{c(Date.now()-m.current)};return h(),N.current=window.setInterval(h,90),()=>{N.current!==null&&window.clearInterval(N.current)}},[]),o.useEffect(()=>{let h=!1;const T=()=>{if(h)return;const R=[],E=[];s(x=>{const b=Date.now(),A=x.cells.map(g=>{if(g.level<=.001)return g.level===0?g:{...g,level:0};const S=36/g.decay;return{...g,level:Math.max(0,g.level-S),size:Math.max(.2,g.size-S*.3)}});let w=x.totalPhotons;const _=Math.random()<.28?2:1;for(let g=0;g<_;g+=1){const S=Math.floor(Math.random()*W),$=Math.floor(Math.random()*j.length),P=j[$],H=A[S],X=G(H.level+P.energy,0,1.25),Z=Math.max(H.size,P.radius+P.energy*.22);A[S]={...H,level:X,size:Z,decay:Math.max(H.decay,P.decay),tint:B(P.hue,P.saturation,P.lightness,.96),glow:B(P.hue,P.saturation,Math.min(88,P.lightness+8),.78)},w+=1,R.push({photonIndex:$,energy:P.energy}),E.push({time:b,photonIndex:$,energy:P.energy,cellIndex:S})}const l=[...x.eventHistory,...E].filter(g=>b-g.time<Q);return{cells:A,eventHistory:l,totalPhotons:w}}),R.forEach((x,b)=>{v(x.photonIndex,x.energy,b*.012)}),f.current=window.setTimeout(T,36+Math.random()*70)};return T(),()=>{h=!0,f.current!==null&&window.clearTimeout(f.current)}},[]),{audioArmed:r,audioSupported:d,enableAudio:y,elapsedMilliseconds:a,exposureStartTime:u,simulation:n}}function ge({cells:t,activeHits:n,averageEnergy:s,guide:a}){return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-stage",children:[e.jsx("div",{className:"ccd-grid-frame",children:e.jsxs("div",{className:"ccd-grid","aria-label":"Photon receptor grid",children:[t.map(c=>e.jsx("div",{className:"ccd-cell",children:e.jsx("span",{className:"ccd-hit",style:{opacity:c.opacity,transform:`translate(-50%, -50%) scale(${c.scale})`,width:`${c.size}rem`,height:`${c.size}rem`,background:c.tint,boxShadow:`0 0 ${.9+c.opacity*1.8}rem ${c.glow}`}})},c.id)),e.jsx("div",{className:"ccd-grid-glow"})]})}),a||null,e.jsxs("div",{className:"ccd-readout","aria-label":"Sensor readout",children:[e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Active pixels"}),e.jsx("strong",{children:String(n).padStart(3,"0")})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Mean charge"}),e.jsx("strong",{children:s.toFixed(3)})]})]})]})})}const je={eyebrow:"Detector Plane",title:"Telescope detector view",description:"The core of the telescope is a camera, called a CCD array. Photons - light from distant galaxies - strike the CCD and light up specific pixels. This is the raw material for the everything a telescope does."},fe={stepLabel:"Step 1",title:"Photons are hitting the detector",body:"Notice how some pixels are bigger than others? They have more energy."};function ve(){return e.jsx("div",{className:"ccd-intro-screen",children:e.jsxs("div",{className:"ccd-intro-panel",children:[e.jsx("div",{className:"ccd-intro-logo-frame","aria-hidden":"true",children:e.jsx("img",{alt:"",className:"ccd-intro-logo",src:"/glitchhunterlogo.png"})}),e.jsx("div",{className:"ccd-intro-brand",children:e.jsx("span",{className:"ccd-intro-brand-mark",children:"Glitch Hunter's"})}),e.jsxs("div",{className:"ccd-intro-copy",children:[e.jsx("h2",{children:"Guide to Telescopes"}),e.jsx("p",{children:"How do they work? What does the telescope actually do?"})]}),e.jsxs("div",{className:"ccd-intro-covers",children:[e.jsx("span",{className:"ccd-stat-label",children:"In this experience, you will see:"}),e.jsxs("div",{className:"ccd-intro-card",children:[e.jsx("span",{className:"ccd-intro-card-index",children:"01"}),e.jsx("strong",{children:"The CCD"}),e.jsx("p",{children:"The telescope's eye, where photons land."})]}),e.jsxs("div",{className:"ccd-intro-card",children:[e.jsx("span",{className:"ccd-intro-card-index",children:"02"}),e.jsx("strong",{children:"Energy and wavelength"}),e.jsx("p",{children:"Colour tells us whether a photon is lower-energy red or higher-energy violet."})]}),e.jsxs("div",{className:"ccd-intro-card",children:[e.jsx("span",{className:"ccd-intro-card-index",children:"03"}),e.jsx("strong",{children:"The event list"}),e.jsx("p",{children:"Each photon hit becomes a recorded row with time, energy, and detector position."})]}),e.jsxs("div",{className:"ccd-intro-card",children:[e.jsx("span",{className:"ccd-intro-card-index",children:"04"}),e.jsx("strong",{children:"Periodograms"}),e.jsx("p",{children:"Group events by time or wavelength to see brightness and spectral power."})]}),e.jsxs("div",{className:"ccd-intro-card",children:[e.jsx("span",{className:"ccd-intro-card-index",children:"05"}),e.jsx("strong",{children:"Spectrograms"}),e.jsx("p",{children:"Bin by both time and wavelength to see how the colours evolve."})]})]}),e.jsx("div",{className:"ccd-intro-actions",children:e.jsx("a",{className:"ccd-experience-button",href:"#receptor",children:"Next"})})]})})}function be(t){return t in U}function ye({onComplete:t}){return e.jsx("div",{className:"ccd-closing-screen",children:e.jsxs("div",{className:"ccd-closing-panel",children:[e.jsx("span",{className:"ccd-stat-label",children:"Key Concepts"}),e.jsx("h2",{children:"What to remember"}),e.jsxs("div",{className:"ccd-closing-grid",children:[e.jsxs("div",{className:"ccd-closing-card",children:[e.jsx("strong",{children:"Binning"}),e.jsx("p",{children:"Grouping events because they arrive at a similar time, or have a similar colour."})]}),e.jsxs("div",{className:"ccd-closing-card",children:[e.jsx("strong",{children:"Energy / wavelength"}),e.jsx("p",{children:"Red means long wavelength and low energy. Violet means short wavelength and high energy."})]}),e.jsxs("div",{className:"ccd-closing-card",children:[e.jsx("strong",{children:"Periodogram"}),e.jsx("p",{children:"How the brightness goes up and down over time."})]}),e.jsxs("div",{className:"ccd-closing-card",children:[e.jsx("strong",{children:"Spectrogram"}),e.jsx("p",{children:"How much there is of each colour."})]}),e.jsxs("div",{className:"ccd-closing-card",children:[e.jsx("strong",{children:"Periodo-spectrogram"}),e.jsx("p",{children:"Binning by both time and wavelength / frequency."})]})]}),e.jsx("p",{className:"ccd-closing-message",children:"You're on your way to becoming a Cosmotologist!"}),e.jsxs("div",{className:"ccd-closing-actions",children:[e.jsx("a",{className:"ccd-experience-button ccd-experience-button-secondary",href:"#orbit",children:"Start Over"}),e.jsx("button",{className:"ccd-experience-button",onClick:()=>{t?.({success:!0,score:100,data:{completedExperience:"ccd-photon-explorer",finalPage:"closing"}})},type:"button",children:"Take the Glitch Gate"})]})]})})}function Ne({page:t}){const n=U[t];return e.jsx("div",{className:"ccd-transition-screen",children:e.jsxs("div",{className:"ccd-transition-card",children:[e.jsx("span",{className:"ccd-stat-label emojilarge",children:n.emoji}),e.jsx("h2",{children:n.title}),e.jsx("p",{children:n.body}),e.jsx("div",{className:"ccd-transition-actions",children:e.jsx("a",{className:"ccd-experience-button",href:`#${n.nextPage}`,children:"Next"})})]})})}const D={eyebrow:"",title:"Space telescope 101",description:"In this interactive tutorial, you will see how photons hit eye of the telescope, and how that is turned into turned into different scientific charts. We`ll cover:"};function we(){const[t,n]=o.useState(.5),s=ie(t),a=B(s.hue,s.saturation,s.lightness,.98);return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-energy-panel",children:[e.jsxs("div",{className:"ccd-energy-scale",children:[e.jsx("div",{className:"ccd-energy-spectrum","aria-hidden":"true",style:{"--ccd-spectrum-position":`${t*100}%`,"--ccd-spectrum-color":a}}),e.jsx("div",{className:"ccd-energy-slider-wrap",children:e.jsx("input",{"aria-label":"Photon wavelength and energy slider",className:"ccd-energy-slider",max:1,min:0,onChange:c=>n(Number(c.target.value)),step:.001,type:"range",value:t})}),e.jsxs("div",{className:"ccd-energy-scale-labels",children:[e.jsx("span",{children:"Longer wavelength"}),e.jsx("span",{children:"Shorter wavelength"})]}),e.jsxs("div",{className:"ccd-energy-scale-labels ccd-energy-scale-labels-strong",children:[e.jsx("span",{children:"Red, lower energy"}),e.jsx("span",{children:"Violet, higher energy"})]})]}),e.jsxs("div",{className:"ccd-energy-readout",children:[e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Selected colour"}),e.jsx("strong",{style:{color:a},children:s.label})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Wavelength"}),e.jsxs("strong",{children:[s.wavelength.toFixed(0)," nm"]})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Energy"}),e.jsxs("strong",{children:[s.energy.toFixed(2)," units"]})]})]})]})})}const Ee={eyebrow:"Photon Energy And Wavelength",title:"Photon colour maps to wavelength",description:"Each hit has energy and wavelength. Red means longer wavelength and lower energy, while violet means shorter wavelength and higher energy. Wavelength is mesaured in nano-meters (nm). One nanometer is one billionth of a meter - about the size of a virus. The visible spectrum ranges from around 380 nm (violet) to 750 nm (red). But telescopes can see beyond that, into high-energy ultraviolet and infrared wavelengths that our eyes can´t detect."},Se={stepLabel:"Colour has meaning",title:"One photon, one observation",body:"In this demo, whenever you see the 🟣 colour, it indicates high energy - short wavelength. 🔴 is lower energy, but longer wavelength. "};function Pe({type:t}){if(t==="count-wavelength-time")return e.jsx("div",{className:"ccd-mini-diagram ccd-mini-diagram-grid","aria-hidden":"true",children:Array.from({length:12},(s,a)=>e.jsx("span",{className:"ccd-mini-diagram-grid-cell",style:{opacity:.28+a%4*.14}},a))});const n=t==="count-time"?[.28,.58,.38,.76,.46,.66]:t==="energy-time"?[.22,.5,.42,.88,.56,.72]:[.2,.32,.48,.84,.6,.3];return e.jsx("div",{className:"ccd-mini-diagram","aria-hidden":"true",children:n.map((s,a)=>e.jsx("span",{className:`ccd-mini-diagram-bar${t!=="count-time"?" is-energy":""}`,style:{height:`${s*100}%`}},a))})}function Ce({page:t,onSelect:n,showGuide:s,onToggleGuide:a}){const c=t==="receptor",r=t==="photon",i=t==="eventlist";return e.jsxs("section",{className:"ccd-selector","aria-label":"Visualization selector",children:[e.jsxs("div",{className:"ccd-selector-root",children:[e.jsx("span",{className:"ccd-stat-label",children:"These plots are different ways of binning the same event list."}),e.jsx("p",{children:"Everything begins with the CCD receiving photons. Those hits become rows in an event list. After that, different binning rules produce different plots."})]}),e.jsxs("div",{className:"ccd-selector-raw",children:[e.jsxs("a",{className:`ccd-selector-link${c?" is-active":""}`,href:"#receptor",onClick:n,children:[e.jsx("span",{className:"ccd-selector-link-label",children:"Raw data"}),e.jsx("strong",{children:"1. Photons hit CCD pixels"}),e.jsx("span",{children:"This is the detector plane: the spatial pattern of hits on the telescope CCD."})]}),e.jsxs("a",{className:`ccd-selector-link${r?" is-active":""}`,href:"#photon",onClick:n,children:[e.jsx("span",{className:"ccd-selector-link-label",children:"Photon properties"}),e.jsx("strong",{children:"2. Colour indicates wavelength and energy"}),e.jsx("span",{children:"Red means lower energy and violet means higher energy, which is why later plots can bin by wavelength."})]}),e.jsxs("a",{className:`ccd-selector-link${i?" is-active":""}`,href:"#eventlist",onClick:n,children:[e.jsx("span",{className:"ccd-selector-link-label",children:"Recorded data"}),e.jsx("strong",{children:"3. Each hit becomes a row: time, energy, x, y"}),e.jsx("span",{children:"This is the FITS-style event table. Every later diagram is derived from these same rows."})]})]}),e.jsx("div",{className:"ccd-selector-section",children:e.jsxs("div",{className:"ccd-selector-axis",children:[e.jsx("span",{className:"ccd-stat-label",children:"4. Choose a binning rule"}),e.jsx("strong",{children:"Derived view: binned visualization"}),e.jsx("p",{children:"These plots are different ways of grouping the same event rows."})]})}),e.jsx("div",{className:"ccd-selector-results",children:ee.map(d=>e.jsxs("a",{className:`ccd-selector-leaf${d.page===t?" is-active":""}`,href:`#${d.page}`,onClick:n,children:[e.jsx("span",{className:"ccd-selector-leaf-dim",children:"Input: same event list"}),e.jsx(Pe,{type:d.diagram}),e.jsx("strong",{children:d.title}),e.jsxs("span",{children:["Rule: ",d.rule]}),e.jsxs("span",{children:["Output: ",d.output]})]},d.page))}),e.jsxs("div",{className:"ccd-selector-current",children:[e.jsx("span",{className:"ccd-stat-label",children:"Recording"}),e.jsx("button",{className:`ccd-selector-option${s?" is-active":""}`,onClick:a,type:"button",children:s?"Guide overlay on":"Guide overlay off"})]})]})}function Te(t){switch(t){case"intro":return D;case"receptor":return je;case"photon":return Ee;case"eventlist":return ke;case"binning":return We;case"flux":return De;case"periodogram":return Le;case"spectrogram":return $e;case"closing":return D;default:return D}}function Ae(t){switch(t){case"intro":return null;case"receptor":return fe;case"photon":return Se;case"eventlist":return Ge;case"binning":return Ye;case"flux":return Be;case"periodogram":return _e;case"spectrogram":return He}}function Me({page:t}){const n=I.indexOf(t),s=n>0?I[n-1]:null,a=n>=0&&n<I.length-1?I[n+1]:null,c=Ae(t),r=Y.length,i=Y.indexOf(t)+1;return c?e.jsxs("div",{className:"ccd-experience-overlay",children:[e.jsxs("div",{className:"ccd-experience-step",children:[e.jsx("span",{className:"ccd-stat-label",children:c.stepLabel}),e.jsxs("span",{children:[i," / ",r]})]}),e.jsx("h2",{children:c.title}),e.jsx("p",{children:c.body}),e.jsxs("div",{className:"ccd-experience-actions",children:[s?e.jsx("a",{className:"ccd-experience-button ccd-experience-button-secondary",href:`#${s}`,children:"Previous"}):e.jsx("span",{className:"ccd-experience-spacer"}),e.jsx("a",{className:"ccd-experience-button",href:`#${a??I[0]}`,children:a?"Next":"Start Over"})]})]}):null}function Re({events:t,exposureStartTime:n}){const s=t.slice(-36).reverse();return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-table-panel",children:[e.jsx("div",{className:"ccd-chart-head",children:e.jsxs("strong",{children:[s.length," recent events"]})}),e.jsxs("div",{className:"ccd-event-table-shell","aria-label":"Photon event list",children:[e.jsxs("div",{className:"ccd-event-table ccd-event-table-head",children:[e.jsx("span",{children:"TIME (s)"}),e.jsx("span",{children:"ENERGY"}),e.jsx("span",{children:"CCD X"}),e.jsx("span",{children:"CCD Y"})]}),e.jsxs("div",{className:"ccd-event-table-body",children:[s.map((a,c)=>{const r=ue(a.cellIndex),i=(a.time-n)/1e3;return j[a.photonIndex],e.jsxs("div",{className:"ccd-event-table",children:[e.jsx("span",{children:i.toFixed(3)}),e.jsx("span",{style:{color:k(a.photonIndex,.92)},children:a.energy.toFixed(2)}),e.jsx("span",{children:String(r.x).padStart(2,"0")}),e.jsx("span",{children:String(r.y).padStart(2,"0")})]},`${a.time}-${a.cellIndex}-${c}`)}),s.length===0?e.jsxs("div",{className:"ccd-event-table ccd-event-table-empty",children:[e.jsx("span",{children:"No rows yet"}),e.jsx("span",{children:"Waiting"}),e.jsx("span",{children:"--"}),e.jsx("span",{children:"--"})]}):null]})]}),e.jsx("div",{className:"ccd-flux-legend",children:j.map((a,c)=>e.jsxs("span",{className:"ccd-flux-legend-item",children:[e.jsx("span",{className:"ccd-legend-dot",style:{background:k(c,.92),boxShadow:`0 0 0.8rem ${k(c,.56)}`}}),e.jsx("span",{children:a.label})]},a.label))})]})})}const ke={eyebrow:"FITS Event Table",title:"Photon event list view",description:"The clicks are recorded in a table, called the event list, with the time, energy, and CCD pixel position."},Ge={stepLabel:"Step 3",title:"Each hit becomes a row in the event list",body:"Astronomy pipelines often save these events as FITS tables. This is the raw data you can download from Telescopes like Chandra!"};function Ie({spectralEnergy:t}){const n=Math.max(...t,.01),s=t.reduce((a,c)=>a+c,0)||1;return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-chart-panel",children:[e.jsxs("div",{className:"ccd-chart-head",children:[e.jsx("span",{className:"ccd-stat-label",children:"Integrated over last 12 completed 1.0 s bins"}),e.jsxs("strong",{children:[s.toFixed(2)," total energy units"]})]}),e.jsx("div",{className:"ccd-periodogram","aria-label":"Periodogram chart",children:j.map((a,c)=>{const r=G(t[c]/n,0,1),i=t[c]/s;return e.jsxs("div",{className:"ccd-periodogram-band",children:[e.jsx("div",{className:"ccd-bar-shell",children:e.jsx("div",{className:"ccd-bar-fill",style:{height:`${18+r*82}%`,background:`linear-gradient(180deg, ${k(c,.55)}, ${k(c,1)})`,boxShadow:`0 0 1.4rem ${k(c,.72)}`}})}),e.jsxs("div",{className:"ccd-band-meta",children:[e.jsx("strong",{children:a.shortLabel}),e.jsxs("span",{children:[a.wavelength," nm"]}),e.jsxs("span",{children:[t[c].toFixed(2)," E"]}),e.jsxs("span",{children:[(i*100).toFixed(1),"%"]})]})]},a.label)})})]})})}const Le={eyebrow:"Spectral power",title:"Spectrogram of energy",description:"We put low-energy on the left, and high energy on the right. The energy of all the photons in each frequency bin integrated over some period (here last 12 secs) gives us the shape of the spectrum during that time."},_e={stepLabel:"Step 6",title:"Spectral power",body:"Spectral power reveals the energy distribution, and it´s very important for many applications. It can tell us a lot about how stars work"};function Oe({spectrogramBins:t}){const n=Math.max(...t.flat(),1);return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-chart-panel ccd-chart-panel-wide",children:[e.jsxs("div",{className:"ccd-chart-head",children:[e.jsx("span",{className:"ccd-stat-label",children:"Clicks per 1.0 s time bin"}),e.jsxs("strong",{children:[L," time bins x ",j.length," frequency bins"]})]}),e.jsxs("div",{className:"ccd-spectrogram-shell",children:[e.jsx("div",{className:"ccd-spectrogram-axis",children:j.map(s=>e.jsx("span",{children:s.label},s.label))}),e.jsx("div",{className:"ccd-spectrogram","aria-label":"Spectrogram heat map",children:j.map((s,a)=>e.jsx("div",{className:"ccd-spectrogram-row",children:t[a].map((c,r)=>e.jsx("span",{className:"ccd-spectrogram-cell",style:{background:k(a,c/n),boxShadow:c>0?`0 0 0.8rem ${k(a,c/n)}`:"none"}},`${s.label}-${r}`))},s.label))})]}),e.jsxs("div",{className:"ccd-spectrogram-footer",children:[e.jsx("span",{children:"Earlier"}),e.jsx("span",{children:"Now"})]})]})})}const $e={eyebrow:"Frequency X Time",title:"Periodo-spectro-gram!",description:"You can play around with the same data and make many charts! This shows the energy arriving during each time bin for each frequency bin!"},He={stepLabel:"Step 7",title:"Binned by time and frequency",body:"Is it useful? Maybe not for a lot of applications, but it looks pretty!"};function Fe({fluxBins:t}){const n=t.some(y=>y>0)?t:[1.2,1.8,1.4,2.1,1.7,1.5,2.3,1.6,1.9,1.4,2,1.7],s=n.map((y,v)=>{const h=n.slice(0,v+1);return h.reduce((T,R)=>T+R,0)/h.length}),a=n[n.length-1]??0,c=n.reduce((y,v)=>y+v,0)/n.length,r=n.reduce((y,v)=>y+(v-c)**2,0)/n.length,i=Math.sqrt(r),d=Math.min(...n),p=Math.max(...n),u=Math.min(...s),m=Math.max(...s),N={min:Math.min(d,u),max:Math.max(p,m)},f=V(n,760,240,N),M=re(n,760,240,N),C=V(s,760,240,N);return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-chart-panel ccd-chart-panel-wide",children:[e.jsxs("div",{className:"ccd-chart-head",children:[e.jsx("span",{className:"ccd-stat-label",children:"Total energy per 1.0 s bin"}),e.jsxs("strong",{children:[a.toFixed(2)," energy units in latest bin"]})]}),e.jsxs("div",{className:"ccd-flux-chart-shell",children:[e.jsxs("svg",{className:"ccd-flux-chart",viewBox:"0 0 760 240","aria-label":"Total flux variability chart",preserveAspectRatio:"none",children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"fluxArea",x1:"0",x2:"0",y1:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"rgba(255, 113, 74, 0.40)"}),e.jsx("stop",{offset:"100%",stopColor:"rgba(125, 100, 255, 0.03)"})]}),e.jsxs("linearGradient",{id:"fluxLine",x1:"0",x2:"1",y1:"0",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"#ff8d66"}),e.jsx("stop",{offset:"55%",stopColor:"#ffd35d"}),e.jsx("stop",{offset:"100%",stopColor:"#8f7dff"})]})]}),n.map((y,v)=>{const h=760/n.length;return e.jsx("rect",{className:v%2===0?"ccd-flux-bin":"ccd-flux-bin ccd-flux-bin-alt",x:v*h,y:0,width:h,height:240},v)}),e.jsx("path",{className:"ccd-flux-area",d:M,fill:"url(#fluxArea)"}),e.jsx("path",{className:"ccd-flux-line",d:f,stroke:"url(#fluxLine)"}),e.jsx("path",{className:"ccd-flux-mean-line",d:C})]}),e.jsxs("div",{className:"ccd-flux-legend",children:[e.jsxs("span",{className:"ccd-flux-legend-item",children:[e.jsx("span",{className:"ccd-flux-legend-swatch ccd-flux-legend-swatch-raw"}),e.jsx("span",{children:"Raw flux"})]}),e.jsxs("span",{className:"ccd-flux-legend-item",children:[e.jsx("span",{className:"ccd-flux-legend-swatch ccd-flux-legend-swatch-mean"}),e.jsx("span",{children:"Running mean"})]})]}),e.jsxs("div",{className:"ccd-flux-axis",children:[e.jsx("span",{children:"Earlier"}),e.jsx("span",{children:"Now"})]})]}),e.jsxs("div",{className:"ccd-flux-metrics",children:[e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Mean flux"}),e.jsx("strong",{children:c.toFixed(4)})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Sigma"}),e.jsx("strong",{children:i.toFixed(4)})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Range"}),e.jsxs("strong",{children:[d.toFixed(4)," to ",p.toFixed(4)]})]})]})]})})}const De={eyebrow:"Flux Variability",title:"Total flux periodogram",description:"If we focus on the energy instead of the count, we get the flux - energy per second. It tells us how the total energy varies over time (1 sec bins)."},Be={stepLabel:"Step 5",title:"Periodogram of flux",body:"This tells you how much the flux varies over time . The dotted line is the running mean, which helps show trends over time."};function Ve({countBins:t}){const n=t.some(c=>c>0)?t:[3,5,4,7,6,5,8,4,6,5,7,4],s=Math.max(...n,1),a=n.reduce((c,r)=>c+r,0)/n.length;return e.jsx("div",{className:"ccd-page",children:e.jsxs("div",{className:"ccd-chart-panel ccd-chart-panel-wide",children:[e.jsxs("div",{className:"ccd-chart-head",children:[e.jsx("span",{className:"ccd-stat-label",children:"Photon clicks per 1.0 s bin"}),e.jsxs("strong",{children:[a.toFixed(1)," clicks / second bin"]})]}),e.jsxs("div",{className:"ccd-counts-shell",children:[e.jsx("div",{className:"ccd-counts-chart","aria-label":"Photon counts per bin chart",children:n.map((c,r)=>e.jsxs("div",{className:"ccd-count-bin",children:[e.jsx("div",{className:"ccd-count-bin-label",children:c}),e.jsx("div",{className:"ccd-count-bar-shell",children:e.jsx("div",{className:"ccd-count-bar",style:{height:`${12+c/s*88}%`}})})]},r))}),e.jsxs("div",{className:"ccd-flux-axis",children:[e.jsx("span",{children:"Earlier"}),e.jsx("span",{children:"Now!"})]})]}),e.jsx("div",{className:"ccd-flux-legend",children:e.jsxs("span",{className:"ccd-flux-legend-item",children:[e.jsx("span",{className:"ccd-flux-legend-swatch ccd-counts-legend-swatch-bin"}),e.jsx("span",{children:"Photon count bins"})]})}),e.jsxs("div",{className:"ccd-flux-metrics",children:[e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Bin width"}),e.jsx("strong",{children:"1.0 s"})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Latest bin"}),e.jsxs("strong",{children:[n[n.length-1]??0," clicks"]})]}),e.jsxs("div",{className:"ccd-stat",children:[e.jsx("span",{className:"ccd-stat-label",children:"Mean bin count"}),e.jsx("strong",{children:a.toFixed(2)})]})]})]})})}const We={eyebrow:"Brightness",title:"Periodogram of counts",description:"The first chart is the periodogram. We put the clicks into groups. They arrive same second, same group! This is called time bining. (each bin 1 sec). This gives us the count per second - or the periodogram of photon counts."},Ye={stepLabel:"Step 4",title:"Brightness is counting clicks!",body:"If we ignore photon energy and just count how many events arrive each second, we get a brightness-style light curve from the same event list."};function ze({onComplete:t,onProgress:n}={}){const[s,a]=o.useState(()=>z()),[c,r]=o.useState(!1),[i,d]=o.useState(!0),{elapsedMilliseconds:p,exposureStartTime:u,simulation:m}=pe(s==="receptor");o.useEffect(()=>{const l=()=>{a(z()),r(!1)};return window.addEventListener("hashchange",l),()=>window.removeEventListener("hashchange",l)},[]),o.useEffect(()=>{const l=I.indexOf(s);l<0||n?.(Math.round(l/(I.length-1)*100))},[n,s]),o.useEffect(()=>{if(!c)return;const l=g=>{g.key==="Escape"&&r(!1)};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[c]);const N=o.useMemo(()=>m.cells.map(l=>({id:l.id,opacity:G(l.level,0,1),scale:.72+G(l.level*.7,0,.86),size:l.size,tint:l.tint,glow:l.glow})),[m.cells]),f=Math.floor(p/O),M=o.useMemo(()=>me(m.eventHistory,u,f),[f,u,m.eventHistory]),C=o.useMemo(()=>q(m.eventHistory,u,f,l=>l.energy),[f,u,m.eventHistory]),y=o.useMemo(()=>q(m.eventHistory,u,f,()=>1),[f,u,m.eventHistory]),v=o.useMemo(()=>he(m.eventHistory,u,f),[f,u,m.eventHistory]),h=N.filter(l=>l.opacity>.08).length,T=N.reduce((l,g)=>l+g.opacity,0)/W,R=M.reduce((l,g,S,$)=>g>$[l]?S:l,0),E=j[R],x=be(s)?s:null,b=s==="orbit"||s==="intro"||s==="closing",A=s==="orbit",w=x||b?null:Te(s),_=i&&!b&&!x?e.jsx(Me,{page:s}):null;return e.jsx("main",{className:"ccd-shell",children:e.jsxs("section",{className:`ccd-panel${A?" ccd-panel-wide-scene":""}`,children:[w?e.jsx("header",{className:"ccd-topbar",children:e.jsxs("div",{className:"ccd-copy",children:[e.jsx("p",{className:"ccd-kicker",children:w.eyebrow}),e.jsx("h1",{children:w.title}),e.jsx("p",{className:"ccd-description",children:w.description})]})}):null,c?e.jsx("div",{className:"ccd-modal-backdrop",onClick:()=>r(!1),role:"presentation",children:e.jsxs("div",{className:"ccd-modal",onClick:l=>l.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Visualization chooser",children:[e.jsxs("div",{className:"ccd-modal-header",children:[e.jsxs("div",{className:"ccd-copy",children:[e.jsx("p",{className:"ccd-kicker",children:"Data Pipeline"}),e.jsx("h2",{children:"How do we transform the event list?"})]}),e.jsx("button",{className:"ccd-modal-close",onClick:()=>r(!1),type:"button","aria-label":"Close visualization chooser",children:"Close"})]}),e.jsx(Ce,{page:s,onSelect:()=>r(!1),showGuide:i,onToggleGuide:()=>d(l=>!l)})]})}):null,e.jsxs("div",{className:"ccd-experience-frame",children:[s==="orbit"?e.jsx(de,{}):null,s==="intro"?e.jsx(ve,{}):null,s==="closing"?e.jsx(ye,{onComplete:t}):null,x?e.jsx(Ne,{page:x}):null,s==="receptor"?e.jsx(ge,{cells:N,activeHits:h,averageEnergy:T,guide:_}):null,s==="photon"?e.jsx(we,{}):null,s==="eventlist"?e.jsx(Re,{events:m.eventHistory,exposureStartTime:u}):null,s==="periodogram"?e.jsx(Ie,{spectralEnergy:M}):null,s==="spectrogram"?e.jsx(Oe,{spectrogramBins:v}):null,s==="flux"?e.jsx(Fe,{fluxBins:C}):null,s==="binning"?e.jsx(Ve,{countBins:y}):null,s!=="receptor"?_:null]}),!b&&!x?e.jsxs("div",{className:"ccd-summary-row","aria-label":"Simulation summary",children:[e.jsxs("div",{className:"ccd-summary-card",children:[e.jsx("span",{className:"ccd-stat-label",children:"Exposure time"}),e.jsx("strong",{children:ae(p)})]}),e.jsxs("div",{className:"ccd-summary-card",children:[e.jsx("span",{className:"ccd-stat-label",children:"Photon count"}),e.jsx("strong",{children:m.totalPhotons})]}),e.jsxs("div",{className:"ccd-summary-card",children:[e.jsx("span",{className:"ccd-stat-label",children:"Dominant Band (Last 1 s)"}),e.jsx("strong",{children:E.label})]})]}):null]})})}function Ue({className:t,onComplete:n,onProgress:s}){return e.jsx("div",{className:t,children:e.jsx(ze,{onComplete:n,onProgress:s})})}const Xe={name:"ccd",displayName:"CCD Photon Explorer",version:"0.1.0",paramSchema:{},defaultParams:{}};export{Ue as default,Xe as metadata};