@rr0/ufoathome 0.86.2 → 0.86.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ContrailSystem-CQsI1Z1v.js","./ContrailGrowth-CuAzwIoc.js","./trafficRuntime-_pIg6nkw.js"])))=>i.map(i=>d[i]);
2
- const pv="modulepreload",mv=function(r,t){return new URL(r,t).href},ff={},an=function(t,e,i){let n=Promise.resolve();if(e&&e.length>0){let a=function(h){return Promise.all(h.map(u=>Promise.resolve(u).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};const o=document.getElementsByTagName("link"),c=document.querySelector("meta[property=csp-nonce]"),l=c?.nonce||c?.getAttribute("nonce");n=a(e.map(h=>{if(h=mv(h,i),h in ff)return;ff[h]=!0;const u=h.endsWith(".css"),d=u?'[rel="stylesheet"]':"";if(!!i)for(let v=o.length-1;v>=0;v--){const m=o[v];if(m.href===h&&(!u||m.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${h}"]${d}`))return;const p=document.createElement("link");if(p.rel=u?"stylesheet":pv,u||(p.as="script"),p.crossOrigin="",p.href=h,l&&p.setAttribute("nonce",l),document.head.appendChild(p),u)return new Promise((v,m)=>{p.addEventListener("load",v),p.addEventListener("error",()=>m(new Error(`Unable to preload CSS for ${h}`)))})}))}function s(a){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=a,window.dispatchEvent(o),!o.defaultPrevented)throw a}return n.then(a=>{for(const o of a||[])o.status==="rejected"&&s(o.reason);return t().catch(s)})};class Fa{static sessionDeclared=!1;static unlock(t){if(Fa.declarePlayback(),t.state!=="running")try{Promise.resolve(t.resume()).catch(()=>{});const e=t.createBufferSource();e.buffer=t.createBuffer(1,1,22050),e.connect(t.destination),e.start(0)}catch{}}static declarePlayback(){if(!(Fa.sessionDeclared||typeof navigator>"u")){Fa.sessionDeclared=!0;try{const t=navigator.audioSession;t&&(t.type="playback")}catch{}}}}const gv=.08,pf=.15,mf=2,vv=2e3;class Mv{context;noiseBuffer;voices=new Map;paused=!0;requested=[];resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("VehicleAudio: Web Audio unavailable, vehicles stay silent:",t);return}}Fa.unlock(this.context),this.apply()}setPaused(t){t!==this.paused&&(this.paused=t,this.apply())}setVoices(t){this.requested=t,this.apply()}dispose(){for(const t of[...this.voices.keys()])this.release(t);this.context?.close(),this.context=void 0}apply(){const t=this.context;if(!t)return;const e=this.paused?[]:this.requested.filter(n=>n.inside||n.distanceM<vv),i=new Set(e.map(n=>n.id));for(const n of[...this.voices.keys()])i.has(n)||this.release(n);for(const n of e){const s=this.voices.get(n.id)??this.build(t,n.id);this.retarget(t,s,n)}}build(t,e){const i=t.createGain();i.gain.value=0;const n=t.createBiquadFilter();n.type="lowpass",n.connect(i).connect(t.destination);const s=t.createOscillator();s.type="sawtooth";const a=t.createOscillator();a.type="sine";const o=t.createGain(),c=t.createBiquadFilter();c.type="lowpass",c.frequency.value=900,s.connect(c),a.connect(c),c.connect(o).connect(n);const l=()=>{const b=t.createBufferSource();return b.buffer=this.noise(t),b.loop=!0,b.loopStart=Math.random()*mf*.5,b},h=l(),u=t.createBiquadFilter();u.type="bandpass",u.Q.value=4;const d=t.createGain();h.connect(u).connect(d).connect(n);const f=l(),p=t.createBiquadFilter();p.type="lowpass",p.frequency.value=600;const v=t.createGain();f.connect(p).connect(v).connect(n);const m=l(),g=t.createBiquadFilter();g.type="bandpass",g.frequency.value=1400,g.Q.value=.7;const _=t.createGain();m.connect(g).connect(_).connect(n);const y=[s,a,h,f,m];for(const b of y)b.start();const M={nodes:[i,n,o,c,u,d,p,v,g,_,...y],sources:y,firing:s,crank:a,knock:u,engineGain:o,knockGain:d,roadGain:v,windGain:_,cabin:n,output:i};return this.voices.set(e,M),M}retarget(t,e,{profile:i,state:n,noise:s,inside:a,windowsOpen:o,distanceM:c}){const l=t.currentTime,h=(_,y)=>_.setTargetAtTime(y,l,gv),u=n.rpm/60,d=u*i.cylinders/2,f=Math.min(1,n.rpm/i.shiftUpRpm),p=Math.min(1.5,n.speedMps/30);h(e.firing.frequency,d),h(e.crank.frequency,u),h(e.knock.frequency,d*3),h(e.engineGain.gain,i.engineGain*(.25+.75*n.load)*(.5+.5*f)*.3),h(e.knockGain.gain,i.roughness*(.2+.8*n.load)*.4),h(e.roadGain.gain,i.roadGain*p**1.5*.8);const v=!a||o;h(e.windGain.gain,p**2*(v?.5:.06));const m=a?o?3500:700:8e3/(1+c/60);h(e.cabin.frequency,m);const g=a?.5:Math.min(1,8/Math.max(c,1));h(e.output.gain,g*s)}release(t){const e=this.voices.get(t);if(!e)return;this.voices.delete(t);const i=this.context;i&&(e.output.gain.setTargetAtTime(0,i.currentTime,pf/3),setTimeout(()=>{for(const n of e.sources)try{n.stop()}catch{}for(const n of e.nodes)n.disconnect()},pf*1e3*3))}noise(t){if(this.noiseBuffer)return this.noiseBuffer;const e=t.createBuffer(1,t.sampleRate*mf,t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;return this.noiseBuffer=e,e}}const gf=2;function Mg(r){return r==="building"||r==="vehicle"}function xv(r,t){const e=r.litKeyframes;if(!e||e.length===0)return r.lit??!1;let i=e[0];for(const n of e){if(n.t>t)break;i=n}return i.lit}function yv(r,t){return r.pattern.kind==="steady"?!0:xg(r,t,t+1)>.5}function xg(r,t,e){if(r.pattern.kind==="steady")return 1;const{perMinute:i,dutyCycle:n,phase:s=0}=r.pattern,a=Math.min(Math.max(n,0),1);if(a===0||i<=0)return 0;const o=6e4/i,c=t/o+s,l=e/o+s;if(l<=c)return Math.min(Math.max(c-Math.floor(c),0),a)<a?1:0;const h=u=>Math.floor(u)*a+Math.min(u-Math.floor(u),a);return(h(l)-h(c))/(l-c)}function Go(r,t){const e=r.track,i={eastM:r.eastM,northM:r.northM,altitudeM:0,headingDeg:r.headingDeg};if(!e||e.length===0)return i;if(e.length===1||t<=e[0].t)return vf(e[0],r);const n=e[e.length-1];if(t>=n.t)return vf(n,r);for(let s=0;s<e.length-1;s++){const a=e[s],o=e[s+1];if(t<a.t||t>o.t)continue;const c=o.t-a.t,l=c===0?0:(t-a.t)/c;return{eastM:a.eastM+(o.eastM-a.eastM)*l,northM:a.northM+(o.northM-a.northM)*l,altitudeM:(a.altitudeM??0)+((o.altitudeM??0)-(a.altitudeM??0))*l,headingDeg:a.headingDeg??r.headingDeg}}return i}function vf(r,t){return{eastM:r.eastM,northM:r.northM,altitudeM:r.altitudeM??0,headingDeg:r.headingDeg??t.headingDeg}}class Vo{static BY_KIND={car:{cylinders:4,idleRpm:800,kmhPer1000Rpm:[8,14,21,29,37,45],shiftUpRpm:3e3,shiftDownRpm:1300,engineGain:.6,roadGain:.5,roughness:.15},generic:{cylinders:4,idleRpm:800,kmhPer1000Rpm:[8,14,21,29,37,45],shiftUpRpm:3e3,shiftDownRpm:1300,engineGain:.6,roadGain:.5,roughness:.15},van:{cylinders:4,idleRpm:750,kmhPer1000Rpm:[7,12,19,27,35,42],shiftUpRpm:2600,shiftDownRpm:1200,engineGain:.8,roadGain:.7,roughness:.45},truck:{cylinders:6,idleRpm:600,kmhPer1000Rpm:[5,8,12,17,23,30,38,48],shiftUpRpm:1900,shiftDownRpm:1e3,engineGain:1,roadGain:.9,roughness:.55},motorcycle:{cylinders:2,idleRpm:1100,kmhPer1000Rpm:[12,18,24,30,35,40],shiftUpRpm:6e3,shiftDownRpm:2500,engineGain:.9,roadGain:.3,roughness:.3}};static of(t){return Vo.BY_KIND[t??"generic"]??Vo.BY_KIND.generic}}const yg=Math.PI/180,El=111320;function Je(r,t,e,i){const n=El*Math.cos(e*yg),s=(r-e)*El;return{x:(t-i)*n,z:-s}}function xn(r,t,e,i){const n=El*Math.cos(e*yg),s=-t,a=r;return{lat:e+s/El,lng:i+a/n}}class Ia{constructor(t,e){this.samples=t,this.startMs=e}static SAMPLE_MS=100;static STANDING_MPS=.3;static of(t,e,i,n){const s=Ia.SAMPLE_MS,a=[];for(let l=i;l<=n+s/2;l+=s){const h=e(l-s/2),u=e(l+s/2);if(!h||!u)return;a.push(Math.hypot(u.eastM-h.eastM,u.northM-h.northM)/(s/1e3))}const o=[];let c=1;for(let l=0;l<a.length;l++){const h=a[l],u=(a[Math.min(l+1,a.length-1)]-a[Math.max(l-1,0)])/(2*s/1e3);if(h<Ia.STANDING_MPS){c=1,o.push({speedMps:h,rpm:t.idleRpm,load:.1,gear:0});continue}const d=h*3.6,f=g=>d/t.kmhPer1000Rpm[g-1]*1e3;for(;c<t.kmhPer1000Rpm.length&&f(c)>t.shiftUpRpm;)c++;for(;c>1&&f(c)<t.shiftDownRpm;)c--;const p=Math.max(f(c),t.idleRpm*(1+.3*Math.min(1,h/3))),v=.15+.5*Math.min(1,(h/35)**2),m=u>.15?Math.min(1,v+u/2.5):u<-.3?.05:v;o.push({speedMps:h,rpm:p,load:m,gear:c})}return new Ia(o,i)}at(t){const e=(t-this.startMs)/Ia.SAMPLE_MS,i=Math.min(Math.max(Math.floor(e),0),this.samples.length-1),n=this.samples[i],s=this.samples[Math.min(i+1,this.samples.length-1)],a=Math.min(Math.max(e-i,0),1);return{speedMps:n.speedMps+(s.speedMps-n.speedMps)*a,rpm:n.rpm+(s.rpm-n.rpm)*a,load:n.load+(s.load-n.load)*a,gear:a<.5?n.gear:s.gear}}}class Al{drives=new Map;at(t,e){const i=[],n=t.event.place?.[0],s=l=>{const h=t.observerTrack.getInterpolatedPoseAt(l),u=h?.lat??n?.lat,d=h?.lng??n?.lng;if(u===void 0||d===void 0||!n)return;const f=Je(u,d,n.lat,n.lng);return{eastM:f.x,northM:-f.z}},a=Math.max(t.observerTrack.duration,(t.event.durationSeconds??0)*1e3),o=t.vehicle;if(o){const l=Vo.of(o.kind),h=this.drive(`observer:${o.kind}`,Al.trackKey(t),()=>Ia.of(l,s,0,a));h&&i.push({id:"observer",profile:l,state:h.at(e),noise:o.noise??1,inside:!0,windowsOpen:o.windowsOpen===!0,distanceM:0})}const c=s(e);for(const l of t.decor){if(!l.engine||!c)continue;const h=Vo.of(l.engine.kind),u=v=>{const m=Go(l,v);return{eastM:m.eastM,northM:m.northM}},d=this.drive(`decor:${l.id}`,Al.decorKey(l,a),()=>Ia.of(h,u,0,a));if(!d)continue;const f=Go(l,e),p=Math.hypot(f.eastM-c.eastM,f.northM-c.northM,f.altitudeM);i.push({id:`decor:${l.id}`,profile:h,state:d.at(e),noise:l.engine.noise??1,inside:!1,windowsOpen:!0,distanceM:p})}return i}drive(t,e,i){const n=this.drives.get(t);if(n&&n.key===e)return n.drive;const s=i();return this.drives.set(t,{key:e,drive:s}),s}static trackKey(t){return t.observerTrack.allKeyframes.map(i=>`${i.t}:${i.pose.lat}:${i.pose.lng}`).join(";")}static decorKey(t,e){return`${e}|${t.eastM},${t.northM}|`+(t.track??[]).map(i=>`${i.t}:${i.eastM}:${i.northM}`).join(";")}}const u0=1e3,_v=.65,d0={cloudCover:0,cloudDarkness:0,precipitationType:"none",precipitationIntensity:0,windDirectionDeg:0,windSpeed:0,storm:!1};function Tl(r){if(r.cloudLayers!==void 0)return r.cloudLayers;const t=[],e=r.lowerCloudCover??r.cloudCover;return e>0&&t.push({id:"lower",type:"cumulus",baseM:r.cloudBaseM??u0,thicknessM:650,coverage:e,sizeM:1400,density:1,darkness:r.cloudDarkness}),(r.highCloudCover??0)>0&&t.push({id:"cirrus",type:"cirrus",baseM:8e3,thicknessM:400,coverage:r.highCloudCover,sizeM:2200,density:.35,darkness:r.cloudDarkness,iceCrystalAlignment:r.iceCrystalAlignment}),t}function Mf(r,t,e,i,n,s){const a=i?.lat!==void 0&&i.lng!==void 0&&n?.lat!==void 0&&n.lng!==void 0?Je(n.lat,n.lng,i.lat,i.lng):{x:0,z:0},o=Math.max(0,r),c=[0,...t.allKeyframes.map(l=>l.t).filter(l=>l>0&&l<o),o];for(let l=1;l<c.length;l++){const h=c[l-1],u=c[l]-h;if(u===0)continue;const d=32;for(let f=0;f<=d;f++){const p=t.getInterpolatedWeatherAt(h+u*f/d)??e,v=s===void 0?void 0:p.cloudLayers?.find(y=>y.id===s),m=(v?.windDirectionDeg??p.windDirectionDeg)*Math.PI/180,g=f===0||f===d?1:f%2===0?2:4,_=(v?.windSpeed??p.windSpeed)*u/1e3/d/3*g;a.x-=Math.sin(m)*_,a.z+=Math.cos(m)*_}}return a}const Sv=`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ContrailSystem-CQsI1Z1v.js","./ContrailGrowth-CuAzwIoc.js","./trafficRuntime-B1Tm75lS.js"])))=>i.map(i=>d[i]);
2
+ const pv="modulepreload",mv=function(r,t){return new URL(r,t).href},ff={},an=function(t,e,i){let n=Promise.resolve();if(e&&e.length>0){let a=function(h){return Promise.all(h.map(u=>Promise.resolve(u).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};const o=document.getElementsByTagName("link"),c=document.querySelector("meta[property=csp-nonce]"),l=c?.nonce||c?.getAttribute("nonce");n=a(e.map(h=>{if(h=mv(h,i),h in ff)return;ff[h]=!0;const u=h.endsWith(".css"),d=u?'[rel="stylesheet"]':"";if(!!i)for(let v=o.length-1;v>=0;v--){const m=o[v];if(m.href===h&&(!u||m.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${h}"]${d}`))return;const p=document.createElement("link");if(p.rel=u?"stylesheet":pv,u||(p.as="script"),p.crossOrigin="",p.href=h,l&&p.setAttribute("nonce",l),document.head.appendChild(p),u)return new Promise((v,m)=>{p.addEventListener("load",v),p.addEventListener("error",()=>m(new Error(`Unable to preload CSS for ${h}`)))})}))}function s(a){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=a,window.dispatchEvent(o),!o.defaultPrevented)throw a}return n.then(a=>{for(const o of a||[])o.status==="rejected"&&s(o.reason);return t().catch(s)})};class Fa{static sessionDeclared=!1;static unlock(t){if(Fa.declarePlayback(),t.state!=="running")try{Promise.resolve(t.resume()).catch(()=>{});const e=t.createBufferSource();e.buffer=t.createBuffer(1,1,22050),e.connect(t.destination),e.start(0)}catch{}}static declarePlayback(){if(!(Fa.sessionDeclared||typeof navigator>"u")){Fa.sessionDeclared=!0;try{const t=navigator.audioSession;t&&(t.type="playback")}catch{}}}}const gv=.08,pf=.15,mf=2,vv=2e3;class Mv{context;noiseBuffer;voices=new Map;level=1;master;paused=!0;requested=[];resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("VehicleAudio: Web Audio unavailable, vehicles stay silent:",t);return}}Fa.unlock(this.context),this.apply()}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}setPaused(t){t!==this.paused&&(this.paused=t,this.apply())}setVoices(t){this.requested=t,this.apply()}dispose(){for(const t of[...this.voices.keys()])this.release(t);this.context?.close(),this.context=void 0,this.master=void 0}masterOf(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}apply(){const t=this.context;if(!t)return;const e=this.paused?[]:this.requested.filter(n=>n.inside||n.distanceM<vv),i=new Set(e.map(n=>n.id));for(const n of[...this.voices.keys()])i.has(n)||this.release(n);for(const n of e){const s=this.voices.get(n.id)??this.build(t,n.id);this.retarget(t,s,n)}}build(t,e){const i=t.createGain();i.gain.value=0;const n=t.createBiquadFilter();n.type="lowpass",n.connect(i).connect(this.masterOf(t));const s=t.createOscillator();s.type="sawtooth";const a=t.createOscillator();a.type="sine";const o=t.createGain(),c=t.createBiquadFilter();c.type="lowpass",c.frequency.value=900,s.connect(c),a.connect(c),c.connect(o).connect(n);const l=()=>{const b=t.createBufferSource();return b.buffer=this.noise(t),b.loop=!0,b.loopStart=Math.random()*mf*.5,b},h=l(),u=t.createBiquadFilter();u.type="bandpass",u.Q.value=4;const d=t.createGain();h.connect(u).connect(d).connect(n);const f=l(),p=t.createBiquadFilter();p.type="lowpass",p.frequency.value=600;const v=t.createGain();f.connect(p).connect(v).connect(n);const m=l(),g=t.createBiquadFilter();g.type="bandpass",g.frequency.value=1400,g.Q.value=.7;const _=t.createGain();m.connect(g).connect(_).connect(n);const y=[s,a,h,f,m];for(const b of y)b.start();const M={nodes:[i,n,o,c,u,d,p,v,g,_,...y],sources:y,firing:s,crank:a,knock:u,engineGain:o,knockGain:d,roadGain:v,windGain:_,cabin:n,output:i};return this.voices.set(e,M),M}retarget(t,e,{profile:i,state:n,noise:s,inside:a,windowsOpen:o,distanceM:c}){const l=t.currentTime,h=(_,y)=>_.setTargetAtTime(y,l,gv),u=n.rpm/60,d=u*i.cylinders/2,f=Math.min(1,n.rpm/i.shiftUpRpm),p=Math.min(1.5,n.speedMps/30);h(e.firing.frequency,d),h(e.crank.frequency,u),h(e.knock.frequency,d*3),h(e.engineGain.gain,i.engineGain*(.25+.75*n.load)*(.5+.5*f)*.3),h(e.knockGain.gain,i.roughness*(.2+.8*n.load)*.4),h(e.roadGain.gain,i.roadGain*p**1.5*.8);const v=!a||o;h(e.windGain.gain,p**2*(v?.5:.06));const m=a?o?3500:700:8e3/(1+c/60);h(e.cabin.frequency,m);const g=a?.5:Math.min(1,8/Math.max(c,1));h(e.output.gain,g*s)}release(t){const e=this.voices.get(t);if(!e)return;this.voices.delete(t);const i=this.context;i&&(e.output.gain.setTargetAtTime(0,i.currentTime,pf/3),setTimeout(()=>{for(const n of e.sources)try{n.stop()}catch{}for(const n of e.nodes)n.disconnect()},pf*1e3*3))}noise(t){if(this.noiseBuffer)return this.noiseBuffer;const e=t.createBuffer(1,t.sampleRate*mf,t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;return this.noiseBuffer=e,e}}const gf=2;function Mg(r){return r==="building"||r==="vehicle"}function xv(r,t){const e=r.litKeyframes;if(!e||e.length===0)return r.lit??!1;let i=e[0];for(const n of e){if(n.t>t)break;i=n}return i.lit}function yv(r,t){return r.pattern.kind==="steady"?!0:xg(r,t,t+1)>.5}function xg(r,t,e){if(r.pattern.kind==="steady")return 1;const{perMinute:i,dutyCycle:n,phase:s=0}=r.pattern,a=Math.min(Math.max(n,0),1);if(a===0||i<=0)return 0;const o=6e4/i,c=t/o+s,l=e/o+s;if(l<=c)return Math.min(Math.max(c-Math.floor(c),0),a)<a?1:0;const h=u=>Math.floor(u)*a+Math.min(u-Math.floor(u),a);return(h(l)-h(c))/(l-c)}function Go(r,t){const e=r.track,i={eastM:r.eastM,northM:r.northM,altitudeM:0,headingDeg:r.headingDeg};if(!e||e.length===0)return i;if(e.length===1||t<=e[0].t)return vf(e[0],r);const n=e[e.length-1];if(t>=n.t)return vf(n,r);for(let s=0;s<e.length-1;s++){const a=e[s],o=e[s+1];if(t<a.t||t>o.t)continue;const c=o.t-a.t,l=c===0?0:(t-a.t)/c;return{eastM:a.eastM+(o.eastM-a.eastM)*l,northM:a.northM+(o.northM-a.northM)*l,altitudeM:(a.altitudeM??0)+((o.altitudeM??0)-(a.altitudeM??0))*l,headingDeg:a.headingDeg??r.headingDeg}}return i}function vf(r,t){return{eastM:r.eastM,northM:r.northM,altitudeM:r.altitudeM??0,headingDeg:r.headingDeg??t.headingDeg}}class Vo{static BY_KIND={car:{cylinders:4,idleRpm:800,kmhPer1000Rpm:[8,14,21,29,37,45],shiftUpRpm:3e3,shiftDownRpm:1300,engineGain:.6,roadGain:.5,roughness:.15},generic:{cylinders:4,idleRpm:800,kmhPer1000Rpm:[8,14,21,29,37,45],shiftUpRpm:3e3,shiftDownRpm:1300,engineGain:.6,roadGain:.5,roughness:.15},van:{cylinders:4,idleRpm:750,kmhPer1000Rpm:[7,12,19,27,35,42],shiftUpRpm:2600,shiftDownRpm:1200,engineGain:.8,roadGain:.7,roughness:.45},truck:{cylinders:6,idleRpm:600,kmhPer1000Rpm:[5,8,12,17,23,30,38,48],shiftUpRpm:1900,shiftDownRpm:1e3,engineGain:1,roadGain:.9,roughness:.55},motorcycle:{cylinders:2,idleRpm:1100,kmhPer1000Rpm:[12,18,24,30,35,40],shiftUpRpm:6e3,shiftDownRpm:2500,engineGain:.9,roadGain:.3,roughness:.3}};static of(t){return Vo.BY_KIND[t??"generic"]??Vo.BY_KIND.generic}}const yg=Math.PI/180,El=111320;function Je(r,t,e,i){const n=El*Math.cos(e*yg),s=(r-e)*El;return{x:(t-i)*n,z:-s}}function xn(r,t,e,i){const n=El*Math.cos(e*yg),s=-t,a=r;return{lat:e+s/El,lng:i+a/n}}class Ia{constructor(t,e){this.samples=t,this.startMs=e}static SAMPLE_MS=100;static STANDING_MPS=.3;static of(t,e,i,n){const s=Ia.SAMPLE_MS,a=[];for(let l=i;l<=n+s/2;l+=s){const h=e(l-s/2),u=e(l+s/2);if(!h||!u)return;a.push(Math.hypot(u.eastM-h.eastM,u.northM-h.northM)/(s/1e3))}const o=[];let c=1;for(let l=0;l<a.length;l++){const h=a[l],u=(a[Math.min(l+1,a.length-1)]-a[Math.max(l-1,0)])/(2*s/1e3);if(h<Ia.STANDING_MPS){c=1,o.push({speedMps:h,rpm:t.idleRpm,load:.1,gear:0});continue}const d=h*3.6,f=g=>d/t.kmhPer1000Rpm[g-1]*1e3;for(;c<t.kmhPer1000Rpm.length&&f(c)>t.shiftUpRpm;)c++;for(;c>1&&f(c)<t.shiftDownRpm;)c--;const p=Math.max(f(c),t.idleRpm*(1+.3*Math.min(1,h/3))),v=.15+.5*Math.min(1,(h/35)**2),m=u>.15?Math.min(1,v+u/2.5):u<-.3?.05:v;o.push({speedMps:h,rpm:p,load:m,gear:c})}return new Ia(o,i)}at(t){const e=(t-this.startMs)/Ia.SAMPLE_MS,i=Math.min(Math.max(Math.floor(e),0),this.samples.length-1),n=this.samples[i],s=this.samples[Math.min(i+1,this.samples.length-1)],a=Math.min(Math.max(e-i,0),1);return{speedMps:n.speedMps+(s.speedMps-n.speedMps)*a,rpm:n.rpm+(s.rpm-n.rpm)*a,load:n.load+(s.load-n.load)*a,gear:a<.5?n.gear:s.gear}}}class Al{drives=new Map;at(t,e){const i=[],n=t.event.place?.[0],s=l=>{const h=t.observerTrack.getInterpolatedPoseAt(l),u=h?.lat??n?.lat,d=h?.lng??n?.lng;if(u===void 0||d===void 0||!n)return;const f=Je(u,d,n.lat,n.lng);return{eastM:f.x,northM:-f.z}},a=Math.max(t.observerTrack.duration,(t.event.durationSeconds??0)*1e3),o=t.vehicle;if(o){const l=Vo.of(o.kind),h=this.drive(`observer:${o.kind}`,Al.trackKey(t),()=>Ia.of(l,s,0,a));h&&i.push({id:"observer",profile:l,state:h.at(e),noise:o.noise??1,inside:!0,windowsOpen:o.windowsOpen===!0,distanceM:0})}const c=s(e);for(const l of t.decor){if(!l.engine||!c)continue;const h=Vo.of(l.engine.kind),u=v=>{const m=Go(l,v);return{eastM:m.eastM,northM:m.northM}},d=this.drive(`decor:${l.id}`,Al.decorKey(l,a),()=>Ia.of(h,u,0,a));if(!d)continue;const f=Go(l,e),p=Math.hypot(f.eastM-c.eastM,f.northM-c.northM,f.altitudeM);i.push({id:`decor:${l.id}`,profile:h,state:d.at(e),noise:l.engine.noise??1,inside:!1,windowsOpen:!0,distanceM:p})}return i}drive(t,e,i){const n=this.drives.get(t);if(n&&n.key===e)return n.drive;const s=i();return this.drives.set(t,{key:e,drive:s}),s}static trackKey(t){return t.observerTrack.allKeyframes.map(i=>`${i.t}:${i.pose.lat}:${i.pose.lng}`).join(";")}static decorKey(t,e){return`${e}|${t.eastM},${t.northM}|`+(t.track??[]).map(i=>`${i.t}:${i.eastM}:${i.northM}`).join(";")}}const u0=1e3,_v=.65,d0={cloudCover:0,cloudDarkness:0,precipitationType:"none",precipitationIntensity:0,windDirectionDeg:0,windSpeed:0,storm:!1};function Tl(r){if(r.cloudLayers!==void 0)return r.cloudLayers;const t=[],e=r.lowerCloudCover??r.cloudCover;return e>0&&t.push({id:"lower",type:"cumulus",baseM:r.cloudBaseM??u0,thicknessM:650,coverage:e,sizeM:1400,density:1,darkness:r.cloudDarkness}),(r.highCloudCover??0)>0&&t.push({id:"cirrus",type:"cirrus",baseM:8e3,thicknessM:400,coverage:r.highCloudCover,sizeM:2200,density:.35,darkness:r.cloudDarkness,iceCrystalAlignment:r.iceCrystalAlignment}),t}function Mf(r,t,e,i,n,s){const a=i?.lat!==void 0&&i.lng!==void 0&&n?.lat!==void 0&&n.lng!==void 0?Je(n.lat,n.lng,i.lat,i.lng):{x:0,z:0},o=Math.max(0,r),c=[0,...t.allKeyframes.map(l=>l.t).filter(l=>l>0&&l<o),o];for(let l=1;l<c.length;l++){const h=c[l-1],u=c[l]-h;if(u===0)continue;const d=32;for(let f=0;f<=d;f++){const p=t.getInterpolatedWeatherAt(h+u*f/d)??e,v=s===void 0?void 0:p.cloudLayers?.find(y=>y.id===s),m=(v?.windDirectionDeg??p.windDirectionDeg)*Math.PI/180,g=f===0||f===d?1:f%2===0?2:4,_=(v?.windSpeed??p.windSpeed)*u/1e3/d/3*g;a.x-=Math.sin(m)*_,a.z+=Math.cos(m)*_}}return a}const Sv=`
3
3
  <div class="stage" id="stage">
4
4
  <div class="frame" id="frame">
5
5
  <canvas id="scene-canvas"></canvas>
@@ -1361,9 +1361,9 @@ canvas[data-cursor="rotate"] {
1361
1361
  pointer-events: none;
1362
1362
  white-space: nowrap;
1363
1363
  }
1364
- `,hc=[{id:"eye",name:"Naked eye",flare:0,projection:"equidistant",stabilization:.97},{id:"rectilinear-lens",name:"Camera, unknown device",projection:"rectilinear",fNumber:8,fNumberRange:{min:2,max:22},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:8},apertureBlades:6},{id:"instamatic-126",name:"Instamatic, 126 film",projection:"rectilinear",frame:{widthMm:28,heightMm:28,focalLengthMm:43},fNumber:11,exposureSeconds:1/90,years:{from:1963,to:1988},apertureBlades:5,detailUm:20,medium:{kind:"negative",iso:64}},{id:"slr-35mm-50",name:"35 mm SLR, 50 mm lens",projection:"rectilinear",frame:{widthMm:36,heightMm:24,focalLengthMm:50},fNumber:8,fNumberRange:{min:2,max:16},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:3600},years:{from:1959},apertureBlades:6,detailUm:20,medium:{kind:"negative",iso:100}},{id:"slr-35mm-zoom",name:"35 mm SLR, 70-210 mm zoom",projection:"rectilinear",frame:{widthMm:36,heightMm:24,focalLengthMm:135,focalRangeMm:{minMm:70,maxMm:210}},fNumber:8,fNumberRange:{min:4,max:22},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:3600},apertureBlades:8,years:{from:1975},detailUm:20,medium:{kind:"negative",iso:100}},{id:"phone-landscape",name:"Phone, held sideways",projection:"rectilinear",frame:{widthMm:7.6,heightMm:5.7,focalLengthMm:5.7},fNumber:1.8,exposureSeconds:1/120,exposureRangeSeconds:{min:1/8e3,max:10},years:{from:2007},apertureBlades:void 0,detailUm:1.4,medium:{kind:"sensor",iso:100,autoExposure:!0}},{id:"phone-portrait",name:"Phone, held upright",projection:"rectilinear",frame:{widthMm:5.7,heightMm:7.6,focalLengthMm:5.7},fNumber:1.8,exposureSeconds:1/120,exposureRangeSeconds:{min:1/8e3,max:10},years:{from:2007},apertureBlades:void 0,detailUm:1.4,medium:{kind:"sensor",iso:100,autoExposure:!0}}];class mi{static get default(){return hc[0]}static byId(t){return hc.find(e=>e.id===t)??this.default}static UNAIDED_FIELD_DEG=60;static UNAIDED_ASPECT=16/9;static fieldOfViewDeg(t){const e=t.frame;return e?2*Math.atan(e.heightMm/(2*e.focalLengthMm))*180/Math.PI:mi.UNAIDED_FIELD_DEG}static aspectOf(t){const e=t.frame;return e?e.widthMm/e.heightMm:mi.UNAIDED_ASPECT}static frameWidthPx(t,e){return Math.round(e*mi.aspectOf(t))}static availableAt(t){return t===void 0?hc:hc.filter(e=>!e.years||t>=e.years.from&&(e.years.to===void 0||t<=e.years.to))}static fieldOfViewDegAt(t,e){const i=t.frame;if(!(!i||e<=0))return 2*Math.atan(i.heightMm/(2*e))*180/Math.PI}static focalLengthMmFor(t,e){const i=t.frame;if(!(!i||e<=0||e>=180))return i.heightMm/(2*Math.tan(e*Math.PI/360))}static bladesShowing(t,e){const i=e??t.fNumber;if(i===void 0||t.apertureBlades===void 0)return 0;const n=t.fNumberRange;return!n||n.max<=n.min?1:Math.max(0,Math.min(1,(i-n.min)/(n.max-n.min)))}static LENS_FLARE_ARTIFACTS=1;static flareArtifactsOf(t){return t.flare??mi.LENS_FLARE_ARTIFACTS}static starPointsOf(t){const e=t.apertureBlades;return e===void 0||e<3?0:e%2===0?e:e*2}}class Cr{constructor(t){this.points=t}static STATIONARY_M=5;static of(t){const e=[];for(const i of t.observerTrack.allKeyframes){const{lat:n,lng:s,headingDeg:a}=i.pose;n===void 0||s===void 0||e.push({t:i.t,lat:n,lng:s,headingDeg:a})}if(e.length===0){const i=t.event.place?.[0];if(!i)return;e.push({t:0,lat:i.lat,lng:i.lng})}return new Cr(e)}static TRAVEL_M=50;get travels(){return this.spanM>Cr.TRAVEL_M}get moved(){return this.spanM>Cr.STATIONARY_M}get spanM(){const t=this.box,e=(t.south+t.north)/2,i=(t.west+t.east)/2;return Math.max(Math.abs(Je(e,t.east,e,t.west).x),Math.abs(Je(t.north,i,t.south,i).z))}get center(){const t=this.box;return{lat:(t.south+t.north)/2,lng:(t.west+t.east)/2}}boundsAround(t,e){const{lat:i,lng:n}=this.center,s=Math.max(this.spanM*(1+e),t)/2;return{north:xn(0,-s,i,n).lat,south:xn(0,s,i,n).lat,east:xn(s,0,i,n).lng,west:xn(-s,0,i,n).lng}}get box(){const t=this.points.map(i=>i.lat),e=this.points.map(i=>i.lng);return{south:Math.min(...t),north:Math.max(...t),west:Math.min(...e),east:Math.max(...e)}}}class wn{constructor(t,e){this.rotationPassed=t,this.scale=e}static SWAY_M=.012;static BREATH_M=.003;static DRIFT_YAW_DEG=.5;static DRIFT_PITCH_DEG=.4;static DRIFT_ROLL_DEG=.3;static GAZE_DRIFT_SHARE=.35;static HAND_HELD_S=.5;static HZ=[.11,.23,.17,.29,.37,.07];static of(t){const e=t.event.tags?.includes("paralysis")||(t.exposure??0)>wn.HAND_HELD_S,i=t.sway??(e?0:1);if(i>0)return new wn(Math.max(1-(t.instrument.stabilization??0),wn.GAZE_DRIFT_SHARE),i)}offsetAt(t){const e=t/1e3,i=this.scale,n=(u,d)=>Math.sin(2*Math.PI*u*e+d),[s,a,o,c,l,h]=wn.HZ;return{eastM:i*wn.SWAY_M*(.7*n(s,.3)+.3*n(c,1.9)),northM:i*wn.SWAY_M*(.6*n(o,2.2)+.4*n(l,.8)),upM:i*wn.BREATH_M*n(a,0),yawDeg:i*this.rotationPassed*wn.DRIFT_YAW_DEG*(.6*n(h,1.1)+.4*n(c,2.7)),pitchDeg:i*this.rotationPassed*wn.DRIFT_PITCH_DEG*(.5*n(a,1.6)+.5*n(o,.4)),rollDeg:i*this.rotationPassed*wn.DRIFT_ROLL_DEG*n(s,2.9)}}}class be{constructor(t,e){this.stretches=t,this.rotationPassed=e}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STOP_LURCH_M=.035;static STOP_PITCH_DEG=3;static START_LURCH_M=.015;static START_PITCH_DEG=1.2;static JOLT_HZ=1.4;static JOLT_DECAY_S=.35;static JOLT_LASTS_MS=1500;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(t){const e=Cr.of(t);if(!e||e.points.length<2)return;const i=[];let n=0;for(let s=1;s<e.points.length;s++){const a=e.points[s-1],o=e.points[s],c=(o.t-a.t)/1e3;if(c<=0)continue;const l=Je(o.lat,o.lng,a.lat,a.lng),h=l.x,u=-l.z,d=Math.hypot(h,u),f=d/c,p=be.stepHzFor(f);i.push({startMs:a.t,endMs:o.t,speedMPerS:f,eastUnit:d>0?h/d:0,northUnit:d>0?u/d:0,stepHz:p,stepsBefore:n,rampsIn:!0,rampsOut:!0}),n+=p*c}for(let s=0;s<i.length;s++){const a=i[s-1],o=i[s+1];i[s].rampsIn=a===void 0||a.stepHz===0,i[s].rampsOut=o===void 0||o.stepHz===0}if(i.some(s=>s.stepHz>0))return new be(i,1-(t.instrument.stabilization??0))}static bodyAt(t,e,i=!1){const n=be.of(t)?.offsetAt(e)??be.STILL;return i?n:be.add(n,wn.of(t)?.offsetAt(e))}static stepHzFor(t){return t<be.SLOWEST_WALK_M_PER_S||t>be.FASTEST_WALK_M_PER_S?0:be.REFERENCE_STEP_HZ*Math.pow(t/be.REFERENCE_SPEED_M_PER_S,be.CADENCE_EXPONENT)}offsetAt(t){return be.add(this.cycleAt(t),this.joltAt(t))}joltAt(t){for(const e of this.stretches){if(e.stepHz===0)continue;const i=e.speedMPerS/be.REFERENCE_SPEED_M_PER_S,n=(o,c,l,h)=>{if(o<0||o>be.JOLT_LASTS_MS)return;const u=o/1e3,d=Math.exp(-u/be.JOLT_DECAY_S)*Math.sin(2*Math.PI*be.JOLT_HZ*u),f=h*c*i*d;return{eastM:f*e.eastUnit,northM:f*e.northUnit,upM:-Math.abs(f)*.3,rollDeg:0,pitchDeg:-h*l*i*d*this.rotationPassed,yawDeg:0}},s=e.rampsOut?n(t-e.endMs,be.STOP_LURCH_M,be.STOP_PITCH_DEG,1):void 0;if(s)return s;const a=e.rampsIn?n(t-e.startMs,be.START_LURCH_M,be.START_PITCH_DEG,-1):void 0;if(a)return a}}static add(t,e){return e?{eastM:t.eastM+e.eastM,northM:t.northM+e.northM,upM:t.upM+e.upM,rollDeg:t.rollDeg+e.rollDeg,pitchDeg:t.pitchDeg+e.pitchDeg,yawDeg:t.yawDeg+e.yawDeg}:t}cycleAt(t){const e=this.stretches.find(c=>t>=c.startMs&&t<=c.endMs);if(!e||e.stepHz===0)return be.STILL;const i=e.stepsBefore+e.stepHz*(t-e.startMs)/1e3,n=2*Math.PI*i,s=this.amplitudeAt(e,t),a=be.SWAY_M*s*Math.cos(n/2),o=s*this.rotationPassed*e.speedMPerS/be.REFERENCE_SPEED_M_PER_S;return{eastM:a*e.northUnit,northM:-a*e.eastUnit,upM:be.RISE_M_PER_M_PER_S*e.speedMPerS*s*Math.cos(n),rollDeg:be.HEAD_ROLL_DEG*o*Math.cos(n/2),pitchDeg:-1.25*o*Math.cos(n),yawDeg:be.HEAD_YAW_DEG*o*Math.cos(n/2)}}amplitudeAt(t,e){const i=1e3/t.stepHz,n=Math.min(i,(t.endMs-t.startMs)/2);if(n<=0)return 1;const s=e-t.startMs,a=t.endMs-e,o=Math.min(t.rampsIn?s/n:1,t.rampsOut?a/n:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class De{static MOON_ANGULAR_WIDTH_DEG=.5237;static CANVAS_WIDTH_PX=640;static CANVAS_HEIGHT_PX=360;static angularWidthDeg(t){return 2*Math.atan(t.sizeM/(2*t.distanceM))*180/Math.PI}static inMoons(t){return t/De.MOON_ANGULAR_WIDTH_DEG}static lerpAngular(t,e,i){if(!(!t||!e))return{widthDeg:t.widthDeg+(e.widthDeg-t.widthDeg)*i,heightDeg:t.heightDeg+(e.heightDeg-t.heightDeg)*i}}static sizeMAt(t,e){return 2*t*Math.tan(e*Math.PI/360)}static distanceMAt(t,e){return t/(2*Math.tan(e*Math.PI/360))}}function Av(r,t,e){if(!r||!t)return e<1?r:t;const i=((t.azimuthDeg-r.azimuthDeg)%360+540)%360-180;return{azimuthDeg:((r.azimuthDeg+i*e)%360+360)%360,altitudeDeg:r.altitudeDeg+(t.altitudeDeg-r.altitudeDeg)*e}}function Tv(r,t,e){const{bounds:i}=r;return t>=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height}function en(r,t,e){return r+(t-r)*e}function xf(r){const t=/^#([0-9a-f]{6})$/i.exec(r);if(!t)return;const e=parseInt(t[1],16);return[e>>16&255,e>>8&255,e&255]}function Rv(r){return`#${r.map(t=>Math.round(t).toString(16).padStart(2,"0")).join("")}`}function Dv(r,t,e){const i=xf(r),n=xf(t);return!i||!n?e<1?r:t:Rv([en(i[0],n[0],e),en(i[1],n[1],e),en(i[2],n[2],e)])}function Iv(r,t,e){const i={x:en(r.bounds.x,t.bounds.x,e),y:en(r.bounds.y,t.bounds.y,e),width:en(r.bounds.width,t.bounds.width,e),height:en(r.bounds.height,t.bounds.height,e)},n=en(r.angle,t.angle,e),s=en(r.transparency,t.transparency,e),a=en(r.haloScale,t.haloScale,e),o=en(r.blur??0,t.blur??0,e),c=en(r.brightness??0,t.brightness??0,e),l=Dv(r.color,t.color,e),h=De.lerpAngular(r.angular,t.angular,e),u=Av(r.aim,t.aim,e);return r.kind==="polygon"&&t.kind==="polygon"&&r.points.length===t.points.length?{...r,bounds:i,angle:n,transparency:s,haloScale:a,blur:o,brightness:c,color:l,angular:h,aim:u,points:r.points.map((d,f)=>({x:en(d.x,t.points[f].x,e),y:en(d.y,t.points[f].y,e)}))}:{...e<1?r:t,bounds:i,angle:n,transparency:s,haloScale:a,blur:o,brightness:c,color:l,angular:h,aim:u}}class wa{static DEFAULT_COLOR="#e8e6df";static complete(t,e=[]){const i=new Map;return t.map((n,s)=>({keyframe:n,index:s})).sort((n,s)=>n.keyframe.t-s.keyframe.t).map(({keyframe:n,index:s})=>({t:n.t,shapes:(n.shapes??[]).map((a,o)=>{const c=`timeline.keyframes.${s}.shapes.${o}.shape`,l=wa.completed(a,i.get(a.sourceId),c,e);return i.set(a.sourceId,l),{sourceId:a.sourceId,shape:l}})}))}static completed(t,e,i,n){const s=t.shape??{},a=e??wa.firstAppearance(s,i,n),o={...a};s.bounds&&e&&(e.aim||e.angular)&&!s.aim&&!s.angular&&n.push({kind:"pixels-over-angles",path:i}),s.bounds&&(s.aim||delete o.aim,s.angular||delete o.angular);const c=s.kind??a.kind??"oval",l={...o,...s,kind:c};if(c==="polygon"&&!l.points){n.push({kind:"defaulted",path:`${i}.points`,expected:"rectangle"});const{width:h,height:u}=l.bounds;return{...l,points:[{x:0,y:0},{x:h,y:0},{x:h,y:u},{x:0,y:u}]}}return l}static firstAppearance(t,e,i){return t.kind||i.push({kind:"defaulted",path:`${e}.kind`,expected:'"oval"'}),t.color||i.push({kind:"defaulted",path:`${e}.color`,expected:`"${wa.DEFAULT_COLOR}"`}),!t.bounds&&!t.aim&&i.push({kind:"unplaced",path:e}),!t.bounds&&!t.angular&&i.push({kind:"unsized",path:e}),{kind:t.kind??"oval",bounds:{...wa.NEUTRAL_BOUNDS},color:wa.DEFAULT_COLOR,angle:0,transparency:0,haloScale:0,selected:!1}}static NEUTRAL_BOUNDS={x:De.CANVAS_WIDTH_PX/2,y:De.CANVAS_HEIGHT_PX/2,width:1,height:1}}class Jl{keyframes=[];order=[];groups=[];addKeyframe(t,e){const i=this.findInsertIndex(t);if(this.keyframes[i]?.t===t){const n=new Set(e.map(s=>s.sourceId));this.keyframes[i]={t,shapes:[...this.keyframes[i].shapes.filter(s=>!n.has(s.sourceId)),...e]}}else this.keyframes.splice(i,0,{t,shapes:[...e]});for(const n of e)this.order.includes(n.sourceId)||this.order.push(n.sourceId)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getKeyframeAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e];return i?.t===t?i:void 0}getShapeAt(t,e){return this.getKeyframeAt(t)?.shapes.find(i=>i.sourceId===e)?.shape}getLatestShapeAt(t,e){let i=this.findInsertIndex(t);for(this.keyframes[i]?.t!==t&&(i-=1);i>=0;i--){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return n.shape}}getInterpolatedShapeAt(t,e){const i=this.findShapeAtOrBefore(t,e);if(i?.t===t)return i.shape;const n=this.findShapeAtOrAfter(t,e);return i?n?Iv(i.shape,n.shape,(t-i.t)/(n.t-i.t)):i.shape:n?.shape}findShapeAtOrBefore(t,e){let i=this.findInsertIndex(t);for(this.keyframes[i]?.t!==t&&(i-=1);i>=0;i--){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return{t:this.keyframes[i].t,shape:n.shape}}}findShapeAtOrAfter(t,e){for(let i=this.findInsertIndex(t);i<this.keyframes.length;i++){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return{t:this.keyframes[i].t,shape:n.shape}}}hitTest(t,e,i,n){const s=this.sourceIds;for(let a=s.length-1;a>=0;a--){if(n?.has(s[a]))continue;const o=this.getInterpolatedShapeAt(t,s[a]);if(o&&Tv(o,e,i))return{sourceId:s[a],shape:o}}}removeSource(t){for(let e=this.keyframes.length-1;e>=0;e--){const i=this.keyframes[e].shapes.filter(n=>n.sourceId!==t);i.length===0?this.keyframes.splice(e,1):i.length!==this.keyframes[e].shapes.length&&(this.keyframes[e]={t:this.keyframes[e].t,shapes:i})}this.order=this.order.filter(e=>e!==t),this.removeFromGroup(t)}group(t){if(!(t.length<2)){for(const e of t)this.removeFromGroup(e);this.groups.push([...t])}}ungroup(t){const e=this.groups.findIndex(i=>i.includes(t));e!==-1&&this.groups.splice(e,1)}groupMembers(t){return this.groups.find(e=>e.includes(t))}removeFromGroup(t){const e=this.groups.findIndex(n=>n.includes(t));if(e===-1)return;const i=this.groups[e].filter(n=>n!==t);i.length<2?this.groups.splice(e,1):this.groups[e]=i}bringToFront(t){const e=this.order.indexOf(t);e!==-1&&(this.order.splice(e,1),this.order.push(t))}sendToBack(t){const e=this.order.indexOf(t);e!==-1&&(this.order.splice(e,1),this.order.unshift(t))}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get sourceIds(){return[...this.order]}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes,order:this.order,groups:this.groups}}static fromJSON(t,e){const i=new Jl;for(const n of wa.complete(t.keyframes??[],e))i.addKeyframe(n.t,n.shapes);if(t.order){const n=i.order.filter(s=>!t.order.includes(s));i.order=[...t.order,...n]}return t.groups&&(i.groups=t.groups.map(n=>n.filter(s=>i.order.includes(s))).filter(n=>n.length>=2)),i}}function Cv(r,t,e){return Math.max(t,Math.min(e,r))}function Pv(r,t,e){const i=((t-r)%360+540)%360-180;return((r+i*e)%360+360)%360}function Za(r,t,e){return r+(t-r)*e}function Lv(r,t,e){return{lat:r.lat===void 0||t.lat===void 0?void 0:Za(r.lat,t.lat,e),lng:r.lng===void 0||t.lng===void 0?void 0:Za(r.lng,t.lng,e),elevationM:Za(r.elevationM,t.elevationM,e),headingDeg:r.headingDeg===void 0||t.headingDeg===void 0?void 0:Pv(r.headingDeg,t.headingDeg,e),pitchDeg:Za(r.pitchDeg,t.pitchDeg,e),rollDeg:Za(r.rollDeg??0,t.rollDeg??0,e),fovDeg:Za(r.fovDeg,t.fovDeg,e),fNumber:r.fNumber,focusDistanceM:r.focusDistanceM}}class Ua{static at(t,e,i,n,s){const a=t[i],c=t[i+1]-a;if(c<=0)return e[i];const l=Ua.tangent(t,e,i,s),h=Ua.tangent(t,e,i+1,s),u=(n-a)/c,d=u*u,f=d*u;return(2*f-3*d+1)*e[i]+(f-2*d+u)*c*l+(-2*f+3*d)*e[i+1]+(f-d)*c*h}static BRAKE_S=.8;static paced(t,e,i,n){if(!i&&!n)return t;const s=e>0?Math.min(.5,Ua.BRAKE_S/e):.5;if(i&&n){const o=1/(1-s);return t<=s?o*t*t/(2*s):t>=1-s?1-o*(1-t)*(1-t)/(2*s):o*(t-s/2)}const a=o=>{const c=1/(1-s/2);if(o<=1-s)return c*o;const l=o-(1-s);return c*(1-s)+c*(l-l*l/(2*s))};return n?a(t):1-a(1-t)}static tangent(t,e,i,n){const s=t.length-1,a=f=>(e[f+1]-e[f])/(t[f+1]-t[f]||1);if(i===0)return n?0:a(0);if(i===s)return n?0:a(s-1);const o=a(i-1),c=a(i);if(o*c<=0)return 0;const l=t[i]-t[i-1],h=t[i+1]-t[i],u=2*h+l,d=h+2*l;return(u+d)/(u/o+d/c)}}class Wo{keyframes=[];addKeyframe(t,e){const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,pose:e}:this.keyframes.splice(i,0,{t,pose:e})}clear(){this.keyframes.length=0}removeKeyframeAt(t){const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getLatestPoseAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].pose:void 0}getInterpolatedPoseAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.pose;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];if(!i)return n?.pose;if(!n)return i.pose;const s=Lv(i.pose,n.pose,Cv((t-i.t)/(n.t-i.t),0,1));return this.humanly(e-1,t,s)}humanly(t,e,i){const n=Math.max(0,t-1),s=Math.min(this.keyframes.length-1,t+2),a=this.keyframes.slice(n,s+1),o=t-n,c=a.map(y=>y.t),l=(y,M)=>{const b=a.map(w=>y(w.pose));if(!b.some(w=>w===void 0))return Ua.at(c,b,o,e,M)},h=a.map(y=>y.pose.headingDeg);let u;if(h.every(y=>y!==void 0)){const y=[h[0]];for(let M=1;M<h.length;M++)y.push(y[M-1]+((h[M]-h[M-1])%360+540)%360-180);u=(Ua.at(c,y,o,e,!0)%360+360)%360}const d=this.keyframes[t],f=this.keyframes[t+1],p=(y,M)=>y.lat===M.lat&&y.lng===M.lng&&y.elevationM===M.elevationM,v=!p(d.pose,f.pose),m=v&&t>0&&p(this.keyframes[t-1].pose,d.pose),g=v&&t+2<this.keyframes.length&&p(f.pose,this.keyframes[t+2].pose);let _;if(m||g){const y=Ua.paced((e-d.t)/(f.t-d.t),(f.t-d.t)/1e3,m,g),M=(b,w)=>b===void 0||w===void 0?void 0:b+(w-b)*y;_={lat:M(d.pose.lat,f.pose.lat),lng:M(d.pose.lng,f.pose.lng),elevationM:M(d.pose.elevationM,f.pose.elevationM)}}return{...i,lat:_?_.lat:l(y=>y.lat,!1)??i.lat,lng:_?_.lng:l(y=>y.lng,!1)??i.lng,elevationM:_?_.elevationM:l(y=>y.elevationM,!1)??i.elevationM,headingDeg:u??i.headingDeg,pitchDeg:l(y=>y.pitchDeg,!0)??i.pitchDeg,rollDeg:l(y=>y.rollDeg??0,!0)??i.rollDeg,fovDeg:l(y=>y.fovDeg,!0)??i.fovDeg}}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Wo;for(const i of t.keyframes)e.addKeyframe(i.t,i.pose);return e}}class js{static MAX_CHANGE_PER_S=.05;points;followed;constructor(t){let e="none",i=0;this.points=t.map(({t:n,weather:s})=>(s.precipitationType!=="none"&&(e=s.precipitationType,i=s.precipitationIntensity),{t:n,lastFalling:e,lastFallingIntensity:i,intensity:s.precipitationType==="none"?0:s.precipitationIntensity,type:s.precipitationType})),this.followed=[];for(let n=0;n<this.points.length;n++){if(n===0){this.followed.push(this.points[0].intensity);continue}const s=this.points[n-1],a=this.points[n];this.followed.push(js.follow(this.followed[n-1],s.intensity,a.intensity,(a.t-s.t)/1e3,(a.t-s.t)/1e3))}}at(t){if(this.points.length===0||t<this.points[0].t)return;let e=this.points.length-1;for(;e>0&&this.points[e].t>t;)e--;const i=this.points[e],n=this.points[e+1],s=n?js.follow(this.followed[e],i.intensity,n.intensity,(n.t-i.t)/1e3,(t-i.t)/1e3):js.follow(this.followed[e],i.intensity,i.intensity,1,(t-i.t)/1e3);return{type:js.typeBetween(i,n,t,s),intensity:s,character:js.characterBetween(i,n,t)}}static characterBetween(t,e,i){return t.type==="none"?e&&e.type!=="none"?e.intensity:t.lastFallingIntensity:!e||e.type==="none"?t.intensity:t.intensity+(e.intensity-t.intensity)*(i-t.t)/(e.t-t.t||1)}static typeBetween(t,e,i,n){return t.type==="none"?e&&e.type!=="none"&&i>t.t?e.type:n>0?t.lastFalling:"none":e&&e.type==="none"&&n<=0?"none":t.type}static follow(t,e,i,n,s){const a=js.MAX_CHANGE_PER_S,o=n>0?(i-e)/n:0,c=u=>e+o*Math.min(Math.max(u,0),n);let l=t,h=0;for(let u=0;u<8&&h<s;u++){const d=c(h)-l;if(Math.abs(d)<1e-9){const y=h<n?o:0;if(Math.abs(y)<=a){const b=h<n?Math.min(s,n):s;l=c(b),h=b;continue}const M=Math.min(s,n);l+=Math.sign(y)*a*(M-h),h=M;continue}const f=Math.sign(d),p=h<n?o:0,v=a-f*p,m=v>0?h+Math.abs(d)/v:1/0,g=h<n?n:1/0,_=Math.min(s,m,g);l+=f*a*(_-h),h=_,_===m&&(l=c(h))}return Math.min(1,Math.max(0,l))}}function Be(r,t,e){return r+(t-r)*e}function f0(r,t,e){const i=((t-r)%360+540)%360-180;return((r+i*e)%360+360)%360}function Ov(r,t,e){return Math.max(t,Math.min(e,r))}function Nv(r=[],t=[],e){if(!(!r.length&&!t.length))return[...new Set([...r.map(i=>i.id),...t.map(i=>i.id)])].map(i=>{const n=r.find(c=>c.id===i),s=t.find(c=>c.id===i),a=n??{...s,density:0},o=s??{...n,density:0};return{...a,eastM:Be(a.eastM,o.eastM,e),northM:Be(a.northM,o.northM,e),baseM:Be(a.baseM,o.baseM,e),thicknessM:Be(a.thicknessM,o.thicknessM,e),widthM:Be(a.widthM,o.widthM,e),depthM:Be(a.depthM,o.depthM,e),rotationDeg:f0(a.rotationDeg,o.rotationDeg,e),density:Be(a.density,o.density,e),darkness:Be(a.darkness??0,o.darkness??0,e)}})}function Fv(r,t,e){if(r.cloudLayers===void 0&&t.cloudLayers===void 0)return;const i=Tl(r),n=Tl(t);return e>=1?n.map(a=>({...a})):[...new Set([...i.map(a=>a.id),...n.map(a=>a.id)])].map(a=>{const o=i.find(u=>u.id===a),c=n.find(u=>u.id===a),l=o??{...c,coverage:0},h=c??{...o,coverage:0};return{...l,instances:Nv(o?.instances,c?.instances,e),baseM:Be(l.baseM,h.baseM,e),thicknessM:Be(l.thicknessM,h.thicknessM,e),coverage:Be(l.coverage,h.coverage,e),sizeM:Be(l.sizeM,h.sizeM,e),density:Be(l.density,h.density,e),darkness:Be(l.darkness??r.cloudDarkness,h.darkness??t.cloudDarkness,e),iceCrystalAlignment:l.iceCrystalAlignment===void 0||h.iceCrystalAlignment===void 0?void 0:Be(l.iceCrystalAlignment,h.iceCrystalAlignment,e),windSpeed:l.windSpeed===void 0&&h.windSpeed===void 0?void 0:Be(l.windSpeed??r.windSpeed,h.windSpeed??t.windSpeed,e),windDirectionDeg:l.windDirectionDeg===void 0&&h.windDirectionDeg===void 0?void 0:f0(l.windDirectionDeg??r.windDirectionDeg,h.windDirectionDeg??t.windDirectionDeg,e)}})}function Uv(r,t,e){return{cloudLayers:Fv(r,t,e),cloudCover:Be(r.cloudCover,t.cloudCover,e),cloudDarkness:Be(r.cloudDarkness,t.cloudDarkness,e),highCloudCover:r.highCloudCover===void 0||t.highCloudCover===void 0?void 0:Be(r.highCloudCover,t.highCloudCover,e),iceCrystalAlignment:r.iceCrystalAlignment===void 0||t.iceCrystalAlignment===void 0?void 0:Be(r.iceCrystalAlignment,t.iceCrystalAlignment,e),lowerCloudCover:r.lowerCloudCover===void 0||t.lowerCloudCover===void 0?void 0:Be(r.lowerCloudCover,t.lowerCloudCover,e),cloudBaseM:r.cloudBaseM===void 0||t.cloudBaseM===void 0?void 0:Be(r.cloudBaseM,t.cloudBaseM,e),relativeHumidity:r.relativeHumidity===void 0||t.relativeHumidity===void 0?void 0:Be(r.relativeHumidity,t.relativeHumidity,e),precipitationType:e<1?r.precipitationType:t.precipitationType,precipitationIntensity:Be(r.precipitationIntensity,t.precipitationIntensity,e),windDirectionDeg:f0(r.windDirectionDeg,t.windDirectionDeg,e),windSpeed:Be(r.windSpeed,t.windSpeed,e),storm:e<1?r.storm:t.storm}}class Xo{keyframes=[];ramp;addKeyframe(t,e){this.ramp=void 0;const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,weather:e}:this.keyframes.splice(i,0,{t,weather:e})}clear(){this.ramp=void 0,this.keyframes.length=0}removeKeyframeAt(t){this.ramp=void 0;const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getLatestWeatherAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].weather:void 0}getInterpolatedWeatherAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.weather;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];return i?n?Uv(i.weather,n.weather,Ov((t-i.t)/(n.t-i.t),0,1)):i.weather:n?.weather}getActualWeatherAt(t){const e=this.getInterpolatedWeatherAt(t);if(!e)return;const i=(this.ramp??=new js(this.keyframes)).at(t);if(!i)return e;const{type:n,intensity:s,character:a}=i,o=a>0?Math.min(1,s/a):n==="none"?0:1;return{...e,precipitationType:n,precipitationIntensity:a,precipitationAmount:o}}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Xo;for(const i of t.keyframes)e.addKeyframe(i.t,i.weather);return e}}class Yo{keyframes=[];addKeyframe(t,e){const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,sound:e}:this.keyframes.splice(i,0,{t,sound:e})}clear(){this.keyframes.length=0}removeKeyframeAt(t){const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}getLatestSoundAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].sound:void 0}getInterpolatedSoundAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.sound;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];if(!i)return n?.sound;if(!n)return i.sound;const s=(t-i.t)/(n.t-i.t);return this.lerp(i.sound,n.sound,Math.max(0,Math.min(1,s)))}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Yo;for(const i of t.keyframes)e.addKeyframe(i.t,i.sound);return e}lerp(t,e,i){return{kind:i<1?t.kind:e.kind,volume:t.volume+(e.volume-t.volume)*i,pitchHz:t.pitchHz+(e.pitchHz-t.pitchHz)*i,src:i<1?t.src:e.src}}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}}const kv=100,zv={kind:"none",volume:0,pitchHz:kv};class Tn{constructor(t){this.entries=t}static empty(){return new Tn(new Map)}get size(){return this.entries.size}at(t){return this.entries.get(t)}paths(){return[...this.entries.keys()]}set(t,e){e.basis==="stated"&&e.rationale===void 0?this.entries.delete(t):this.entries.set(t,e)}clear(t){for(const e of this.entries.keys())(e===t||e.startsWith(`${t}.`))&&this.entries.delete(e)}static strip(t){const e=new Tn(new Map);return{recording:Tn.stripValue(t,[],e),provenance:e}}static restore(t,e){if(e.size===0)return t;const i=structuredClone(t);for(const n of e.paths()){const s=e.at(n),a=n.split("."),o=Tn.holderOf(i,a);if(!o)continue;const c=a[a.length-1],l=o[c];l!==void 0&&(s.of!==void 0&&JSON.stringify(s.of)!==JSON.stringify(l)||(o[c]={value:l,...s.basis==="stated"?{}:{basis:s.basis},...s.rationale===void 0?{}:{rationale:s.rationale}}))}return i}static isWrapper(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&"value"in t}static stripValue(t,e,i){return Tn.isWrapper(t)?(i.set(e.join("."),{basis:t.basis??"stated",...t.rationale===void 0?{}:{rationale:t.rationale},of:t.value}),Tn.stripValue(t.value,e,i)):Array.isArray(t)?t.map((n,s)=>Tn.stripValue(n,[...e,String(s)],i)):typeof t=="object"&&t!==null?Object.fromEntries(Object.entries(t).map(([n,s])=>[n,Tn.stripValue(s,[...e,n],i)])):t}static holderOf(t,e){let i=t;for(const n of e.slice(0,-1)){if(typeof i!="object"||i===null)return;i=i[n]}return typeof i=="object"&&i!==null?i:void 0}}function zu(r){if(r.year!==void 0)return Date.UTC(r.year,(r.month??1)-1,r.day??1,r.hour??0,r.minute??0,r.second??0)}function yf(r){return(((r.day??0)*24+(r.hour??0))*60+(r.minute??0))*6e4+(r.second??0)*1e3}const Bv=["year","month","day","hour","minute"],Hv=["day","hour","minute"];function _f(r,t){return t.filter(e=>r[e]!==void 0).join(",")}function Gv(r){if(r.durationSeconds!==void 0)return r.durationSeconds*1e3;if(!r.time||!r.endTime)return;const t=r.time.year!==void 0&&r.endTime.year!==void 0,e=t?Bv:Hv,i=_f(r.time,e);if(!(i===""||i!==_f(r.endTime,e)))return t?zu(r.endTime)-zu(r.time):yf(r.endTime)-yf(r.time)}class jl{constructor(t,e,i,n,s,a,o,c,l=[],h,u,d,f=[],p=[],v=[],m=[]){this.event=t,this.timeline=e,this.observerTrack=i,this.weatherTrack=n,this.soundTrack=s,this.observer=a,this.id=o,this.weather=c,this.decor=l,this.weatherSource=h,this.instrumentId=u,this.exposureSeconds=d,this.milestones=f,this.references=p,this.roads=v,this.traces=m}provenance=Tn.empty();loadIssues=[];account;sources;interpretation;sway;lightPollution;iso;vehicle;get observerCount(){return 1+this.decor.filter(t=>t.kind==="observer").length}get exposure(){return this.exposureSeconds??this.instrument.exposureSeconds}get instrument(){return mi.byId(this.instrumentId)}static create(t,e,i){return new jl({eventType:"sighting",time:t,place:e},new Jl,new Wo,new Xo,new Yo,i)}}const Vv=0,Wv=0;function Ze(r,t){const e=r.observerTrack.getInterpolatedPoseAt(t);if(e)return e;const i=r.event.place?.[0];if(i)return{lat:i.lat,lng:i.lng,elevationM:Vv,headingDeg:void 0,pitchDeg:Wv,fovDeg:mi.fieldOfViewDeg(r.instrument)}}function eo(r,t){return r.weatherTrack.getInterpolatedWeatherAt(t)??r.weather??d0}function uc(r,t){return r.weatherTrack.getActualWeatherAt(t)??r.weather??d0}function Xv(r,t){return r.soundTrack.getInterpolatedSoundAt(t)??zv}class Yv{constructor(t,e){this.timeline=t,this.onFrame=e}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const t=()=>{if(this.state!=="playing")return;const e=performance.now();if(this.currentT+=(e-this.lastWallTime)*this.playbackRate,this.lastWallTime=e,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t)};this.rafId=requestAnimationFrame(t)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(t){this.currentT=Math.max(0,Math.min(t,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(t){const e=new Map;for(const i of this.timeline.sourceIds){const n=this.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}this.onFrame(t,e)}}const Sg=["nw","n","ne","e","se","s","sw","w"],qv=24,dc=8,$v=3,Kv=8;function fc(r,t,e){const i=r.x-t.x,n=r.y-t.y,s=Math.cos(e),a=Math.sin(e);return{x:t.x+i*s-n*a,y:t.y+i*a+n*s}}function io(r){return{x:r.x+r.width/2,y:r.y+r.height/2}}const Zv={nw:{left:!0,top:!0},n:{top:!0},ne:{right:!0,top:!0},e:{right:!0},se:{right:!0,bottom:!0},s:{bottom:!0},sw:{left:!0,bottom:!0},w:{left:!0}};class pn{static handlePointsFor(t){const{x:e,y:i,width:n,height:s}=t.bounds,a={nw:{x:e,y:i},n:{x:e+n/2,y:i},ne:{x:e+n,y:i},e:{x:e+n,y:i+s/2},se:{x:e+n,y:i+s},s:{x:e+n/2,y:i+s},sw:{x:e,y:i+s},w:{x:e,y:i+s/2},rotate:{x:e+n/2,y:i-qv}},o=io(t.bounds),c={};for(const l of Object.keys(a))c[l]=fc(a[l],o,t.angle);return c}static hitTestHandle(t,e,i=8,n=[...Sg,"rotate"]){const s=pn.handlePointsFor(t);for(const a of n)if(Math.hypot(e.x-s[a].x,e.y-s[a].y)<=i)return a}static HANDLE_DIRECTION_DEG={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315};static resizeAxisFor(t,e){const n=((pn.HANDLE_DIRECTION_DEG[t]+e*180/Math.PI)%180+180)%180/45,s=["ew","nwse","ns","nesw"];return s[Math.round(n)%s.length]}static resizeBounds(t,e,i,n){const s=io(t),a=fc(n,s,-e),{x:o,y:c,width:l,height:h}=t,u=Zv[i];let d=o,f=c,p=o+l,v=c+h;return u.left&&(d=Math.min(a.x,p-dc)),u.right&&(p=Math.max(a.x,d+dc)),u.top&&(f=Math.min(a.y,v-dc)),u.bottom&&(v=Math.max(a.y,f+dc)),{x:d,y:f,width:p-d,height:v-f}}static resizeShape(t,e,i){if(e==="rotate")throw new Error("resizeShape does not accept the rotate handle");const{width:n,height:s}=t.bounds,a=pn.resizeBounds(t.bounds,t.angle,e,i);if(t.kind==="oval")return{...t,bounds:a};const o=n===0?1:a.width/n,c=s===0?1:a.height/s;return{...t,bounds:a,points:t.points.map(l=>({x:l.x*o,y:l.y*c}))}}static rotateShape(t,e){const i=io(t.bounds),n=Math.atan2(e.y-i.y,e.x-i.x)+Math.PI/2;return{...t,angle:n}}static groupBoundsFor(t){const e=Math.min(...t.map(a=>a.x)),i=Math.min(...t.map(a=>a.y)),n=Math.max(...t.map(a=>a.x+a.width)),s=Math.max(...t.map(a=>a.y+a.height));return{x:e,y:i,width:n-e,height:s-i}}static vertexPointsFor(t){const e=io(t.bounds);return t.points.map(i=>fc({x:t.bounds.x+i.x,y:t.bounds.y+i.y},e,t.angle))}static hitTestVertex(t,e,i=Kv){const n=pn.vertexPointsFor(t);let s,a=i;return n.forEach((o,c)=>{const l=Math.hypot(e.x-o.x,e.y-o.y);l<=a&&(a=l,s=c)}),s}static toLocalPoint(t,e){const i=io(t.bounds),n=fc(e,i,-t.angle);return{x:n.x-t.bounds.x,y:n.y-t.bounds.y}}static moveVertex(t,e,i){const n=t.points.map((u,d)=>d===e?pn.toLocalPoint(t,i):u),s=Math.min(...n.map(u=>u.x)),a=Math.min(...n.map(u=>u.y)),o=Math.max(...n.map(u=>u.x)),c=Math.max(...n.map(u=>u.y)),l={x:t.bounds.x+s,y:t.bounds.y+a,width:o-s,height:c-a},h=n.map(u=>({x:u.x-s,y:u.y-a}));return{...t,bounds:l,points:h}}static insertVertexNear(t,e){const i=pn.toLocalPoint(t,e),{points:n}=t;let s=n.length-1,a=1/0;for(let c=0;c<n.length;c++){const l=n[c],h=n[(c+1)%n.length],u=pn.distanceToSegment(i,l,h);u<a&&(a=u,s=c)}const o=[...n.slice(0,s+1),i,...n.slice(s+1)];return{...t,points:o}}static distanceToSegment(t,e,i){const n=i.x-e.x,s=i.y-e.y,a=n*n+s*s,o=a===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*s)/a)),c=e.x+o*n,l=e.y+o*s;return Math.hypot(t.x-c,t.y-l)}static deleteVertex(t,e){return t.points.length<=$v?t:{...t,points:t.points.filter((i,n)=>n!==e)}}}const Bu=6,pc=Bu/2,Sf=20,bf=24,wf=9,Ef=6,Af=7,Tf=6,Jn=4;class qo{constructor(t){this.ctx=t}starPoints=0;roll=0;clear(t,e){this.ctx.clearRect(0,0,t,e)}static paintExtent(t){const{x:e,y:i,width:n,height:s}=t.bounds,a=e+n/2,o=i+s/2,c=t.angle%(2*Math.PI)!==0,l=Math.hypot(n,s)/2,h=c?l:n/2,u=c?l:s/2,d=Math.max(n,s)/2,f=t.brightness??0,p=f>0?Math.max(d*(1+wf*f),Tf*f)-d:0,v=f>0?d*(1+Af*f)-d:0,m=3*bf*(t.blur??0)+1.5*Sf*t.haloScale,g=Math.max(p,v,0)+m+2;return{x:a-h-g,y:o-u-g,width:2*(h+g),height:2*(u+g)}}paintInto(t,e,i,n=!1){this.ctx.save(),this.ctx.scale(i,i),this.ctx.translate(-e.x,-e.y);const s=t.selected?{...t,selected:!1}:t;n?this.paintGhost(s,1.5):this.paintShape(s),this.ctx.restore()}paintShape(t){this.ctx.save(),this.ctx.globalAlpha=1-t.transparency;const e=t.blur??0;e>0&&(this.ctx.filter=`blur(${(bf*e).toFixed(2)}px)`);const i=t.brightness??0;i>0&&this.paintDazzle(t,i),t.haloScale>0&&this.paintHalo(t),this.paintBase(t),this.ctx.restore(),t.selected&&this.paintSelectionHandles(t)}setStarPoints(t){this.starPoints=Math.max(0,Math.floor(t))}setRoll(t){this.roll=t}paintDazzle(t,e){const{x:i,y:n,width:s,height:a}=t.bounds,o=i+s/2,c=n+a/2,l=Math.max(s,a)/2,h=Math.max(l*(1+wf*e),Tf*e);if(h<=0)return;this.ctx.save(),this.ctx.globalCompositeOperation="lighter";const u=this.ctx.createRadialGradient(o,c,0,o,c,h);for(let d=0;d<=Ef;d++){const f=d/Ef,p=1/(1+24*f*f);this.ctx.globalAlpha=1,u.addColorStop(f,this.withAlpha(t.color,p*e*.55))}if(this.ctx.fillStyle=u,this.ctx.beginPath(),this.ctx.arc(o,c,h,0,2*Math.PI),this.ctx.fill(),this.starPoints>0){const d=l*(1+Af*e);this.ctx.lineWidth=Math.max(1,l*.12),this.ctx.lineCap="round";for(let f=0;f<this.starPoints;f++){const p=f/this.starPoints*Math.PI*2+this.roll,v=o+Math.cos(p)*d,m=c+Math.sin(p)*d,g=this.ctx.createLinearGradient(o,c,v,m);g.addColorStop(0,this.withAlpha(t.color,e*.55)),g.addColorStop(.35,this.withAlpha(t.color,e*.22)),g.addColorStop(1,this.withAlpha(t.color,0)),this.ctx.strokeStyle=g,this.ctx.beginPath(),this.ctx.moveTo(o,c),this.ctx.lineTo(v,m),this.ctx.stroke()}}this.ctx.restore()}dazzledFill(t,e){if(e<=0)return t.color;const i=/^#([0-9a-f]{6})$/i.exec(t.color.trim());if(!i)return t.color;const n=Number.parseInt(i[1],16),s=a=>Math.round(a+(255-a)*e);return`rgb(${s(n>>16&255)}, ${s(n>>8&255)}, ${s(n&255)})`}withAlpha(t,e){const i=Math.max(0,Math.min(1,e)),n=/^#([0-9a-f]{6})$/i.exec(t.trim());if(!n)return t;const s=Number.parseInt(n[1],16);return`rgba(${s>>16&255}, ${s>>8&255}, ${s&255}, ${i.toFixed(3)})`}paintBase(t){this.ctx.fillStyle=this.dazzledFill(t,t.brightness??0),this.tracePath(t),this.ctx.fill()}paintGhost(t,e){this.ctx.save(),this.tracePath(t),this.ctx.setLineDash([e*3,e*2]),this.ctx.lineWidth=e,this.ctx.strokeStyle=t.color,this.ctx.stroke(),this.ctx.restore()}tracePath(t){if(this.ctx.beginPath(),t.kind==="oval"){const{x:e,y:i,width:n,height:s}=t.bounds,a=n/2,o=s/2;this.ctx.ellipse(e+a,i+o,a,o,t.angle,0,2*Math.PI)}else{const{x:e,y:i,width:n,height:s}=t.bounds;this.ctx.save(),this.ctx.translate(e+n/2,i+s/2),this.ctx.rotate(t.angle),this.ctx.translate(-n/2,-s/2),t.points.forEach((a,o)=>{o===0?this.ctx.moveTo(a.x,a.y):this.ctx.lineTo(a.x,a.y)}),this.ctx.closePath(),this.ctx.restore()}}paintHalo(t){this.ctx.save(),this.ctx.shadowColor=t.color,this.ctx.shadowBlur=Sf*t.haloScale,this.paintBase(t),this.ctx.restore()}paintSelectionHandles(t){this.paintHandleFrame(pn.handlePointsFor(t),{includeRotate:!0}),t.kind==="polygon"&&this.paintVertexHandles(t)}paintVertexHandles(t){this.ctx.fillStyle="#39f";for(const e of pn.vertexPointsFor(t))this.ctx.beginPath(),this.ctx.ellipse(e.x,e.y,Jn,Jn,0,0,2*Math.PI),this.ctx.fill()}paintMemberOutline(t){this.paintOutline(pn.handlePointsFor(t))}paintSelectionOnly(t){this.paintSelectionHandles(t)}paintPictureFrame(t,e,i){const n=this.ctx;if(n.save(),t&&t.length===4){n.strokeStyle="#39f",n.lineWidth=1.5,n.setLineDash([6,4]),n.beginPath(),n.moveTo(t[0].x,t[0].y);for(const s of t.slice(1))n.lineTo(s.x,s.y);n.closePath(),n.stroke(),n.setLineDash([])}for(const s of e){const a=qo.landmarkColour(s.residualDeg),o=s.selected?3:2;s.selected&&(n.strokeStyle="#fff",n.lineWidth=o+3,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Jn+2,Jn+2,0,0,2*Math.PI),n.stroke()),s.scene&&(n.strokeStyle=a,n.lineWidth=1,n.beginPath(),n.moveTo(s.picture.x,s.picture.y),n.lineTo(s.scene.x,s.scene.y),n.stroke(),n.fillStyle=a,n.beginPath(),n.ellipse(s.scene.x,s.scene.y,Jn,Jn,0,0,2*Math.PI),n.fill()),n.strokeStyle=a,n.lineWidth=o,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Jn+2,Jn+2,0,0,2*Math.PI),n.stroke(),this.paintLabel(s.label,s.picture.x+Jn+5,s.picture.y-Jn-2,a)}i&&this.paintLabel(i,8,8,"#fff",13),n.restore()}static landmarkColour(t){return t===void 0?"#ffb000":t<=1?"#3c3":t<=3?"#ffb000":"#f33"}paintLabel(t,e,i,n,s=11){const a=this.ctx;a.save(),a.font=`${s}px system-ui, sans-serif`,a.textBaseline="top";const o=a.measureText(t).width;a.fillStyle="rgba(0, 0, 0, 0.6)",a.fillRect(e-3,i-2,o+6,s+4),a.fillStyle=n,a.fillText(t,e,i),a.restore()}paintGroupHandles(t){this.paintHandleFrame(pn.handlePointsFor({bounds:t,angle:0}),{includeRotate:!0})}paintOutline(t){this.ctx.strokeStyle="lightgray",this.ctx.beginPath(),this.ctx.moveTo(t.nw.x,t.nw.y),this.ctx.lineTo(t.ne.x,t.ne.y),this.ctx.lineTo(t.se.x,t.se.y),this.ctx.lineTo(t.sw.x,t.sw.y),this.ctx.closePath(),this.ctx.stroke()}paintHandleFrame(t,{includeRotate:e}){this.paintOutline(t),this.ctx.fillStyle="lightgray";for(const i of Sg){const n=t[i];this.ctx.fillRect(n.x-pc,n.y-pc,Bu,Bu)}e&&(this.ctx.beginPath(),this.ctx.moveTo(t.n.x,t.n.y),this.ctx.lineTo(t.rotate.x,t.rotate.y),this.ctx.stroke(),this.ctx.beginPath(),this.ctx.ellipse(t.rotate.x,t.rotate.y,pc+1,pc+1,0,0,2*Math.PI),this.ctx.fill())}}const Rf=.05,Df=.08,If=2,Cf=3,Jv=14,jv=.02;class Qv{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",t);return}}Fa.unlock(this.context)}setSound(t){if(this.requested=t,!this.context)return;const e=this.keyFor(t);if(!e){this.silence();return}if(this.voice?.key!==e){this.stopVoice();const i=++this.voiceToken;e.startsWith("src:")?this.buildRecordedVoice(t.src,e,i):this.voice=this.buildSynthesizedVoice(t,e)}this.applyTo(this.voice,t)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(t){if(!(t.volume<=0))return t.src?`src:${t.src}`:t.kind==="none"?void 0:t.kind}applyTo(t,e){const i=this.context;if(!t||!i)return;const n=i.currentTime;t.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,e.volume))*t.gainScale,n,Rf);for(const{param:s,ratio:a}of t.pitch)s.setTargetAtTime(Math.min(e.pitchHz*a,i.sampleRate/2-1),n,Rf)}buildSynthesizedVoice(t,e){const i=this.context;if(i)switch(t.kind){case"hum":return this.buildHum(i,e);case"whistle":return this.buildWhistle(i,e);case"rumble":return this.buildRumble(i,e);case"crackle":return this.buildCrackle(i,e);default:return}}buildHum(t,e){const i=t.createOscillator();i.type="sawtooth";const n=t.createOscillator();n.type="sawtooth";const s=t.createBiquadFilter();s.type="lowpass",s.Q.value=1;const a=t.createGain();return a.gain.value=0,i.connect(s),n.connect(s),s.connect(a).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.16,pitch:[{param:i.frequency,ratio:1},{param:n.frequency,ratio:1.006},{param:s.frequency,ratio:6}]}}buildWhistle(t,e){const i=t.createOscillator();i.type="sine";const n=t.createOscillator();n.type="sine",n.frequency.value=5;const s=t.createGain(),a=t.createGain();return a.gain.value=0,n.connect(s).connect(i.frequency),i.connect(a).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.22,pitch:[{param:i.frequency,ratio:1},{param:s.gain,ratio:.012}]}}buildRumble(t,e){const i=t.createBufferSource();i.buffer=this.brownNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="lowpass",n.Q.value=.8;const s=t.createGain();return s.gain.value=0,i.connect(n).connect(s).connect(this.output(t)),i.start(),{key:e,nodes:[n,s],sources:[i],volumeParam:s.gain,gainScale:1.4,pitch:[{param:n.frequency,ratio:1}]}}buildCrackle(t,e){const i=t.createBufferSource();i.buffer=this.whiteNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="bandpass",n.Q.value=1.2;const s=t.createGain();s.gain.value=0;const a=t.createBufferSource();a.buffer=this.crackleEnvelope(t),a.loop=!0;const o=t.createGain();return o.gain.value=0,a.connect(o).connect(s.gain),i.connect(n).connect(s).connect(this.output(t)),i.start(),a.start(),{key:e,nodes:[n,s,o],sources:[i,a],volumeParam:o.gain,gainScale:.9,pitch:[{param:n.frequency,ratio:4}]}}async buildRecordedVoice(t,e,i){const n=this.context;if(!n)return;let s;try{s=await this.getBuffer(t)}catch(c){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",c);return}if(i!==this.voiceToken||!this.context)return;const a=n.createBufferSource();a.buffer=s,a.loop=!0;const o=n.createGain();o.gain.value=0,a.connect(o).connect(this.output(n)),a.start(),this.voice={key:e,nodes:[o],sources:[a],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(t){const e=this.context;if(!e)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}whiteNoise(t){if(!this.noiseBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*If),t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;this.noiseBuffer=e}return this.noiseBuffer}brownNoise(t){const e=t.createBuffer(1,Math.floor(t.sampleRate*If),t.sampleRate),i=e.getChannelData(0);let n=0,s=0;for(let a=0;a<i.length;a++)n=(n+.02*(Math.random()*2-1))/1.02,i[a]=n,s=Math.max(s,Math.abs(n));if(s>0)for(let a=0;a<i.length;a++)i[a]/=s;return e}crackleEnvelope(t){if(!this.crackleBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*Cf),t.sampleRate),i=e.getChannelData(0),n=Math.max(1,Math.floor(jv*t.sampleRate)),s=Math.round(Cf*Jv);for(let a=0;a<s;a++){const o=Math.floor(Math.random()*i.length),c=.4+Math.random()*.6;for(let l=0;l<n&&o+l<i.length;l++)i[o+l]=Math.max(i[o+l],c*(1-l/n))}this.crackleBuffer=e}return this.crackleBuffer}stopVoice(){const t=this.voice,e=this.context;if(this.voice=void 0,!t||!e)return;const i=e.currentTime;t.volumeParam.cancelScheduledValues(i),t.volumeParam.setTargetAtTime(0,i,Df/3);const n=i+Df;for(const s of t.sources){s.onended=()=>{s.disconnect();for(const a of t.nodes)a.disconnect()};try{s.stop(n)}catch{s.disconnect();for(const a of t.nodes)a.disconnect()}}}}class Gt{static svg(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="currentColor"/></svg>`}static outline(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" stroke-linecap="round"/></svg>`}static solid(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="currentColor" fill-rule="evenodd"/></svg>`}static BOOKMARK="M6 3.5h12a.5.5 0 0 1 .5.5v16.5L12 16.8l-6.5 3.7V4a.5.5 0 0 1 .5-.5z";static PICTURE="M5 4h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z";static PICTURE_HILLS="M4.5 17.5l4.5-6 3 4 2.5-3 5 5z";static PIN="M12 21.5s-6.5-5.7-6.5-10.8a6.5 6.5 0 0 1 13 0c0 5.1-6.5 10.8-6.5 10.8z";static PIN_HOLE="M12 8.4a2.4 2.4 0 1 0 0 4.8 2.4 2.4 0 0 0 0-4.8z";static MILESTONES_OFF=Gt.outline(Gt.BOOKMARK);static MILESTONES_ON=Gt.solid(Gt.BOOKMARK);static PICTURES_OFF=Gt.outline(`${Gt.PICTURE}${Gt.PICTURE_HILLS}`);static PICTURES_ON=Gt.solid(`${Gt.PICTURE}${Gt.PICTURE_HILLS}`);static TRACE_LINE="M3 19.5l2.2-2.2 1.4 1.4L4.4 20.9zM8 14.5l2.2-2.2 1.4 1.4-2.2 2.2zM13 9.5l2.2-2.2 1.4 1.4-2.2 2.2z";static TRACE_MARK="M18.5 2.5l3.5 3.5-3.5 3.5-3.5-3.5z";static TRACES_OFF=Gt.outline(`${Gt.TRACE_LINE}${Gt.TRACE_MARK}`);static TRACES_ON=Gt.solid(`${Gt.TRACE_LINE}${Gt.TRACE_MARK}`);static MAP_OFF=Gt.outline(`${Gt.PIN}${Gt.PIN_HOLE}`);static MAP_ON=Gt.solid(`${Gt.PIN}${Gt.PIN_HOLE}`);static SHARE=Gt.outline("M14 4l7 7-7 7v-4.2C8.6 13.8 5.4 15.6 3.5 19c.6-5.6 3.4-9.6 10.5-10.8V4z");static FOLDED=Gt.svg("M15.4 7.4 14 6l-6 6 6 6 1.4-1.4L10.8 12z");static UNFOLDED=Gt.svg("M8.6 16.6 10 18l6-6-6-6-1.4 1.4 4.6 4.6z");static PLAY=Gt.svg("M7.4 5v14l11-7z");static PAUSE=Gt.svg("M6 5h4v14H6zM14 5h4v14h-4z");static VOLUME=Gt.svg("M2 9.5v5h3.5l4.5 4.5V5L5.5 9.5H2zm12.5 2.5A4 4 0 0 0 12.5 8.5v7A4 4 0 0 0 14.5 12zM12.5 4.2v2.1a6.5 6.5 0 0 1 0 11.4v2.1a8.6 8.6 0 0 0 0-15.6z");static MUTED=Gt.svg("M2 9.5v5h3.5l4.5 4.5V5L5.5 9.5H2zM15 9.8l1.4-1.4 2.6 2.6 2.6-2.6 1.4 1.4-2.6 2.6 2.6 2.6-1.4 1.4-2.6-2.6-2.6 2.6-1.4-1.4 2.6-2.6z");static ENTER_FULLSCREEN=Gt.svg("M5 5h5v2H7v3H5V5zm9 0h5v5h-2V7h-3V5zM5 14h2v3h3v2H5v-5zm12 0h2v5h-5v-2h3v-3z");static EXIT_FULLSCREEN=Gt.svg("M8 5h2v5H5V8h3V5zm6 0h2v3h3v2h-5V5zM5 14h5v5H8v-3H5v-2zm9 0h5v2h-3v3h-2v-5z")}function Oo(r){return[...r].sort((t,e)=>t.t-e.t)}function mh(r,t){let e;for(const i of Oo(r)){if(i.t>t)break;e=i}return e}const gh=Math.PI/180,mc=180/Math.PI;class Is{constructor(t,e,i){this.kind=t,this.canvasHeightPx=e,this.fovDeg=i;const n=i*gh/2;this.focalPx=t==="equidistant"?e/2/n:e/2/Math.tan(n)}focalPx;static of(t,e,i){return new Is(t.projection,e,i)}degToPx(t){const e=t*gh;return this.kind==="equidistant"?this.focalPx*e:2*this.focalPx*Math.tan(e/2)}pxToDeg(t){return this.kind==="equidistant"?t/this.focalPx*mc:2*Math.atan(t/(2*this.focalPx))*mc}angleDegToRadiusPx(t){const e=t*gh;return this.kind==="equidistant"?this.focalPx*e:this.focalPx*Math.tan(e)}halfWidthAngleDeg(t){return this.radiusPxToAngleDeg(this.canvasHeightPx*t/2)}radiusPxToAngleDeg(t){return this.kind==="equidistant"?t/this.focalPx*mc:Math.atan(t/this.focalPx)*mc}ofBounds(t){return{widthDeg:this.pxToDeg(t.width),heightDeg:this.pxToDeg(t.height)}}toBoundsSize(t){return{width:this.degToPx(t.widthDeg),height:this.degToPx(t.heightDeg)}}widthPx(t){return this.degToPx(De.angularWidthDeg(t))}}class sn{static fovOf(t,e){return Ze(t,e)?.fovDeg??mi.fieldOfViewDeg(t.instrument)}static toAngular(t){this.eachKeyframe(t,(e,i)=>({...e,angular:i.ofBounds(e.bounds)}))}static toBounds(t){this.eachKeyframe(t,(e,i)=>{if(!e.angular)return e;const{width:n,height:s}=i.toBoundsSize(e.angular),a={x:e.bounds.x+(e.bounds.width-n)/2,y:e.bounds.y+(e.bounds.height-s)/2,width:n,height:s};if(e.kind!=="polygon")return{...e,bounds:a};const o=e.bounds.width===0?1:n/e.bounds.width,c=e.bounds.height===0?1:s/e.bounds.height;return{...e,bounds:a,points:e.points.map(l=>({x:l.x*o,y:l.y*c}))}})}static toAim(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);if(s&&Math.abs(s.x-e.bounds.x)<sn.UNMOVED_PX&&Math.abs(s.y-e.bounds.y)<sn.UNMOVED_PX)return e;const a=this.aimFrom(t,i,n,e.bounds);return a?{...e,aim:a}:e})}static UNMOVED_PX=.01;static aimOf(t,e,i){const n=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,this.fovOf(t,e));return this.aimFrom(t,n,Ze(t,e),i)}static aimFrom(t,e,i,n){if(i?.headingDeg===void 0)return;const s=this.frameCentre(t),a=e.radiusPxToAngleDeg(n.x+n.width/2-s.x),o=e.radiusPxToAngleDeg(s.y-(n.y+n.height/2));return{azimuthDeg:((i.headingDeg+a)%360+360)%360,altitudeDeg:i.pitchDeg+o}}static toPosition(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);return s?{...e,bounds:{...e.bounds,...s}}:e})}static positionOf(t,e,i,n,s){if(s?.headingDeg===void 0)return;const a=this.frameCentre(t),o=this.shortestArc(e.azimuthDeg-s.headingDeg),c=e.altitudeDeg-s.pitchDeg;return{x:a.x+this.offAxisPx(n,o)-i.width/2,y:a.y-this.offAxisPx(n,c)-i.height/2}}static frameCentre(t){return{x:mi.frameWidthPx(t.instrument,De.CANVAS_HEIGHT_PX)/2,y:De.CANVAS_HEIGHT_PX/2}}static shortestArc(t){return(t%360+540)%360-180}static offAxisPx(t,e){return Math.abs(e)>=sn.OFF_CANVAS_DEG?Math.sign(e)*sn.OFF_CANVAS_PX:t.angleDegToRadiusPx(e)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(t,e,i){const n=mi.frameWidthPx(e,De.CANVAS_HEIGHT_PX)/2,s=mi.frameWidthPx(t.instrument,De.CANVAS_HEIGHT_PX)/2,a=De.CANVAS_HEIGHT_PX/2;for(const o of[...t.timeline.allKeyframes]){const c=this.fovOf(t,o.t),l=i?.get(o.t)??c,h=Is.of(e,De.CANVAS_HEIGHT_PX,l),u=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,c);t.timeline.addKeyframe(o.t,o.shapes.map(d=>{const{bounds:f}=d.shape,p=f.x+f.width/2-n,v=f.y+f.height/2-a,m=Math.hypot(p,v),g=m===0?1:u.angleDegToRadiusPx(h.radiusPxToAngleDeg(m))/m,_={...f,x:s+p*g-f.width/2,y:a+v*g-f.height/2};return{...d,shape:{...d.shape,bounds:_}}}))}this.toBounds(t)}static eachKeyframe(t,e){const{timeline:i}=t;for(const n of[...i.allKeyframes]){const s=Ze(t,n.t),a=this.fovOf(t,n.t),o=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,a);i.addKeyframe(n.t,n.shapes.map(c=>({...c,shape:e(c.shape,o,s)})))}}}function t2(r){return Tn.restore(e2(r),r.provenance)}function e2(r){return sn.toAngular(r),sn.toAim(r),{version:1,id:r.id,time:r.event.time,endTime:r.event.endTime,durationSeconds:r.event.durationSeconds,utcOffsetHours:r.event.utcOffsetHours,timeZone:r.event.timeZone,place:r.event.place,observer:r.observer,account:r.account,sources:r.sources?.length?r.sources:void 0,sway:r.sway,vehicle:r.vehicle,description:r.event.description,tags:r.event.tags,timeline:r.timeline.toJSON(),observerTrack:r.observerTrack.toJSON(),weatherTrack:r.weatherTrack.toJSON(),soundTrack:r.soundTrack.toJSON(),weather:r.weather,decor:r.decor,milestones:r.milestones.length>0?r.milestones:void 0,references:r.references.length>0?r.references:void 0,roads:r.roads.length>0?r.roads:void 0,traces:r.traces.length>0?r.traces:void 0,weatherSource:r.weatherSource,instrument:r.instrumentId,exposureSeconds:r.exposureSeconds,iso:r.iso,lightPollution:r.lightPollution,interpretation:r.interpretation}}function i2(r){const{recording:t,provenance:e}=Tn.strip(r),i=n2(t);return i.provenance=e,i}function n2(r){const t=[],e=new jl({eventType:"sighting",time:r.time,endTime:r.endTime,durationSeconds:r.durationSeconds,utcOffsetHours:r.utcOffsetHours,timeZone:r.timeZone,place:r.place,description:r.description,tags:r.tags},Jl.fromJSON(r.timeline,t),r.observerTrack?Wo.fromJSON(r.observerTrack):new Wo,r.weatherTrack?Xo.fromJSON(r.weatherTrack):new Xo,r.soundTrack?Yo.fromJSON(r.soundTrack):new Yo,r.observer&&{id:r.observer.id,title:r.observer.title,lastName:r.observer.lastName,firstNames:r.observer.firstNames},r.id,r.weather,r.decor??[],r.weatherSource,r.instrument,r.exposureSeconds??r.observerTrack?.keyframes.map(i=>i.pose.exposureSeconds).find(i=>i!==void 0),Oo(r.milestones??[]),r.references??[],r.roads??[],r.traces??[]);return e.account=r.account,e.sources=r.sources,e.sway=r.sway,e.iso=r.iso,e.lightPollution=r.lightPollution,e.vehicle=r.vehicle,e.interpretation=r.interpretation,e.loadIssues=t,sn.toBounds(e),sn.toPosition(e),e}class Xr{static EN={"unknown-key":"{path}: unknown key, ignored","wrong-type":"{path}: expected {expected}, found {found}","not-in-list":"{path}: {found} is not one of {expected}",defaulted:"{path}: missing, {expected} used",unplaced:"{path}: no aim (and no bounds), drawn at the middle of the view",unsized:"{path}: no angular size (and no bounds), drawn one pixel wide","pixels-over-angles":"{path}: bounds restated without aim or angular, so the shape follows the pixels"};static text(t,e=Xr.EN){return e[t.kind].replace("{path}",t.path).replace("{expected}",t.expected??"").replace("{found}",t.found??"")}static warn(t,e){if(t.length===0)return;const i=t.map(n=>` ${Xr.text(n)}`);console.warn(`UFO@home: ${t.length} problem(s) in ${e??"this recording"}:
1364
+ `,hc=[{id:"eye",name:"Naked eye",flare:0,projection:"equidistant",stabilization:.97},{id:"rectilinear-lens",name:"Camera, unknown device",projection:"rectilinear",fNumber:8,fNumberRange:{min:2,max:22},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:8},apertureBlades:6},{id:"instamatic-126",name:"Instamatic, 126 film",projection:"rectilinear",frame:{widthMm:28,heightMm:28,focalLengthMm:43},fNumber:11,exposureSeconds:1/90,years:{from:1963,to:1988},apertureBlades:5,detailUm:20,medium:{kind:"negative",iso:64}},{id:"slr-35mm-50",name:"35 mm SLR, 50 mm lens",projection:"rectilinear",frame:{widthMm:36,heightMm:24,focalLengthMm:50},fNumber:8,fNumberRange:{min:2,max:16},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:3600},years:{from:1959},apertureBlades:6,detailUm:20,medium:{kind:"negative",iso:100}},{id:"slr-35mm-zoom",name:"35 mm SLR, 70-210 mm zoom",projection:"rectilinear",frame:{widthMm:36,heightMm:24,focalLengthMm:135,focalRangeMm:{minMm:70,maxMm:210}},fNumber:8,fNumberRange:{min:4,max:22},exposureSeconds:1/250,exposureRangeSeconds:{min:1/1e3,max:3600},apertureBlades:8,years:{from:1975},detailUm:20,medium:{kind:"negative",iso:100}},{id:"phone-landscape",name:"Phone, held sideways",projection:"rectilinear",frame:{widthMm:7.6,heightMm:5.7,focalLengthMm:5.7},fNumber:1.8,exposureSeconds:1/120,exposureRangeSeconds:{min:1/8e3,max:10},years:{from:2007},apertureBlades:void 0,detailUm:1.4,medium:{kind:"sensor",iso:100,autoExposure:!0}},{id:"phone-portrait",name:"Phone, held upright",projection:"rectilinear",frame:{widthMm:5.7,heightMm:7.6,focalLengthMm:5.7},fNumber:1.8,exposureSeconds:1/120,exposureRangeSeconds:{min:1/8e3,max:10},years:{from:2007},apertureBlades:void 0,detailUm:1.4,medium:{kind:"sensor",iso:100,autoExposure:!0}}];class mi{static get default(){return hc[0]}static byId(t){return hc.find(e=>e.id===t)??this.default}static UNAIDED_FIELD_DEG=60;static UNAIDED_ASPECT=16/9;static fieldOfViewDeg(t){const e=t.frame;return e?2*Math.atan(e.heightMm/(2*e.focalLengthMm))*180/Math.PI:mi.UNAIDED_FIELD_DEG}static aspectOf(t){const e=t.frame;return e?e.widthMm/e.heightMm:mi.UNAIDED_ASPECT}static frameWidthPx(t,e){return Math.round(e*mi.aspectOf(t))}static availableAt(t){return t===void 0?hc:hc.filter(e=>!e.years||t>=e.years.from&&(e.years.to===void 0||t<=e.years.to))}static fieldOfViewDegAt(t,e){const i=t.frame;if(!(!i||e<=0))return 2*Math.atan(i.heightMm/(2*e))*180/Math.PI}static focalLengthMmFor(t,e){const i=t.frame;if(!(!i||e<=0||e>=180))return i.heightMm/(2*Math.tan(e*Math.PI/360))}static bladesShowing(t,e){const i=e??t.fNumber;if(i===void 0||t.apertureBlades===void 0)return 0;const n=t.fNumberRange;return!n||n.max<=n.min?1:Math.max(0,Math.min(1,(i-n.min)/(n.max-n.min)))}static LENS_FLARE_ARTIFACTS=1;static flareArtifactsOf(t){return t.flare??mi.LENS_FLARE_ARTIFACTS}static starPointsOf(t){const e=t.apertureBlades;return e===void 0||e<3?0:e%2===0?e:e*2}}class Cr{constructor(t){this.points=t}static STATIONARY_M=5;static of(t){const e=[];for(const i of t.observerTrack.allKeyframes){const{lat:n,lng:s,headingDeg:a}=i.pose;n===void 0||s===void 0||e.push({t:i.t,lat:n,lng:s,headingDeg:a})}if(e.length===0){const i=t.event.place?.[0];if(!i)return;e.push({t:0,lat:i.lat,lng:i.lng})}return new Cr(e)}static TRAVEL_M=50;get travels(){return this.spanM>Cr.TRAVEL_M}get moved(){return this.spanM>Cr.STATIONARY_M}get spanM(){const t=this.box,e=(t.south+t.north)/2,i=(t.west+t.east)/2;return Math.max(Math.abs(Je(e,t.east,e,t.west).x),Math.abs(Je(t.north,i,t.south,i).z))}get center(){const t=this.box;return{lat:(t.south+t.north)/2,lng:(t.west+t.east)/2}}boundsAround(t,e){const{lat:i,lng:n}=this.center,s=Math.max(this.spanM*(1+e),t)/2;return{north:xn(0,-s,i,n).lat,south:xn(0,s,i,n).lat,east:xn(s,0,i,n).lng,west:xn(-s,0,i,n).lng}}get box(){const t=this.points.map(i=>i.lat),e=this.points.map(i=>i.lng);return{south:Math.min(...t),north:Math.max(...t),west:Math.min(...e),east:Math.max(...e)}}}class wn{constructor(t,e){this.rotationPassed=t,this.scale=e}static SWAY_M=.012;static BREATH_M=.003;static DRIFT_YAW_DEG=.5;static DRIFT_PITCH_DEG=.4;static DRIFT_ROLL_DEG=.3;static GAZE_DRIFT_SHARE=.35;static HAND_HELD_S=.5;static HZ=[.11,.23,.17,.29,.37,.07];static of(t){const e=t.event.tags?.includes("paralysis")||(t.exposure??0)>wn.HAND_HELD_S,i=t.sway??(e?0:1);if(i>0)return new wn(Math.max(1-(t.instrument.stabilization??0),wn.GAZE_DRIFT_SHARE),i)}offsetAt(t){const e=t/1e3,i=this.scale,n=(u,d)=>Math.sin(2*Math.PI*u*e+d),[s,a,o,c,l,h]=wn.HZ;return{eastM:i*wn.SWAY_M*(.7*n(s,.3)+.3*n(c,1.9)),northM:i*wn.SWAY_M*(.6*n(o,2.2)+.4*n(l,.8)),upM:i*wn.BREATH_M*n(a,0),yawDeg:i*this.rotationPassed*wn.DRIFT_YAW_DEG*(.6*n(h,1.1)+.4*n(c,2.7)),pitchDeg:i*this.rotationPassed*wn.DRIFT_PITCH_DEG*(.5*n(a,1.6)+.5*n(o,.4)),rollDeg:i*this.rotationPassed*wn.DRIFT_ROLL_DEG*n(s,2.9)}}}class be{constructor(t,e){this.stretches=t,this.rotationPassed=e}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STOP_LURCH_M=.035;static STOP_PITCH_DEG=3;static START_LURCH_M=.015;static START_PITCH_DEG=1.2;static JOLT_HZ=1.4;static JOLT_DECAY_S=.35;static JOLT_LASTS_MS=1500;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(t){const e=Cr.of(t);if(!e||e.points.length<2)return;const i=[];let n=0;for(let s=1;s<e.points.length;s++){const a=e.points[s-1],o=e.points[s],c=(o.t-a.t)/1e3;if(c<=0)continue;const l=Je(o.lat,o.lng,a.lat,a.lng),h=l.x,u=-l.z,d=Math.hypot(h,u),f=d/c,p=be.stepHzFor(f);i.push({startMs:a.t,endMs:o.t,speedMPerS:f,eastUnit:d>0?h/d:0,northUnit:d>0?u/d:0,stepHz:p,stepsBefore:n,rampsIn:!0,rampsOut:!0}),n+=p*c}for(let s=0;s<i.length;s++){const a=i[s-1],o=i[s+1];i[s].rampsIn=a===void 0||a.stepHz===0,i[s].rampsOut=o===void 0||o.stepHz===0}if(i.some(s=>s.stepHz>0))return new be(i,1-(t.instrument.stabilization??0))}static bodyAt(t,e,i=!1){const n=be.of(t)?.offsetAt(e)??be.STILL;return i?n:be.add(n,wn.of(t)?.offsetAt(e))}static stepHzFor(t){return t<be.SLOWEST_WALK_M_PER_S||t>be.FASTEST_WALK_M_PER_S?0:be.REFERENCE_STEP_HZ*Math.pow(t/be.REFERENCE_SPEED_M_PER_S,be.CADENCE_EXPONENT)}offsetAt(t){return be.add(this.cycleAt(t),this.joltAt(t))}joltAt(t){for(const e of this.stretches){if(e.stepHz===0)continue;const i=e.speedMPerS/be.REFERENCE_SPEED_M_PER_S,n=(o,c,l,h)=>{if(o<0||o>be.JOLT_LASTS_MS)return;const u=o/1e3,d=Math.exp(-u/be.JOLT_DECAY_S)*Math.sin(2*Math.PI*be.JOLT_HZ*u),f=h*c*i*d;return{eastM:f*e.eastUnit,northM:f*e.northUnit,upM:-Math.abs(f)*.3,rollDeg:0,pitchDeg:-h*l*i*d*this.rotationPassed,yawDeg:0}},s=e.rampsOut?n(t-e.endMs,be.STOP_LURCH_M,be.STOP_PITCH_DEG,1):void 0;if(s)return s;const a=e.rampsIn?n(t-e.startMs,be.START_LURCH_M,be.START_PITCH_DEG,-1):void 0;if(a)return a}}static add(t,e){return e?{eastM:t.eastM+e.eastM,northM:t.northM+e.northM,upM:t.upM+e.upM,rollDeg:t.rollDeg+e.rollDeg,pitchDeg:t.pitchDeg+e.pitchDeg,yawDeg:t.yawDeg+e.yawDeg}:t}cycleAt(t){const e=this.stretches.find(c=>t>=c.startMs&&t<=c.endMs);if(!e||e.stepHz===0)return be.STILL;const i=e.stepsBefore+e.stepHz*(t-e.startMs)/1e3,n=2*Math.PI*i,s=this.amplitudeAt(e,t),a=be.SWAY_M*s*Math.cos(n/2),o=s*this.rotationPassed*e.speedMPerS/be.REFERENCE_SPEED_M_PER_S;return{eastM:a*e.northUnit,northM:-a*e.eastUnit,upM:be.RISE_M_PER_M_PER_S*e.speedMPerS*s*Math.cos(n),rollDeg:be.HEAD_ROLL_DEG*o*Math.cos(n/2),pitchDeg:-1.25*o*Math.cos(n),yawDeg:be.HEAD_YAW_DEG*o*Math.cos(n/2)}}amplitudeAt(t,e){const i=1e3/t.stepHz,n=Math.min(i,(t.endMs-t.startMs)/2);if(n<=0)return 1;const s=e-t.startMs,a=t.endMs-e,o=Math.min(t.rampsIn?s/n:1,t.rampsOut?a/n:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class De{static MOON_ANGULAR_WIDTH_DEG=.5237;static CANVAS_WIDTH_PX=640;static CANVAS_HEIGHT_PX=360;static angularWidthDeg(t){return 2*Math.atan(t.sizeM/(2*t.distanceM))*180/Math.PI}static inMoons(t){return t/De.MOON_ANGULAR_WIDTH_DEG}static lerpAngular(t,e,i){if(!(!t||!e))return{widthDeg:t.widthDeg+(e.widthDeg-t.widthDeg)*i,heightDeg:t.heightDeg+(e.heightDeg-t.heightDeg)*i}}static sizeMAt(t,e){return 2*t*Math.tan(e*Math.PI/360)}static distanceMAt(t,e){return t/(2*Math.tan(e*Math.PI/360))}}function Av(r,t,e){if(!r||!t)return e<1?r:t;const i=((t.azimuthDeg-r.azimuthDeg)%360+540)%360-180;return{azimuthDeg:((r.azimuthDeg+i*e)%360+360)%360,altitudeDeg:r.altitudeDeg+(t.altitudeDeg-r.altitudeDeg)*e}}function Tv(r,t,e){const{bounds:i}=r;return t>=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height}function en(r,t,e){return r+(t-r)*e}function xf(r){const t=/^#([0-9a-f]{6})$/i.exec(r);if(!t)return;const e=parseInt(t[1],16);return[e>>16&255,e>>8&255,e&255]}function Rv(r){return`#${r.map(t=>Math.round(t).toString(16).padStart(2,"0")).join("")}`}function Dv(r,t,e){const i=xf(r),n=xf(t);return!i||!n?e<1?r:t:Rv([en(i[0],n[0],e),en(i[1],n[1],e),en(i[2],n[2],e)])}function Iv(r,t,e){const i={x:en(r.bounds.x,t.bounds.x,e),y:en(r.bounds.y,t.bounds.y,e),width:en(r.bounds.width,t.bounds.width,e),height:en(r.bounds.height,t.bounds.height,e)},n=en(r.angle,t.angle,e),s=en(r.transparency,t.transparency,e),a=en(r.haloScale,t.haloScale,e),o=en(r.blur??0,t.blur??0,e),c=en(r.brightness??0,t.brightness??0,e),l=Dv(r.color,t.color,e),h=De.lerpAngular(r.angular,t.angular,e),u=Av(r.aim,t.aim,e);return r.kind==="polygon"&&t.kind==="polygon"&&r.points.length===t.points.length?{...r,bounds:i,angle:n,transparency:s,haloScale:a,blur:o,brightness:c,color:l,angular:h,aim:u,points:r.points.map((d,f)=>({x:en(d.x,t.points[f].x,e),y:en(d.y,t.points[f].y,e)}))}:{...e<1?r:t,bounds:i,angle:n,transparency:s,haloScale:a,blur:o,brightness:c,color:l,angular:h,aim:u}}class wa{static DEFAULT_COLOR="#e8e6df";static complete(t,e=[]){const i=new Map;return t.map((n,s)=>({keyframe:n,index:s})).sort((n,s)=>n.keyframe.t-s.keyframe.t).map(({keyframe:n,index:s})=>({t:n.t,shapes:(n.shapes??[]).map((a,o)=>{const c=`timeline.keyframes.${s}.shapes.${o}.shape`,l=wa.completed(a,i.get(a.sourceId),c,e);return i.set(a.sourceId,l),{sourceId:a.sourceId,shape:l}})}))}static completed(t,e,i,n){const s=t.shape??{},a=e??wa.firstAppearance(s,i,n),o={...a};s.bounds&&e&&(e.aim||e.angular)&&!s.aim&&!s.angular&&n.push({kind:"pixels-over-angles",path:i}),s.bounds&&(s.aim||delete o.aim,s.angular||delete o.angular);const c=s.kind??a.kind??"oval",l={...o,...s,kind:c};if(c==="polygon"&&!l.points){n.push({kind:"defaulted",path:`${i}.points`,expected:"rectangle"});const{width:h,height:u}=l.bounds;return{...l,points:[{x:0,y:0},{x:h,y:0},{x:h,y:u},{x:0,y:u}]}}return l}static firstAppearance(t,e,i){return t.kind||i.push({kind:"defaulted",path:`${e}.kind`,expected:'"oval"'}),t.color||i.push({kind:"defaulted",path:`${e}.color`,expected:`"${wa.DEFAULT_COLOR}"`}),!t.bounds&&!t.aim&&i.push({kind:"unplaced",path:e}),!t.bounds&&!t.angular&&i.push({kind:"unsized",path:e}),{kind:t.kind??"oval",bounds:{...wa.NEUTRAL_BOUNDS},color:wa.DEFAULT_COLOR,angle:0,transparency:0,haloScale:0,selected:!1}}static NEUTRAL_BOUNDS={x:De.CANVAS_WIDTH_PX/2,y:De.CANVAS_HEIGHT_PX/2,width:1,height:1}}class Jl{keyframes=[];order=[];groups=[];addKeyframe(t,e){const i=this.findInsertIndex(t);if(this.keyframes[i]?.t===t){const n=new Set(e.map(s=>s.sourceId));this.keyframes[i]={t,shapes:[...this.keyframes[i].shapes.filter(s=>!n.has(s.sourceId)),...e]}}else this.keyframes.splice(i,0,{t,shapes:[...e]});for(const n of e)this.order.includes(n.sourceId)||this.order.push(n.sourceId)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getKeyframeAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e];return i?.t===t?i:void 0}getShapeAt(t,e){return this.getKeyframeAt(t)?.shapes.find(i=>i.sourceId===e)?.shape}getLatestShapeAt(t,e){let i=this.findInsertIndex(t);for(this.keyframes[i]?.t!==t&&(i-=1);i>=0;i--){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return n.shape}}getInterpolatedShapeAt(t,e){const i=this.findShapeAtOrBefore(t,e);if(i?.t===t)return i.shape;const n=this.findShapeAtOrAfter(t,e);return i?n?Iv(i.shape,n.shape,(t-i.t)/(n.t-i.t)):i.shape:n?.shape}findShapeAtOrBefore(t,e){let i=this.findInsertIndex(t);for(this.keyframes[i]?.t!==t&&(i-=1);i>=0;i--){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return{t:this.keyframes[i].t,shape:n.shape}}}findShapeAtOrAfter(t,e){for(let i=this.findInsertIndex(t);i<this.keyframes.length;i++){const n=this.keyframes[i].shapes.find(s=>s.sourceId===e);if(n)return{t:this.keyframes[i].t,shape:n.shape}}}hitTest(t,e,i,n){const s=this.sourceIds;for(let a=s.length-1;a>=0;a--){if(n?.has(s[a]))continue;const o=this.getInterpolatedShapeAt(t,s[a]);if(o&&Tv(o,e,i))return{sourceId:s[a],shape:o}}}removeSource(t){for(let e=this.keyframes.length-1;e>=0;e--){const i=this.keyframes[e].shapes.filter(n=>n.sourceId!==t);i.length===0?this.keyframes.splice(e,1):i.length!==this.keyframes[e].shapes.length&&(this.keyframes[e]={t:this.keyframes[e].t,shapes:i})}this.order=this.order.filter(e=>e!==t),this.removeFromGroup(t)}group(t){if(!(t.length<2)){for(const e of t)this.removeFromGroup(e);this.groups.push([...t])}}ungroup(t){const e=this.groups.findIndex(i=>i.includes(t));e!==-1&&this.groups.splice(e,1)}groupMembers(t){return this.groups.find(e=>e.includes(t))}removeFromGroup(t){const e=this.groups.findIndex(n=>n.includes(t));if(e===-1)return;const i=this.groups[e].filter(n=>n!==t);i.length<2?this.groups.splice(e,1):this.groups[e]=i}bringToFront(t){const e=this.order.indexOf(t);e!==-1&&(this.order.splice(e,1),this.order.push(t))}sendToBack(t){const e=this.order.indexOf(t);e!==-1&&(this.order.splice(e,1),this.order.unshift(t))}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get sourceIds(){return[...this.order]}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes,order:this.order,groups:this.groups}}static fromJSON(t,e){const i=new Jl;for(const n of wa.complete(t.keyframes??[],e))i.addKeyframe(n.t,n.shapes);if(t.order){const n=i.order.filter(s=>!t.order.includes(s));i.order=[...t.order,...n]}return t.groups&&(i.groups=t.groups.map(n=>n.filter(s=>i.order.includes(s))).filter(n=>n.length>=2)),i}}function Cv(r,t,e){return Math.max(t,Math.min(e,r))}function Pv(r,t,e){const i=((t-r)%360+540)%360-180;return((r+i*e)%360+360)%360}function Za(r,t,e){return r+(t-r)*e}function Lv(r,t,e){return{lat:r.lat===void 0||t.lat===void 0?void 0:Za(r.lat,t.lat,e),lng:r.lng===void 0||t.lng===void 0?void 0:Za(r.lng,t.lng,e),elevationM:Za(r.elevationM,t.elevationM,e),headingDeg:r.headingDeg===void 0||t.headingDeg===void 0?void 0:Pv(r.headingDeg,t.headingDeg,e),pitchDeg:Za(r.pitchDeg,t.pitchDeg,e),rollDeg:Za(r.rollDeg??0,t.rollDeg??0,e),fovDeg:Za(r.fovDeg,t.fovDeg,e),fNumber:r.fNumber,focusDistanceM:r.focusDistanceM}}class Ua{static at(t,e,i,n,s){const a=t[i],c=t[i+1]-a;if(c<=0)return e[i];const l=Ua.tangent(t,e,i,s),h=Ua.tangent(t,e,i+1,s),u=(n-a)/c,d=u*u,f=d*u;return(2*f-3*d+1)*e[i]+(f-2*d+u)*c*l+(-2*f+3*d)*e[i+1]+(f-d)*c*h}static BRAKE_S=.8;static paced(t,e,i,n){if(!i&&!n)return t;const s=e>0?Math.min(.5,Ua.BRAKE_S/e):.5;if(i&&n){const o=1/(1-s);return t<=s?o*t*t/(2*s):t>=1-s?1-o*(1-t)*(1-t)/(2*s):o*(t-s/2)}const a=o=>{const c=1/(1-s/2);if(o<=1-s)return c*o;const l=o-(1-s);return c*(1-s)+c*(l-l*l/(2*s))};return n?a(t):1-a(1-t)}static tangent(t,e,i,n){const s=t.length-1,a=f=>(e[f+1]-e[f])/(t[f+1]-t[f]||1);if(i===0)return n?0:a(0);if(i===s)return n?0:a(s-1);const o=a(i-1),c=a(i);if(o*c<=0)return 0;const l=t[i]-t[i-1],h=t[i+1]-t[i],u=2*h+l,d=h+2*l;return(u+d)/(u/o+d/c)}}class Wo{keyframes=[];addKeyframe(t,e){const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,pose:e}:this.keyframes.splice(i,0,{t,pose:e})}clear(){this.keyframes.length=0}removeKeyframeAt(t){const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getLatestPoseAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].pose:void 0}getInterpolatedPoseAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.pose;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];if(!i)return n?.pose;if(!n)return i.pose;const s=Lv(i.pose,n.pose,Cv((t-i.t)/(n.t-i.t),0,1));return this.humanly(e-1,t,s)}humanly(t,e,i){const n=Math.max(0,t-1),s=Math.min(this.keyframes.length-1,t+2),a=this.keyframes.slice(n,s+1),o=t-n,c=a.map(y=>y.t),l=(y,M)=>{const b=a.map(w=>y(w.pose));if(!b.some(w=>w===void 0))return Ua.at(c,b,o,e,M)},h=a.map(y=>y.pose.headingDeg);let u;if(h.every(y=>y!==void 0)){const y=[h[0]];for(let M=1;M<h.length;M++)y.push(y[M-1]+((h[M]-h[M-1])%360+540)%360-180);u=(Ua.at(c,y,o,e,!0)%360+360)%360}const d=this.keyframes[t],f=this.keyframes[t+1],p=(y,M)=>y.lat===M.lat&&y.lng===M.lng&&y.elevationM===M.elevationM,v=!p(d.pose,f.pose),m=v&&t>0&&p(this.keyframes[t-1].pose,d.pose),g=v&&t+2<this.keyframes.length&&p(f.pose,this.keyframes[t+2].pose);let _;if(m||g){const y=Ua.paced((e-d.t)/(f.t-d.t),(f.t-d.t)/1e3,m,g),M=(b,w)=>b===void 0||w===void 0?void 0:b+(w-b)*y;_={lat:M(d.pose.lat,f.pose.lat),lng:M(d.pose.lng,f.pose.lng),elevationM:M(d.pose.elevationM,f.pose.elevationM)}}return{...i,lat:_?_.lat:l(y=>y.lat,!1)??i.lat,lng:_?_.lng:l(y=>y.lng,!1)??i.lng,elevationM:_?_.elevationM:l(y=>y.elevationM,!1)??i.elevationM,headingDeg:u??i.headingDeg,pitchDeg:l(y=>y.pitchDeg,!0)??i.pitchDeg,rollDeg:l(y=>y.rollDeg??0,!0)??i.rollDeg,fovDeg:l(y=>y.fovDeg,!0)??i.fovDeg}}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Wo;for(const i of t.keyframes)e.addKeyframe(i.t,i.pose);return e}}class js{static MAX_CHANGE_PER_S=.05;points;followed;constructor(t){let e="none",i=0;this.points=t.map(({t:n,weather:s})=>(s.precipitationType!=="none"&&(e=s.precipitationType,i=s.precipitationIntensity),{t:n,lastFalling:e,lastFallingIntensity:i,intensity:s.precipitationType==="none"?0:s.precipitationIntensity,type:s.precipitationType})),this.followed=[];for(let n=0;n<this.points.length;n++){if(n===0){this.followed.push(this.points[0].intensity);continue}const s=this.points[n-1],a=this.points[n];this.followed.push(js.follow(this.followed[n-1],s.intensity,a.intensity,(a.t-s.t)/1e3,(a.t-s.t)/1e3))}}at(t){if(this.points.length===0||t<this.points[0].t)return;let e=this.points.length-1;for(;e>0&&this.points[e].t>t;)e--;const i=this.points[e],n=this.points[e+1],s=n?js.follow(this.followed[e],i.intensity,n.intensity,(n.t-i.t)/1e3,(t-i.t)/1e3):js.follow(this.followed[e],i.intensity,i.intensity,1,(t-i.t)/1e3);return{type:js.typeBetween(i,n,t,s),intensity:s,character:js.characterBetween(i,n,t)}}static characterBetween(t,e,i){return t.type==="none"?e&&e.type!=="none"?e.intensity:t.lastFallingIntensity:!e||e.type==="none"?t.intensity:t.intensity+(e.intensity-t.intensity)*(i-t.t)/(e.t-t.t||1)}static typeBetween(t,e,i,n){return t.type==="none"?e&&e.type!=="none"&&i>t.t?e.type:n>0?t.lastFalling:"none":e&&e.type==="none"&&n<=0?"none":t.type}static follow(t,e,i,n,s){const a=js.MAX_CHANGE_PER_S,o=n>0?(i-e)/n:0,c=u=>e+o*Math.min(Math.max(u,0),n);let l=t,h=0;for(let u=0;u<8&&h<s;u++){const d=c(h)-l;if(Math.abs(d)<1e-9){const y=h<n?o:0;if(Math.abs(y)<=a){const b=h<n?Math.min(s,n):s;l=c(b),h=b;continue}const M=Math.min(s,n);l+=Math.sign(y)*a*(M-h),h=M;continue}const f=Math.sign(d),p=h<n?o:0,v=a-f*p,m=v>0?h+Math.abs(d)/v:1/0,g=h<n?n:1/0,_=Math.min(s,m,g);l+=f*a*(_-h),h=_,_===m&&(l=c(h))}return Math.min(1,Math.max(0,l))}}function Be(r,t,e){return r+(t-r)*e}function f0(r,t,e){const i=((t-r)%360+540)%360-180;return((r+i*e)%360+360)%360}function Ov(r,t,e){return Math.max(t,Math.min(e,r))}function Nv(r=[],t=[],e){if(!(!r.length&&!t.length))return[...new Set([...r.map(i=>i.id),...t.map(i=>i.id)])].map(i=>{const n=r.find(c=>c.id===i),s=t.find(c=>c.id===i),a=n??{...s,density:0},o=s??{...n,density:0};return{...a,eastM:Be(a.eastM,o.eastM,e),northM:Be(a.northM,o.northM,e),baseM:Be(a.baseM,o.baseM,e),thicknessM:Be(a.thicknessM,o.thicknessM,e),widthM:Be(a.widthM,o.widthM,e),depthM:Be(a.depthM,o.depthM,e),rotationDeg:f0(a.rotationDeg,o.rotationDeg,e),density:Be(a.density,o.density,e),darkness:Be(a.darkness??0,o.darkness??0,e)}})}function Fv(r,t,e){if(r.cloudLayers===void 0&&t.cloudLayers===void 0)return;const i=Tl(r),n=Tl(t);return e>=1?n.map(a=>({...a})):[...new Set([...i.map(a=>a.id),...n.map(a=>a.id)])].map(a=>{const o=i.find(u=>u.id===a),c=n.find(u=>u.id===a),l=o??{...c,coverage:0},h=c??{...o,coverage:0};return{...l,instances:Nv(o?.instances,c?.instances,e),baseM:Be(l.baseM,h.baseM,e),thicknessM:Be(l.thicknessM,h.thicknessM,e),coverage:Be(l.coverage,h.coverage,e),sizeM:Be(l.sizeM,h.sizeM,e),density:Be(l.density,h.density,e),darkness:Be(l.darkness??r.cloudDarkness,h.darkness??t.cloudDarkness,e),iceCrystalAlignment:l.iceCrystalAlignment===void 0||h.iceCrystalAlignment===void 0?void 0:Be(l.iceCrystalAlignment,h.iceCrystalAlignment,e),windSpeed:l.windSpeed===void 0&&h.windSpeed===void 0?void 0:Be(l.windSpeed??r.windSpeed,h.windSpeed??t.windSpeed,e),windDirectionDeg:l.windDirectionDeg===void 0&&h.windDirectionDeg===void 0?void 0:f0(l.windDirectionDeg??r.windDirectionDeg,h.windDirectionDeg??t.windDirectionDeg,e)}})}function Uv(r,t,e){return{cloudLayers:Fv(r,t,e),cloudCover:Be(r.cloudCover,t.cloudCover,e),cloudDarkness:Be(r.cloudDarkness,t.cloudDarkness,e),highCloudCover:r.highCloudCover===void 0||t.highCloudCover===void 0?void 0:Be(r.highCloudCover,t.highCloudCover,e),iceCrystalAlignment:r.iceCrystalAlignment===void 0||t.iceCrystalAlignment===void 0?void 0:Be(r.iceCrystalAlignment,t.iceCrystalAlignment,e),lowerCloudCover:r.lowerCloudCover===void 0||t.lowerCloudCover===void 0?void 0:Be(r.lowerCloudCover,t.lowerCloudCover,e),cloudBaseM:r.cloudBaseM===void 0||t.cloudBaseM===void 0?void 0:Be(r.cloudBaseM,t.cloudBaseM,e),relativeHumidity:r.relativeHumidity===void 0||t.relativeHumidity===void 0?void 0:Be(r.relativeHumidity,t.relativeHumidity,e),precipitationType:e<1?r.precipitationType:t.precipitationType,precipitationIntensity:Be(r.precipitationIntensity,t.precipitationIntensity,e),windDirectionDeg:f0(r.windDirectionDeg,t.windDirectionDeg,e),windSpeed:Be(r.windSpeed,t.windSpeed,e),storm:e<1?r.storm:t.storm}}class Xo{keyframes=[];ramp;addKeyframe(t,e){this.ramp=void 0;const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,weather:e}:this.keyframes.splice(i,0,{t,weather:e})}clear(){this.ramp=void 0,this.keyframes.length=0}removeKeyframeAt(t){this.ramp=void 0;const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}getLatestWeatherAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].weather:void 0}getInterpolatedWeatherAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.weather;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];return i?n?Uv(i.weather,n.weather,Ov((t-i.t)/(n.t-i.t),0,1)):i.weather:n?.weather}getActualWeatherAt(t){const e=this.getInterpolatedWeatherAt(t);if(!e)return;const i=(this.ramp??=new js(this.keyframes)).at(t);if(!i)return e;const{type:n,intensity:s,character:a}=i,o=a>0?Math.min(1,s/a):n==="none"?0:1;return{...e,precipitationType:n,precipitationIntensity:a,precipitationAmount:o}}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Xo;for(const i of t.keyframes)e.addKeyframe(i.t,i.weather);return e}}class Yo{keyframes=[];addKeyframe(t,e){const i=this.findInsertIndex(t);this.keyframes[i]?.t===t?this.keyframes[i]={t,sound:e}:this.keyframes.splice(i,0,{t,sound:e})}clear(){this.keyframes.length=0}removeKeyframeAt(t){const e=this.findInsertIndex(t);this.keyframes[e]?.t===t&&this.keyframes.splice(e,1)}getLatestSoundAt(t){let e=this.findInsertIndex(t);return this.keyframes[e]?.t!==t&&(e-=1),e>=0?this.keyframes[e].sound:void 0}getInterpolatedSoundAt(t){const e=this.findInsertIndex(t),i=this.keyframes[e]?.t===t?this.keyframes[e]:this.keyframes[e-1];if(i?.t===t)return i.sound;const n=this.keyframes[e]?.t===t?void 0:this.keyframes[e];if(!i)return n?.sound;if(!n)return i.sound;const s=(t-i.t)/(n.t-i.t);return this.lerp(i.sound,n.sound,Math.max(0,Math.min(1,s)))}get duration(){return this.keyframes.length===0?0:this.keyframes[this.keyframes.length-1].t}get allKeyframes(){return this.keyframes}toJSON(){return{keyframes:this.keyframes}}static fromJSON(t){const e=new Yo;for(const i of t.keyframes)e.addKeyframe(i.t,i.sound);return e}lerp(t,e,i){return{kind:i<1?t.kind:e.kind,volume:t.volume+(e.volume-t.volume)*i,pitchHz:t.pitchHz+(e.pitchHz-t.pitchHz)*i,src:i<1?t.src:e.src}}findInsertIndex(t){let e=0,i=this.keyframes.length;for(;e<i;){const n=e+i>>>1;this.keyframes[n].t<t?e=n+1:i=n}return e}}const kv=100,zv={kind:"none",volume:0,pitchHz:kv};class Tn{constructor(t){this.entries=t}static empty(){return new Tn(new Map)}get size(){return this.entries.size}at(t){return this.entries.get(t)}paths(){return[...this.entries.keys()]}set(t,e){e.basis==="stated"&&e.rationale===void 0?this.entries.delete(t):this.entries.set(t,e)}clear(t){for(const e of this.entries.keys())(e===t||e.startsWith(`${t}.`))&&this.entries.delete(e)}static strip(t){const e=new Tn(new Map);return{recording:Tn.stripValue(t,[],e),provenance:e}}static restore(t,e){if(e.size===0)return t;const i=structuredClone(t);for(const n of e.paths()){const s=e.at(n),a=n.split("."),o=Tn.holderOf(i,a);if(!o)continue;const c=a[a.length-1],l=o[c];l!==void 0&&(s.of!==void 0&&JSON.stringify(s.of)!==JSON.stringify(l)||(o[c]={value:l,...s.basis==="stated"?{}:{basis:s.basis},...s.rationale===void 0?{}:{rationale:s.rationale}}))}return i}static isWrapper(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&"value"in t}static stripValue(t,e,i){return Tn.isWrapper(t)?(i.set(e.join("."),{basis:t.basis??"stated",...t.rationale===void 0?{}:{rationale:t.rationale},of:t.value}),Tn.stripValue(t.value,e,i)):Array.isArray(t)?t.map((n,s)=>Tn.stripValue(n,[...e,String(s)],i)):typeof t=="object"&&t!==null?Object.fromEntries(Object.entries(t).map(([n,s])=>[n,Tn.stripValue(s,[...e,n],i)])):t}static holderOf(t,e){let i=t;for(const n of e.slice(0,-1)){if(typeof i!="object"||i===null)return;i=i[n]}return typeof i=="object"&&i!==null?i:void 0}}function zu(r){if(r.year!==void 0)return Date.UTC(r.year,(r.month??1)-1,r.day??1,r.hour??0,r.minute??0,r.second??0)}function yf(r){return(((r.day??0)*24+(r.hour??0))*60+(r.minute??0))*6e4+(r.second??0)*1e3}const Bv=["year","month","day","hour","minute"],Hv=["day","hour","minute"];function _f(r,t){return t.filter(e=>r[e]!==void 0).join(",")}function Gv(r){if(r.durationSeconds!==void 0)return r.durationSeconds*1e3;if(!r.time||!r.endTime)return;const t=r.time.year!==void 0&&r.endTime.year!==void 0,e=t?Bv:Hv,i=_f(r.time,e);if(!(i===""||i!==_f(r.endTime,e)))return t?zu(r.endTime)-zu(r.time):yf(r.endTime)-yf(r.time)}class jl{constructor(t,e,i,n,s,a,o,c,l=[],h,u,d,f=[],p=[],v=[],m=[]){this.event=t,this.timeline=e,this.observerTrack=i,this.weatherTrack=n,this.soundTrack=s,this.observer=a,this.id=o,this.weather=c,this.decor=l,this.weatherSource=h,this.instrumentId=u,this.exposureSeconds=d,this.milestones=f,this.references=p,this.roads=v,this.traces=m}provenance=Tn.empty();loadIssues=[];account;sources;interpretation;sway;lightPollution;observerMap;iso;vehicle;get observerCount(){return 1+this.decor.filter(t=>t.kind==="observer").length}get exposure(){return this.exposureSeconds??this.instrument.exposureSeconds}get instrument(){return mi.byId(this.instrumentId)}static create(t,e,i){return new jl({eventType:"sighting",time:t,place:e},new Jl,new Wo,new Xo,new Yo,i)}}const Vv=0,Wv=0;function Ze(r,t){const e=r.observerTrack.getInterpolatedPoseAt(t);if(e)return e;const i=r.event.place?.[0];if(i)return{lat:i.lat,lng:i.lng,elevationM:Vv,headingDeg:void 0,pitchDeg:Wv,fovDeg:mi.fieldOfViewDeg(r.instrument)}}function eo(r,t){return r.weatherTrack.getInterpolatedWeatherAt(t)??r.weather??d0}function uc(r,t){return r.weatherTrack.getActualWeatherAt(t)??r.weather??d0}function Xv(r,t){return r.soundTrack.getInterpolatedSoundAt(t)??zv}class Yv{constructor(t,e){this.timeline=t,this.onFrame=e}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const t=()=>{if(this.state!=="playing")return;const e=performance.now();if(this.currentT+=(e-this.lastWallTime)*this.playbackRate,this.lastWallTime=e,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t)};this.rafId=requestAnimationFrame(t)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(t){this.currentT=Math.max(0,Math.min(t,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(t){const e=new Map;for(const i of this.timeline.sourceIds){const n=this.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}this.onFrame(t,e)}}const Sg=["nw","n","ne","e","se","s","sw","w"],qv=24,dc=8,$v=3,Kv=8;function fc(r,t,e){const i=r.x-t.x,n=r.y-t.y,s=Math.cos(e),a=Math.sin(e);return{x:t.x+i*s-n*a,y:t.y+i*a+n*s}}function io(r){return{x:r.x+r.width/2,y:r.y+r.height/2}}const Zv={nw:{left:!0,top:!0},n:{top:!0},ne:{right:!0,top:!0},e:{right:!0},se:{right:!0,bottom:!0},s:{bottom:!0},sw:{left:!0,bottom:!0},w:{left:!0}};class pn{static handlePointsFor(t){const{x:e,y:i,width:n,height:s}=t.bounds,a={nw:{x:e,y:i},n:{x:e+n/2,y:i},ne:{x:e+n,y:i},e:{x:e+n,y:i+s/2},se:{x:e+n,y:i+s},s:{x:e+n/2,y:i+s},sw:{x:e,y:i+s},w:{x:e,y:i+s/2},rotate:{x:e+n/2,y:i-qv}},o=io(t.bounds),c={};for(const l of Object.keys(a))c[l]=fc(a[l],o,t.angle);return c}static hitTestHandle(t,e,i=8,n=[...Sg,"rotate"]){const s=pn.handlePointsFor(t);for(const a of n)if(Math.hypot(e.x-s[a].x,e.y-s[a].y)<=i)return a}static HANDLE_DIRECTION_DEG={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315};static resizeAxisFor(t,e){const n=((pn.HANDLE_DIRECTION_DEG[t]+e*180/Math.PI)%180+180)%180/45,s=["ew","nwse","ns","nesw"];return s[Math.round(n)%s.length]}static resizeBounds(t,e,i,n){const s=io(t),a=fc(n,s,-e),{x:o,y:c,width:l,height:h}=t,u=Zv[i];let d=o,f=c,p=o+l,v=c+h;return u.left&&(d=Math.min(a.x,p-dc)),u.right&&(p=Math.max(a.x,d+dc)),u.top&&(f=Math.min(a.y,v-dc)),u.bottom&&(v=Math.max(a.y,f+dc)),{x:d,y:f,width:p-d,height:v-f}}static resizeShape(t,e,i){if(e==="rotate")throw new Error("resizeShape does not accept the rotate handle");const{width:n,height:s}=t.bounds,a=pn.resizeBounds(t.bounds,t.angle,e,i);if(t.kind==="oval")return{...t,bounds:a};const o=n===0?1:a.width/n,c=s===0?1:a.height/s;return{...t,bounds:a,points:t.points.map(l=>({x:l.x*o,y:l.y*c}))}}static rotateShape(t,e){const i=io(t.bounds),n=Math.atan2(e.y-i.y,e.x-i.x)+Math.PI/2;return{...t,angle:n}}static groupBoundsFor(t){const e=Math.min(...t.map(a=>a.x)),i=Math.min(...t.map(a=>a.y)),n=Math.max(...t.map(a=>a.x+a.width)),s=Math.max(...t.map(a=>a.y+a.height));return{x:e,y:i,width:n-e,height:s-i}}static vertexPointsFor(t){const e=io(t.bounds);return t.points.map(i=>fc({x:t.bounds.x+i.x,y:t.bounds.y+i.y},e,t.angle))}static hitTestVertex(t,e,i=Kv){const n=pn.vertexPointsFor(t);let s,a=i;return n.forEach((o,c)=>{const l=Math.hypot(e.x-o.x,e.y-o.y);l<=a&&(a=l,s=c)}),s}static toLocalPoint(t,e){const i=io(t.bounds),n=fc(e,i,-t.angle);return{x:n.x-t.bounds.x,y:n.y-t.bounds.y}}static moveVertex(t,e,i){const n=t.points.map((u,d)=>d===e?pn.toLocalPoint(t,i):u),s=Math.min(...n.map(u=>u.x)),a=Math.min(...n.map(u=>u.y)),o=Math.max(...n.map(u=>u.x)),c=Math.max(...n.map(u=>u.y)),l={x:t.bounds.x+s,y:t.bounds.y+a,width:o-s,height:c-a},h=n.map(u=>({x:u.x-s,y:u.y-a}));return{...t,bounds:l,points:h}}static insertVertexNear(t,e){const i=pn.toLocalPoint(t,e),{points:n}=t;let s=n.length-1,a=1/0;for(let c=0;c<n.length;c++){const l=n[c],h=n[(c+1)%n.length],u=pn.distanceToSegment(i,l,h);u<a&&(a=u,s=c)}const o=[...n.slice(0,s+1),i,...n.slice(s+1)];return{...t,points:o}}static distanceToSegment(t,e,i){const n=i.x-e.x,s=i.y-e.y,a=n*n+s*s,o=a===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*s)/a)),c=e.x+o*n,l=e.y+o*s;return Math.hypot(t.x-c,t.y-l)}static deleteVertex(t,e){return t.points.length<=$v?t:{...t,points:t.points.filter((i,n)=>n!==e)}}}const Bu=6,pc=Bu/2,Sf=20,bf=24,wf=9,Ef=6,Af=7,Tf=6,Jn=4;class qo{constructor(t){this.ctx=t}starPoints=0;roll=0;clear(t,e){this.ctx.clearRect(0,0,t,e)}static paintExtent(t){const{x:e,y:i,width:n,height:s}=t.bounds,a=e+n/2,o=i+s/2,c=t.angle%(2*Math.PI)!==0,l=Math.hypot(n,s)/2,h=c?l:n/2,u=c?l:s/2,d=Math.max(n,s)/2,f=t.brightness??0,p=f>0?Math.max(d*(1+wf*f),Tf*f)-d:0,v=f>0?d*(1+Af*f)-d:0,m=3*bf*(t.blur??0)+1.5*Sf*t.haloScale,g=Math.max(p,v,0)+m+2;return{x:a-h-g,y:o-u-g,width:2*(h+g),height:2*(u+g)}}paintInto(t,e,i,n=!1){this.ctx.save(),this.ctx.scale(i,i),this.ctx.translate(-e.x,-e.y);const s=t.selected?{...t,selected:!1}:t;n?this.paintGhost(s,1.5):this.paintShape(s),this.ctx.restore()}paintShape(t){this.ctx.save(),this.ctx.globalAlpha=1-t.transparency;const e=t.blur??0;e>0&&(this.ctx.filter=`blur(${(bf*e).toFixed(2)}px)`);const i=t.brightness??0;i>0&&this.paintDazzle(t,i),t.haloScale>0&&this.paintHalo(t),this.paintBase(t),this.ctx.restore(),t.selected&&this.paintSelectionHandles(t)}setStarPoints(t){this.starPoints=Math.max(0,Math.floor(t))}setRoll(t){this.roll=t}paintDazzle(t,e){const{x:i,y:n,width:s,height:a}=t.bounds,o=i+s/2,c=n+a/2,l=Math.max(s,a)/2,h=Math.max(l*(1+wf*e),Tf*e);if(h<=0)return;this.ctx.save(),this.ctx.globalCompositeOperation="lighter";const u=this.ctx.createRadialGradient(o,c,0,o,c,h);for(let d=0;d<=Ef;d++){const f=d/Ef,p=1/(1+24*f*f);this.ctx.globalAlpha=1,u.addColorStop(f,this.withAlpha(t.color,p*e*.55))}if(this.ctx.fillStyle=u,this.ctx.beginPath(),this.ctx.arc(o,c,h,0,2*Math.PI),this.ctx.fill(),this.starPoints>0){const d=l*(1+Af*e);this.ctx.lineWidth=Math.max(1,l*.12),this.ctx.lineCap="round";for(let f=0;f<this.starPoints;f++){const p=f/this.starPoints*Math.PI*2+this.roll,v=o+Math.cos(p)*d,m=c+Math.sin(p)*d,g=this.ctx.createLinearGradient(o,c,v,m);g.addColorStop(0,this.withAlpha(t.color,e*.55)),g.addColorStop(.35,this.withAlpha(t.color,e*.22)),g.addColorStop(1,this.withAlpha(t.color,0)),this.ctx.strokeStyle=g,this.ctx.beginPath(),this.ctx.moveTo(o,c),this.ctx.lineTo(v,m),this.ctx.stroke()}}this.ctx.restore()}dazzledFill(t,e){if(e<=0)return t.color;const i=/^#([0-9a-f]{6})$/i.exec(t.color.trim());if(!i)return t.color;const n=Number.parseInt(i[1],16),s=a=>Math.round(a+(255-a)*e);return`rgb(${s(n>>16&255)}, ${s(n>>8&255)}, ${s(n&255)})`}withAlpha(t,e){const i=Math.max(0,Math.min(1,e)),n=/^#([0-9a-f]{6})$/i.exec(t.trim());if(!n)return t;const s=Number.parseInt(n[1],16);return`rgba(${s>>16&255}, ${s>>8&255}, ${s&255}, ${i.toFixed(3)})`}paintBase(t){this.ctx.fillStyle=this.dazzledFill(t,t.brightness??0),this.tracePath(t),this.ctx.fill()}paintGhost(t,e){this.ctx.save(),this.tracePath(t),this.ctx.setLineDash([e*3,e*2]),this.ctx.lineWidth=e,this.ctx.strokeStyle=t.color,this.ctx.stroke(),this.ctx.restore()}tracePath(t){if(this.ctx.beginPath(),t.kind==="oval"){const{x:e,y:i,width:n,height:s}=t.bounds,a=n/2,o=s/2;this.ctx.ellipse(e+a,i+o,a,o,t.angle,0,2*Math.PI)}else{const{x:e,y:i,width:n,height:s}=t.bounds;this.ctx.save(),this.ctx.translate(e+n/2,i+s/2),this.ctx.rotate(t.angle),this.ctx.translate(-n/2,-s/2),t.points.forEach((a,o)=>{o===0?this.ctx.moveTo(a.x,a.y):this.ctx.lineTo(a.x,a.y)}),this.ctx.closePath(),this.ctx.restore()}}paintHalo(t){this.ctx.save(),this.ctx.shadowColor=t.color,this.ctx.shadowBlur=Sf*t.haloScale,this.paintBase(t),this.ctx.restore()}paintSelectionHandles(t){this.paintHandleFrame(pn.handlePointsFor(t),{includeRotate:!0}),t.kind==="polygon"&&this.paintVertexHandles(t)}paintVertexHandles(t){this.ctx.fillStyle="#39f";for(const e of pn.vertexPointsFor(t))this.ctx.beginPath(),this.ctx.ellipse(e.x,e.y,Jn,Jn,0,0,2*Math.PI),this.ctx.fill()}paintMemberOutline(t){this.paintOutline(pn.handlePointsFor(t))}paintSelectionOnly(t){this.paintSelectionHandles(t)}paintPictureFrame(t,e,i){const n=this.ctx;if(n.save(),t&&t.length===4){n.strokeStyle="#39f",n.lineWidth=1.5,n.setLineDash([6,4]),n.beginPath(),n.moveTo(t[0].x,t[0].y);for(const s of t.slice(1))n.lineTo(s.x,s.y);n.closePath(),n.stroke(),n.setLineDash([])}for(const s of e){const a=qo.landmarkColour(s.residualDeg),o=s.selected?3:2;s.selected&&(n.strokeStyle="#fff",n.lineWidth=o+3,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Jn+2,Jn+2,0,0,2*Math.PI),n.stroke()),s.scene&&(n.strokeStyle=a,n.lineWidth=1,n.beginPath(),n.moveTo(s.picture.x,s.picture.y),n.lineTo(s.scene.x,s.scene.y),n.stroke(),n.fillStyle=a,n.beginPath(),n.ellipse(s.scene.x,s.scene.y,Jn,Jn,0,0,2*Math.PI),n.fill()),n.strokeStyle=a,n.lineWidth=o,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Jn+2,Jn+2,0,0,2*Math.PI),n.stroke(),this.paintLabel(s.label,s.picture.x+Jn+5,s.picture.y-Jn-2,a)}i&&this.paintLabel(i,8,8,"#fff",13),n.restore()}static landmarkColour(t){return t===void 0?"#ffb000":t<=1?"#3c3":t<=3?"#ffb000":"#f33"}paintLabel(t,e,i,n,s=11){const a=this.ctx;a.save(),a.font=`${s}px system-ui, sans-serif`,a.textBaseline="top";const o=a.measureText(t).width;a.fillStyle="rgba(0, 0, 0, 0.6)",a.fillRect(e-3,i-2,o+6,s+4),a.fillStyle=n,a.fillText(t,e,i),a.restore()}paintGroupHandles(t){this.paintHandleFrame(pn.handlePointsFor({bounds:t,angle:0}),{includeRotate:!0})}paintOutline(t){this.ctx.strokeStyle="lightgray",this.ctx.beginPath(),this.ctx.moveTo(t.nw.x,t.nw.y),this.ctx.lineTo(t.ne.x,t.ne.y),this.ctx.lineTo(t.se.x,t.se.y),this.ctx.lineTo(t.sw.x,t.sw.y),this.ctx.closePath(),this.ctx.stroke()}paintHandleFrame(t,{includeRotate:e}){this.paintOutline(t),this.ctx.fillStyle="lightgray";for(const i of Sg){const n=t[i];this.ctx.fillRect(n.x-pc,n.y-pc,Bu,Bu)}e&&(this.ctx.beginPath(),this.ctx.moveTo(t.n.x,t.n.y),this.ctx.lineTo(t.rotate.x,t.rotate.y),this.ctx.stroke(),this.ctx.beginPath(),this.ctx.ellipse(t.rotate.x,t.rotate.y,pc+1,pc+1,0,0,2*Math.PI),this.ctx.fill())}}const Rf=.05,Df=.08,If=2,Cf=3,Jv=14,jv=.02;class Qv{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",t);return}}Fa.unlock(this.context)}setSound(t){if(this.requested=t,!this.context)return;const e=this.keyFor(t);if(!e){this.silence();return}if(this.voice?.key!==e){this.stopVoice();const i=++this.voiceToken;e.startsWith("src:")?this.buildRecordedVoice(t.src,e,i):this.voice=this.buildSynthesizedVoice(t,e)}this.applyTo(this.voice,t)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(t){if(!(t.volume<=0))return t.src?`src:${t.src}`:t.kind==="none"?void 0:t.kind}applyTo(t,e){const i=this.context;if(!t||!i)return;const n=i.currentTime;t.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,e.volume))*t.gainScale,n,Rf);for(const{param:s,ratio:a}of t.pitch)s.setTargetAtTime(Math.min(e.pitchHz*a,i.sampleRate/2-1),n,Rf)}buildSynthesizedVoice(t,e){const i=this.context;if(i)switch(t.kind){case"hum":return this.buildHum(i,e);case"whistle":return this.buildWhistle(i,e);case"rumble":return this.buildRumble(i,e);case"crackle":return this.buildCrackle(i,e);default:return}}buildHum(t,e){const i=t.createOscillator();i.type="sawtooth";const n=t.createOscillator();n.type="sawtooth";const s=t.createBiquadFilter();s.type="lowpass",s.Q.value=1;const a=t.createGain();return a.gain.value=0,i.connect(s),n.connect(s),s.connect(a).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.16,pitch:[{param:i.frequency,ratio:1},{param:n.frequency,ratio:1.006},{param:s.frequency,ratio:6}]}}buildWhistle(t,e){const i=t.createOscillator();i.type="sine";const n=t.createOscillator();n.type="sine",n.frequency.value=5;const s=t.createGain(),a=t.createGain();return a.gain.value=0,n.connect(s).connect(i.frequency),i.connect(a).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.22,pitch:[{param:i.frequency,ratio:1},{param:s.gain,ratio:.012}]}}buildRumble(t,e){const i=t.createBufferSource();i.buffer=this.brownNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="lowpass",n.Q.value=.8;const s=t.createGain();return s.gain.value=0,i.connect(n).connect(s).connect(this.output(t)),i.start(),{key:e,nodes:[n,s],sources:[i],volumeParam:s.gain,gainScale:1.4,pitch:[{param:n.frequency,ratio:1}]}}buildCrackle(t,e){const i=t.createBufferSource();i.buffer=this.whiteNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="bandpass",n.Q.value=1.2;const s=t.createGain();s.gain.value=0;const a=t.createBufferSource();a.buffer=this.crackleEnvelope(t),a.loop=!0;const o=t.createGain();return o.gain.value=0,a.connect(o).connect(s.gain),i.connect(n).connect(s).connect(this.output(t)),i.start(),a.start(),{key:e,nodes:[n,s,o],sources:[i,a],volumeParam:o.gain,gainScale:.9,pitch:[{param:n.frequency,ratio:4}]}}async buildRecordedVoice(t,e,i){const n=this.context;if(!n)return;let s;try{s=await this.getBuffer(t)}catch(c){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",c);return}if(i!==this.voiceToken||!this.context)return;const a=n.createBufferSource();a.buffer=s,a.loop=!0;const o=n.createGain();o.gain.value=0,a.connect(o).connect(this.output(n)),a.start(),this.voice={key:e,nodes:[o],sources:[a],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(t){const e=this.context;if(!e)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}whiteNoise(t){if(!this.noiseBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*If),t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;this.noiseBuffer=e}return this.noiseBuffer}brownNoise(t){const e=t.createBuffer(1,Math.floor(t.sampleRate*If),t.sampleRate),i=e.getChannelData(0);let n=0,s=0;for(let a=0;a<i.length;a++)n=(n+.02*(Math.random()*2-1))/1.02,i[a]=n,s=Math.max(s,Math.abs(n));if(s>0)for(let a=0;a<i.length;a++)i[a]/=s;return e}crackleEnvelope(t){if(!this.crackleBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*Cf),t.sampleRate),i=e.getChannelData(0),n=Math.max(1,Math.floor(jv*t.sampleRate)),s=Math.round(Cf*Jv);for(let a=0;a<s;a++){const o=Math.floor(Math.random()*i.length),c=.4+Math.random()*.6;for(let l=0;l<n&&o+l<i.length;l++)i[o+l]=Math.max(i[o+l],c*(1-l/n))}this.crackleBuffer=e}return this.crackleBuffer}stopVoice(){const t=this.voice,e=this.context;if(this.voice=void 0,!t||!e)return;const i=e.currentTime;t.volumeParam.cancelScheduledValues(i),t.volumeParam.setTargetAtTime(0,i,Df/3);const n=i+Df;for(const s of t.sources){s.onended=()=>{s.disconnect();for(const a of t.nodes)a.disconnect()};try{s.stop(n)}catch{s.disconnect();for(const a of t.nodes)a.disconnect()}}}}class Gt{static svg(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="currentColor"/></svg>`}static outline(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" stroke-linecap="round"/></svg>`}static solid(t){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5em" aria-hidden="true" focusable="false"><path d="${t}" fill="currentColor" fill-rule="evenodd"/></svg>`}static BOOKMARK="M6 3.5h12a.5.5 0 0 1 .5.5v16.5L12 16.8l-6.5 3.7V4a.5.5 0 0 1 .5-.5z";static PICTURE="M5 4h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z";static PICTURE_HILLS="M4.5 17.5l4.5-6 3 4 2.5-3 5 5z";static PIN="M12 21.5s-6.5-5.7-6.5-10.8a6.5 6.5 0 0 1 13 0c0 5.1-6.5 10.8-6.5 10.8z";static PIN_HOLE="M12 8.4a2.4 2.4 0 1 0 0 4.8 2.4 2.4 0 0 0 0-4.8z";static MILESTONES_OFF=Gt.outline(Gt.BOOKMARK);static MILESTONES_ON=Gt.solid(Gt.BOOKMARK);static PICTURES_OFF=Gt.outline(`${Gt.PICTURE}${Gt.PICTURE_HILLS}`);static PICTURES_ON=Gt.solid(`${Gt.PICTURE}${Gt.PICTURE_HILLS}`);static TRACE_LINE="M3 19.5l2.2-2.2 1.4 1.4L4.4 20.9zM8 14.5l2.2-2.2 1.4 1.4-2.2 2.2zM13 9.5l2.2-2.2 1.4 1.4-2.2 2.2z";static TRACE_MARK="M18.5 2.5l3.5 3.5-3.5 3.5-3.5-3.5z";static TRACES_OFF=Gt.outline(`${Gt.TRACE_LINE}${Gt.TRACE_MARK}`);static TRACES_ON=Gt.solid(`${Gt.TRACE_LINE}${Gt.TRACE_MARK}`);static MAP_OFF=Gt.outline(`${Gt.PIN}${Gt.PIN_HOLE}`);static MAP_ON=Gt.solid(`${Gt.PIN}${Gt.PIN_HOLE}`);static SHARE=Gt.outline("M14 4l7 7-7 7v-4.2C8.6 13.8 5.4 15.6 3.5 19c.6-5.6 3.4-9.6 10.5-10.8V4z");static FOLDED=Gt.svg("M15.4 7.4 14 6l-6 6 6 6 1.4-1.4L10.8 12z");static UNFOLDED=Gt.svg("M8.6 16.6 10 18l6-6-6-6-1.4 1.4 4.6 4.6z");static PLAY=Gt.svg("M7.4 5v14l11-7z");static PAUSE=Gt.svg("M6 5h4v14H6zM14 5h4v14h-4z");static VOLUME=Gt.svg("M2 9.5v5h3.5l4.5 4.5V5L5.5 9.5H2zm12.5 2.5A4 4 0 0 0 12.5 8.5v7A4 4 0 0 0 14.5 12zM12.5 4.2v2.1a6.5 6.5 0 0 1 0 11.4v2.1a8.6 8.6 0 0 0 0-15.6z");static MUTED=Gt.svg("M2 9.5v5h3.5l4.5 4.5V5L5.5 9.5H2zM15 9.8l1.4-1.4 2.6 2.6 2.6-2.6 1.4 1.4-2.6 2.6 2.6 2.6-1.4 1.4-2.6-2.6-2.6 2.6-1.4-1.4 2.6-2.6z");static ENTER_FULLSCREEN=Gt.svg("M5 5h5v2H7v3H5V5zm9 0h5v5h-2V7h-3V5zM5 14h2v3h3v2H5v-5zm12 0h2v5h-5v-2h3v-3z");static EXIT_FULLSCREEN=Gt.svg("M8 5h2v5H5V8h3V5zm6 0h2v3h3v2h-5V5zM5 14h5v5H8v-3H5v-2zm9 0h5v2h-3v3h-2v-5z")}function Oo(r){return[...r].sort((t,e)=>t.t-e.t)}function mh(r,t){let e;for(const i of Oo(r)){if(i.t>t)break;e=i}return e}const gh=Math.PI/180,mc=180/Math.PI;class Is{constructor(t,e,i){this.kind=t,this.canvasHeightPx=e,this.fovDeg=i;const n=i*gh/2;this.focalPx=t==="equidistant"?e/2/n:e/2/Math.tan(n)}focalPx;static of(t,e,i){return new Is(t.projection,e,i)}degToPx(t){const e=t*gh;return this.kind==="equidistant"?this.focalPx*e:2*this.focalPx*Math.tan(e/2)}pxToDeg(t){return this.kind==="equidistant"?t/this.focalPx*mc:2*Math.atan(t/(2*this.focalPx))*mc}angleDegToRadiusPx(t){const e=t*gh;return this.kind==="equidistant"?this.focalPx*e:this.focalPx*Math.tan(e)}halfWidthAngleDeg(t){return this.radiusPxToAngleDeg(this.canvasHeightPx*t/2)}radiusPxToAngleDeg(t){return this.kind==="equidistant"?t/this.focalPx*mc:Math.atan(t/this.focalPx)*mc}ofBounds(t){return{widthDeg:this.pxToDeg(t.width),heightDeg:this.pxToDeg(t.height)}}toBoundsSize(t){return{width:this.degToPx(t.widthDeg),height:this.degToPx(t.heightDeg)}}widthPx(t){return this.degToPx(De.angularWidthDeg(t))}}class sn{static fovOf(t,e){return Ze(t,e)?.fovDeg??mi.fieldOfViewDeg(t.instrument)}static toAngular(t){this.eachKeyframe(t,(e,i)=>({...e,angular:i.ofBounds(e.bounds)}))}static toBounds(t){this.eachKeyframe(t,(e,i)=>{if(!e.angular)return e;const{width:n,height:s}=i.toBoundsSize(e.angular),a={x:e.bounds.x+(e.bounds.width-n)/2,y:e.bounds.y+(e.bounds.height-s)/2,width:n,height:s};if(e.kind!=="polygon")return{...e,bounds:a};const o=e.bounds.width===0?1:n/e.bounds.width,c=e.bounds.height===0?1:s/e.bounds.height;return{...e,bounds:a,points:e.points.map(l=>({x:l.x*o,y:l.y*c}))}})}static toAim(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);if(s&&Math.abs(s.x-e.bounds.x)<sn.UNMOVED_PX&&Math.abs(s.y-e.bounds.y)<sn.UNMOVED_PX)return e;const a=this.aimFrom(t,i,n,e.bounds);return a?{...e,aim:a}:e})}static UNMOVED_PX=.01;static aimOf(t,e,i){const n=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,this.fovOf(t,e));return this.aimFrom(t,n,Ze(t,e),i)}static aimFrom(t,e,i,n){if(i?.headingDeg===void 0)return;const s=this.frameCentre(t),a=e.radiusPxToAngleDeg(n.x+n.width/2-s.x),o=e.radiusPxToAngleDeg(s.y-(n.y+n.height/2));return{azimuthDeg:((i.headingDeg+a)%360+360)%360,altitudeDeg:i.pitchDeg+o}}static toPosition(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);return s?{...e,bounds:{...e.bounds,...s}}:e})}static positionOf(t,e,i,n,s){if(s?.headingDeg===void 0)return;const a=this.frameCentre(t),o=this.shortestArc(e.azimuthDeg-s.headingDeg),c=e.altitudeDeg-s.pitchDeg;return{x:a.x+this.offAxisPx(n,o)-i.width/2,y:a.y-this.offAxisPx(n,c)-i.height/2}}static frameCentre(t){return{x:mi.frameWidthPx(t.instrument,De.CANVAS_HEIGHT_PX)/2,y:De.CANVAS_HEIGHT_PX/2}}static shortestArc(t){return(t%360+540)%360-180}static offAxisPx(t,e){return Math.abs(e)>=sn.OFF_CANVAS_DEG?Math.sign(e)*sn.OFF_CANVAS_PX:t.angleDegToRadiusPx(e)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(t,e,i){const n=mi.frameWidthPx(e,De.CANVAS_HEIGHT_PX)/2,s=mi.frameWidthPx(t.instrument,De.CANVAS_HEIGHT_PX)/2,a=De.CANVAS_HEIGHT_PX/2;for(const o of[...t.timeline.allKeyframes]){const c=this.fovOf(t,o.t),l=i?.get(o.t)??c,h=Is.of(e,De.CANVAS_HEIGHT_PX,l),u=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,c);t.timeline.addKeyframe(o.t,o.shapes.map(d=>{const{bounds:f}=d.shape,p=f.x+f.width/2-n,v=f.y+f.height/2-a,m=Math.hypot(p,v),g=m===0?1:u.angleDegToRadiusPx(h.radiusPxToAngleDeg(m))/m,_={...f,x:s+p*g-f.width/2,y:a+v*g-f.height/2};return{...d,shape:{...d.shape,bounds:_}}}))}this.toBounds(t)}static eachKeyframe(t,e){const{timeline:i}=t;for(const n of[...i.allKeyframes]){const s=Ze(t,n.t),a=this.fovOf(t,n.t),o=Is.of(t.instrument,De.CANVAS_HEIGHT_PX,a);i.addKeyframe(n.t,n.shapes.map(c=>({...c,shape:e(c.shape,o,s)})))}}}function t2(r){return Tn.restore(e2(r),r.provenance)}function e2(r){return sn.toAngular(r),sn.toAim(r),{version:1,id:r.id,time:r.event.time,endTime:r.event.endTime,durationSeconds:r.event.durationSeconds,utcOffsetHours:r.event.utcOffsetHours,timeZone:r.event.timeZone,place:r.event.place,observer:r.observer,account:r.account,sources:r.sources?.length?r.sources:void 0,sway:r.sway,vehicle:r.vehicle,description:r.event.description,tags:r.event.tags,timeline:r.timeline.toJSON(),observerTrack:r.observerTrack.toJSON(),weatherTrack:r.weatherTrack.toJSON(),soundTrack:r.soundTrack.toJSON(),weather:r.weather,decor:r.decor,milestones:r.milestones.length>0?r.milestones:void 0,references:r.references.length>0?r.references:void 0,roads:r.roads.length>0?r.roads:void 0,traces:r.traces.length>0?r.traces:void 0,weatherSource:r.weatherSource,instrument:r.instrumentId,exposureSeconds:r.exposureSeconds,iso:r.iso,lightPollution:r.lightPollution,observerMap:r.observerMap,interpretation:r.interpretation}}function i2(r){const{recording:t,provenance:e}=Tn.strip(r),i=n2(t);return i.provenance=e,i}function n2(r){const t=[],e=new jl({eventType:"sighting",time:r.time,endTime:r.endTime,durationSeconds:r.durationSeconds,utcOffsetHours:r.utcOffsetHours,timeZone:r.timeZone,place:r.place,description:r.description,tags:r.tags},Jl.fromJSON(r.timeline,t),r.observerTrack?Wo.fromJSON(r.observerTrack):new Wo,r.weatherTrack?Xo.fromJSON(r.weatherTrack):new Xo,r.soundTrack?Yo.fromJSON(r.soundTrack):new Yo,r.observer&&{id:r.observer.id,title:r.observer.title,lastName:r.observer.lastName,firstNames:r.observer.firstNames},r.id,r.weather,r.decor??[],r.weatherSource,r.instrument,r.exposureSeconds??r.observerTrack?.keyframes.map(i=>i.pose.exposureSeconds).find(i=>i!==void 0),Oo(r.milestones??[]),r.references??[],r.roads??[],r.traces??[]);return e.account=r.account,e.sources=r.sources,e.sway=r.sway,e.iso=r.iso,e.lightPollution=r.lightPollution,e.observerMap=r.observerMap,e.vehicle=r.vehicle,e.interpretation=r.interpretation,e.loadIssues=t,sn.toBounds(e),sn.toPosition(e),e}class Xr{static EN={"unknown-key":"{path}: unknown key, ignored","wrong-type":"{path}: expected {expected}, found {found}","not-in-list":"{path}: {found} is not one of {expected}",defaulted:"{path}: missing, {expected} used",unplaced:"{path}: no aim (and no bounds), drawn at the middle of the view",unsized:"{path}: no angular size (and no bounds), drawn one pixel wide","pixels-over-angles":"{path}: bounds restated without aim or angular, so the shape follows the pixels"};static text(t,e=Xr.EN){return e[t.kind].replace("{path}",t.path).replace("{expected}",t.expected??"").replace("{found}",t.found??"")}static warn(t,e){if(t.length===0)return;const i=t.map(n=>` ${Xr.text(n)}`);console.warn(`UFO@home: ${t.length} problem(s) in ${e??"this recording"}:
1365
1365
  ${i.join(`
1366
- `)}`)}}class On{constructor(t){this.format=t}issues(t){const e=[];return this.object(t,this.format,"",e),e}object(t,e,i,n){if(!On.isObject(t)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:On.typeOf(t)});return}for(const[s,a]of Object.entries(t)){const o=i?`${i}.${s}`:s,c=e[s];c?this.field(a,c,o,n):n.push({kind:"unknown-key",path:o})}}field(t,e,i,n){if(On.isStated(t)){this.field(t.value,e,i,n);return}if(!(e.loose||t===void 0||t===null))switch(e.type){case"enum":(typeof t!="string"||!e.values?.includes(t))&&n.push({kind:"not-in-list",path:i,expected:(e.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(t)});return;case"object":e.fields?this.object(t,e.fields,i,n):On.isObject(t)||n.push({kind:"wrong-type",path:i,expected:"object",found:On.typeOf(t)});return;case"array":Array.isArray(t)?e.fields&&t.forEach((s,a)=>{const o=On.isStated(s)?s.value:s;this.object(o,e.fields,`${i}.${a}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:On.typeOf(t)});return;default:typeof t!==e.type&&n.push({kind:"wrong-type",path:i,expected:e.type,found:On.typeOf(t)})}}static isObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}static isStated(t){return On.isObject(t)&&"value"in t&&Object.keys(t).every(e=>e==="value"||e==="basis"||e==="rationale")}static typeOf(t){return Array.isArray(t)?"array":t===null?"null":typeof t}}class zn{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(t,e){const i=Number.isFinite(e)?Math.max(0,e):0,n=Math.max(0,t-i*1e3),s=Math.max(0,t-n);return{fromMs:n,toMs:t,ms:s,seconds:s/1e3}}static instants(t,e,i,n,s){if(!(n>0))return 1;const a=s>0?zn.travelDegOver(t,e,i,i+n*1e3)/s/zn.PIXELS_PER_INSTANT:0,o=zn.flashesOver(t,n)*zn.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(a,o));return c<2?1:Math.min(zn.MAX_INSTANTS,c)}static travelDegOver(t,e,i,n){let s=0;for(const a of t){if(!a.track||a.track.length<2)continue;const o=zn.directionAt(a,e,i),c=zn.directionAt(a,e,n),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));s=Math.max(s,Math.acos(l)*180/Math.PI)}return s}static flashesOver(t,e){let i=0;for(const n of t)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*e}static directionAt(t,e,i){const n=Go(t,i),s=n.eastM,a=n.altitudeM-e,o=n.northM,c=Math.hypot(s,a,o);return c===0?{x:0,y:1,z:0}:{x:s/c,y:a/c,z:o/c}}}function bg(r,t){for(const e of r){const i=e.toLowerCase().split("-")[0];if(t.includes(i))return i}return"en"}class Pr{static preferencesFor(t){const e=navigator.languages??[],i=this.declaredFor(t);return i?[i,...e]:e}static declaredFor(t){for(let e=t;e;){const i=e.closest("[lang]")?.getAttribute("lang")?.trim();if(i)return i;const n=e.getRootNode();e=n instanceof ShadowRoot?n.host:void 0}}}class Rs{constructor(t){this.preferences=t}read(t){if(t===void 0||typeof t=="string")return t===""?void 0:t;for(const i of this.preferences){const n=t[i]??t[Rs.base(i)];if(n)return n}const e=new Set(this.preferences.map(i=>Rs.base(i)));for(const[i,n]of Object.entries(t))if(n&&e.has(Rs.base(i)))return n;return Object.values(t).find(i=>i)??void 0}write(t,e,i){const n=e?.trim()?e.trim():void 0;if(t===void 0||typeof t=="string")return n;const s={...t},a=Object.keys(s).find(o=>o===i)??Object.keys(s).find(o=>Rs.base(o)===Rs.base(i))??i;return n===void 0?delete s[a]:s[a]=n,Object.keys(s).length===0?void 0:s}static base(t){return t.toLowerCase().split("-")[0]}}const wg=["en","fr","es","it"],s2={en:()=>an(()=>Promise.resolve().then(()=>o2),void 0,import.meta.url).then(r=>r.ufoMessages_en),fr:()=>an(()=>import("./UfoMessages_fr-BMafKxyw.js"),[],import.meta.url).then(r=>r.ufoMessages_fr),es:()=>an(()=>import("./UfoMessages_es-8Us-3wIq.js"),[],import.meta.url).then(r=>r.ufoMessages_es),it:()=>an(()=>import("./UfoMessages_it-C7cNoyQt.js"),[],import.meta.url).then(r=>r.ufoMessages_it)};function a2(r){return s2[r]()}function r2(r){switch(r){case"fr":return an(()=>import("./SceneNames_fr-DYU3H8s1.js"),[],import.meta.url).then(t=>t.sceneNames_fr);case"es":return an(()=>import("./SceneNames_es-DjVl7xge.js"),[],import.meta.url).then(t=>t.sceneNames_es);case"it":return an(()=>import("./SceneNames_it-Box-aRN9.js"),[],import.meta.url).then(t=>t.sceneNames_it);default:return Promise.resolve(void 0)}}const Eg={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",showTraces:"Show the investigator's lines",hideTraces:"Hide the investigator's lines",referenceOpacity:"Picture opacity",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Xr.EN},o2=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:Eg},Symbol.toStringTag,{value:"Module"})),Ag=Math.PI/180,c2=180/Math.PI,l2=256,Tg=19,h2=1.25;function Rg(r,t){return 156543.03392*Math.cos(r*Ag)/2**t}function Dg(r,t){return Rg(r,t)*l2}function u2(r,t){let e=0;for(;e<Tg&&Dg(r,e+1)>=t;)e++;return e}function Ig(r,t){return Dg(r,t)}function d2(r,t){const e=t*h2;let i=0;for(;i<Tg&&Rg(r,i)>e;)i++;return i}function pl(r){const t=r*Ag;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}function Cg(r,t,e){const i=2**e;return{x:(r+180)/360*i,y:pl(t)*i}}function Pg(r,t,e){const i=pl(r.north),n=pl(r.south);return{x:(t-r.west)/(r.east-r.west),y:(pl(e)-i)/(n-i)}}function f2(r,t,e){const{x:i,y:n}=Cg(r,t,e);return{x:Math.floor(i),y:Math.floor(n),z:e}}function p2(r){const t=2**r.z,e=r.x/t*360-180,i=(r.x+1)/t*360-180,n=Pf(r.y,t);return{south:Pf(r.y+1,t),north:n,west:e,east:i}}function Pf(r,t){const e=r/t;return Math.atan(Math.sinh(Math.PI*(1-2*e)))*c2}function Lg(r,t,e,i){const n=f2(r,t,e),s=Math.floor(i/2),a=[];for(let l=-s;l<=s;l++)for(let h=-s;h<=s;h++)a.push({x:n.x+h,y:n.y+l,z:e});const o=a.map(p2),c={south:Math.min(...o.map(l=>l.south)),north:Math.max(...o.map(l=>l.north)),west:Math.min(...o.map(l=>l.west)),east:Math.max(...o.map(l=>l.east))};return{tiles:a,bounds:c}}const m2="#2ec4ff";class Ea{constructor(t){this.ctx=t}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(t,e){let i,n=1/0;for(const s of this.targets){const a=Math.hypot(s.x-t,s.y-e);a>s.radius||a>n||(i=s,n=a)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(t){const{ctx:e}=this;e.save(),this.targets=[],e.clearRect(0,0,this.width,this.height),this.paintGround(t),this.paintNight(t.nightFraction),this.paintPath(t),this.paintTraces(t),t.position?(this.paintCone(t,t.position),this.paintDecor(t),this.paintMarkers(t),this.paintObserver(t,t.position)):(this.paintDecor(t),this.paintMarkers(t)),this.paintNorth(),this.paintFooter(t.bounds,t.attribution),e.restore()}toCanvas(t,e,i){const n=Pg(t,i,e);return{x:n.x*this.width,y:n.y*this.height}}paintGround(t){const{ctx:e}=this;e.fillStyle="#1d2321",e.fillRect(0,0,this.width,this.height);const i=t.imagery;if(!i)return;const n=this.toCanvas(t.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(t.bounds,i.bounds.south,i.bounds.east);e.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(t=0){if(t<=0)return;const{ctx:e}=this;e.save(),e.fillStyle=`rgba(6, 12, 30, ${Math.min(t,1)*.78})`,e.fillRect(0,0,this.width,this.height),e.restore()}paintDecor(t){const{ctx:e}=this;for(const i of t.decor){const n=this.toCanvas(t.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),e.beginPath(),e.rect(n.x-3.5,n.y-3.5,7,7),e.fillStyle="rgba(120, 220, 255, 0.85)",e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.7)",e.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),e.lineWidth=3,e.strokeStyle="rgba(0, 0, 0, 0.6)",e.stroke(),e.lineWidth=1.5,e.strokeStyle="rgba(120, 220, 255, 0.9)",e.stroke()}}paintPath(t){if(!t.path.moved)return;const{ctx:e}=this,i=t.path.points.map(n=>this.toCanvas(t.bounds,n.lat,n.lng));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))e.lineTo(n.x,n.y);e.lineJoin="round",e.lineCap="round",e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=5,e.stroke(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.stroke()}paintTraces(t){const{ctx:e}=this;for(const i of t.traces??[]){const n=i.points.map(a=>this.toCanvas(t.bounds,a.lat,a.lng));if(n.length===0)continue;const s=i.color??m2;if(i.kind==="point")e.beginPath(),e.moveTo(n[0].x,n[0].y-6),e.lineTo(n[0].x+6,n[0].y),e.lineTo(n[0].x,n[0].y+6),e.lineTo(n[0].x-6,n[0].y),e.closePath(),e.fillStyle=s,e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.8)",e.stroke();else{e.beginPath(),e.moveTo(n[0].x,n[0].y);for(const a of n.slice(1))e.lineTo(a.x,a.y);i.kind==="polygon"&&e.closePath(),e.lineJoin="round",e.setLineDash([]),e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=4.5,e.stroke(),e.setLineDash([9,5]),e.strokeStyle=s,e.lineWidth=2.5,e.stroke(),e.setLineDash([])}if(i.label){e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle";let a=n[0];if(i.kind==="line"&&t.position){const o=this.toCanvas(t.bounds,t.position.lat,t.position.lng);a=n.reduce((c,l)=>Math.hypot(l.x-o.x,l.y-o.y)>Math.hypot(c.x-o.x,c.y-o.y)?l:c)}this.paintOutlinedText(i.label,a.x+9,a.y-9)}}}paintCone(t,e){const{headingDeg:i,coneHalfAngleDeg:n}=t;if(i===void 0||n===void 0)return;const{ctx:s}=this,a=this.toCanvas(t.bounds,e.lat,e.lng),o=Math.hypot(this.width,this.height),c=(i-90)*Math.PI/180,l=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(a.x,a.y),s.arc(a.x,a.y,o,c-l,c+l),s.closePath();const h=s.createRadialGradient(a.x,a.y,0,a.x,a.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(t){const{ctx:e}=this;e.textAlign="center",e.textBaseline="middle",e.font="bold 10px sans-serif";for(const i of[...t.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(t.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:Ea.MARKER_RADIUS_PX}),e.beginPath(),e.arc(n.x,n.y,Ea.MARKER_RADIUS_PX,0,Math.PI*2),e.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",e.fill(),e.lineWidth=2,e.strokeStyle="rgba(255, 255, 255, 0.9)",e.stroke(),e.fillStyle=i.current?"#1d2321":"#fff",e.fillText(i.label,n.x,n.y)}}paintObserver(t,e){const{ctx:i}=this,n=this.toCanvas(t.bounds,e.lat,e.lng);t.observerLabel&&this.targets.push({kind:"observer",label:t.observerLabel,lat:e.lat,lng:e.lng,x:n.x,y:n.y,radius:8});const s=t.markers.some(a=>{if(!a.current)return!1;const o=Je(a.lat,a.lng,e.lat,e.lng);return Math.hypot(o.x,o.z)<=Ea.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?Ea.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:t}=this,e=this.width-14,i=16;t.beginPath(),t.moveTo(e,i-9),t.lineTo(e-4.5,i+5),t.lineTo(e,i+2),t.lineTo(e+4.5,i+5),t.closePath(),t.fillStyle="rgba(255, 255, 255, 0.92)",t.strokeStyle="rgba(0, 0, 0, 0.6)",t.lineWidth=1,t.fill(),t.stroke(),t.font="bold 9px sans-serif",t.textAlign="center",t.textBaseline="top",t.strokeText("N",e,i+6),t.fillText("N",e,i+6)}paintFooter(t,e){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=e?this.wrap(e,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const a=(t.south+t.north)/2,c=Math.abs(Je(a,t.east,a,t.west).x)/this.width,l=Ea.SCALE_STEPS_M.find(f=>f/c<=this.width/3);if(l===void 0)return;const h=l/c,u=8,d=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(u,d),i.lineTo(u+h,d),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(l>=1e3?`${l/1e3} km`:`${l} m`,u,d-3)}paintOutlinedText(t,e,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(t,e,i),n.fillStyle="#fff",n.fillText(t,e,i)}wrap(t,e){const i=[];let n="";for(const s of t.split(" ")){const a=n?`${n} ${s}`:s;n&&this.ctx.measureText(a).width>e?(i.push(n),n=s):n=a}return n&&i.push(n),i}}class Xe{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(t,e,i){const n=Math.min(Xe.MAX_ZOOM,Math.max(Xe.MIN_ZOOM,this.zoom*i)),s=this.centerX+(t-.5)/this.zoom,a=this.centerY+(e-.5)/this.zoom;this.centerX=s-(t-.5)/n,this.centerY=a-(e-.5)/n,this.zoom=n}panBy(t,e){this.centerX-=t/this.zoom,this.centerY-=e/this.zoom}refit(t,e){if(!this.changed)return;const i=this.boundsWithin(t),n=Xe.mercatorY01(e.north),s=Xe.mercatorY01(e.south),a=Xe.mercatorY01(i.north),o=Xe.mercatorY01(i.south);this.zoom=(e.east-e.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-e.west)/(e.east-e.west),this.centerY=((a+o)/2-n)/(s-n)}keepInView(t,e,i){if(!this.changed)return!1;const n=this.boundsWithin(t),s=Xe.mercatorY01(n.north),a=Xe.mercatorY01(n.south),o=(e.lng-n.west)/(n.east-n.west),c=(Xe.mercatorY01(e.lat)-s)/(a-s);return o>=i&&o<=1-i&&c>=i&&c<=1-i?!1:(this.panBy(.5-o,.5-c),!0)}boundsWithin(t){if(!this.changed)return t;const e=.5/this.zoom,i=Xe.mercatorY01(t.north),n=Xe.mercatorY01(t.south),s=t.east-t.west;return{west:t.west+(this.centerX-e)*s,east:t.west+(this.centerX+e)*s,north:Xe.latitudeAt(i+(this.centerY-e)*(n-i)),south:Xe.latitudeAt(i+(this.centerY+e)*(n-i))}}static including(t,e,i=3){const n=(t.north+t.south)/2,s=(t.east+t.west)/2,a=Je(n,t.east,n,s).x;let o=a;for(const c of e){const{x:l,z:h}=Je(c.lat,c.lng,n,s),u=Math.max(Math.abs(l),Math.abs(h));u<=a*i&&(o=Math.max(o,u*1.15))}return o<=a?t:{north:xn(0,-o,n,s).lat,south:xn(0,o,n,s).lat,east:xn(o,0,n,s).lng,west:xn(-o,0,n,s).lng}}static expand(t,e){const i=t.east-t.west,n=t.north-t.south;return{west:t.west-i*e,east:t.east+i*e,south:t.south-n*e,north:t.north+n*e}}static pointAt(t,e,i){const n=Xe.mercatorY01(t.north),s=Xe.mercatorY01(t.south);return{lat:Xe.latitudeAt(n+i*(s-n)),lng:t.west+e*(t.east-t.west)}}static mercatorY01(t){const e=t*Math.PI/180;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}static latitudeAt(t){return Math.atan(Math.sinh(Math.PI*(1-2*t)))*180/Math.PI}}const Sn=256,Lf=3,g2=32768;class v2{fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(t,e){const i=(t.south+t.north)/2,n=(t.west+t.east)/2,s=Math.abs(Je(i,t.east,i,t.west).x),a=Math.abs(Je(t.north,n,t.south,n).z),o=u2(i,Math.max(s,a)),{tiles:c}=Lg(n,i,o,Lf),l=Lf*Sn,h=new Float32Array(l*l),u=c[0];await Promise.all(c.map(f=>this.decodeTileInto(f,u,h,l)));const d=new Float32Array(e.width*e.height);for(let f=0;f<e.height;f++){const p=t.north+(t.south-t.north)*(f/(e.height-1));for(let v=0;v<e.width;v++){const m=t.west+(t.east-t.west)*(v/(e.width-1));d[f*e.width+v]=this.sampleAt(p,m,o,u,h,l)}}return{heights:d,width:e.width,height:e.height,bounds:t}}async decodeTileInto(t,e,i,n){const s=this.tileUrlTemplate.replace("{z}",String(t.z)).replace("{x}",String(t.x)).replace("{y}",String(t.y)),a=await this.fetchImpl(s);if(!a.ok)throw new Error(`Elevation tile fetch failed (${a.status}): ${s}`);const o=await createImageBitmap(await a.blob()),c=document.createElement("canvas");c.width=Sn,c.height=Sn;const l=c.getContext("2d");if(!l)throw new Error("2D canvas context unavailable");l.drawImage(o,0,0);const{data:h}=l.getImageData(0,0,Sn,Sn),u=(t.x-e.x)*Sn,d=(t.y-e.y)*Sn;for(let f=0;f<Sn;f++)for(let p=0;p<Sn;p++){const v=(f*Sn+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-g2,g=u+p,_=d+f;i[_*n+g]=m}}sampleAt(t,e,i,n,s,a){const{x:o,y:c}=Cg(e,t,i),l=(o-n.x)*Sn,h=(c-n.y)*Sn,u=Math.max(0,Math.min(a-1,Math.floor(l))),d=Math.max(0,Math.min(a-1,Math.floor(h))),f=Math.min(a-1,u+1),p=Math.min(a-1,d+1),v=l-u,m=h-d,g=s[d*a+u],_=s[d*a+f],y=s[p*a+u],M=s[p*a+f],b=g+(_-g)*v,w=y+(M-y)*v;return b+(w-b)*m}}const ml=256,M2=5;async function x2(r,t,e,i){const n=(r.south+r.north)/2,s=(r.west+r.east)/2,a=Math.abs(Je(n,r.east,n,r.west).x),o=Math.abs(Je(r.north,s,r.south,s).z),c=Math.max(a,o),{zoom:l,gridSize:h}=y2(n,c,Math.max(t.width,t.height)),{tiles:u,bounds:d}=Lg(s,n,l,h),f=h*ml,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=u[0];await Promise.all(u.map(async M=>{const b=e(M),w=await i(b);if(!w.ok)throw new Error(`Imagery tile fetch failed (${w.status}): ${b}`);const T=await createImageBitmap(await w.blob());v.drawImage(T,(M.x-m.x)*ml,(M.y-m.y)*ml)}));const g=Math.min(Math.max(t.width,t.height),f);if(g===f)return{source:p,width:f,height:f,bounds:d};const _=document.createElement("canvas");_.width=g,_.height=g;const y=_.getContext("2d");if(!y)throw new Error("2D canvas context unavailable");return y.drawImage(p,0,0,f,f,0,0,g,g),{source:_,width:g,height:g,bounds:d}}function y2(r,t,e){let i=d2(r,t/Math.max(1,e)),n=Of(r,i,t);for(;n>M2&&i>0;)i--,n=Of(r,i,t);return{zoom:i,gridSize:n,mPerPixel:Ig(r,i)/ml}}function Of(r,t,e){const i=Math.ceil(e/2/Ig(r,t));return Math.max(3,2*i+1)}class _2{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(t,e){return x2(t,e,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class Nn{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.endpoints=t.endpoints??Nn.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];way["highway"~"^(${Nn.DRIVABLE.join("|")})$"](${e});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||e.push({id:`osm-${i.id??e.length}`,name:s.name,surface:Nn.surfaceOf(s),widthM:Nn.widthOf(s),points:n.map(a=>({lat:a.lat,lng:a.lon}))})}return e}queued(t){const e=Nn.queue.then(t,t);return Nn.queue=e.catch(()=>{}),e}async ask(t){let e;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(t)}`);if(s.ok)return await s.json();if(e=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){e=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,Nn.RETRY_MS))}throw e??new Error("No Overpass instance answered")}static widthOf(t){const e=Number.parseFloat(t.width??t.est_width??"");if(Number.isFinite(e)&&e>0)return e;const i=Number.parseInt(t.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:Nn.WIDTH_M[t.highway]??Nn.DEFAULT_WIDTH_M}static surfaceOf(t){const e=t.surface;return e==="dirt"||e==="earth"||e==="mud"?"dirt":e==="gravel"||e==="fine_gravel"||e==="compacted"||e==="ground"||e==="sand"||e==="unpaved"?"gravel":e?"paved":t.highway==="track"?"gravel":"paved"}}const vh="https://ufoathome.org/roads/index.json";class p0{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??p0.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRoads(t);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(t){let e;try{e=await this.load()}catch{return}const i=e.find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){return this.index??=this.fetchFirstAvailable(),this.index}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.86.1")}`,e=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(e&&e!==vh?[e,vh]:[vh]).map(i=>i+t)}}function S2(){return{elevation:new v2,imagery:Og(),roads:b2()}}function Og(){return new _2}function b2(){return new p0({fallback:new Nn})}const w2=new Set,Lr="show-observer-map",Or="hide-milestones";class fe extends HTMLElement{static get observedAttributes(){return["src",Lr,Or]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new Xe;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=jl.create();issues=[];issueCheck=0;sightingAudio=new Qv;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=Eg;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");fe.setIcon(this.moreButton,t?Gt.UNFOLDED:Gt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<fe.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=Xe.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=Xe.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},fe.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=Xe.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Ev}</style>${wv}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new qo(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",e=>{e.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new Ea(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",e=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(e),this.beginTouchScrub(e)}),this.seekInput.addEventListener("pointerup",e=>{this.seekSnapArmed=!1,this.endTouchScrub(e)}),this.seekInput.addEventListener("pointercancel",e=>this.endTouchScrub(e)),this.seekInput.addEventListener("pointermove",e=>{this.nameMarkUnder(e),this.hoverSeek(e),this.touchScrub(e)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const e of["touchend","click"])this.stageElement.addEventListener(e,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",e=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}e.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",e=>{this.enableClickToPlay&&(e.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===Lr&&this.applyObserverMapDefault(),t===Or&&this.setMilestonesShown(!this.hasAttribute(Or))}async loadFromSrc(t){this.sightingData=await _g.json(t)}get sightingData(){return t2(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=i2(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await an(async()=>{const{default:a}=await import("./sightingSchema-DKClwkcL.js");return{default:a}},[],import.meta.url);n=new On(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Xr.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(E2,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Xr.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}toggleReferences(){this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity)),this.updateReferencesButton()}updateReferencesButton(){const t=this.currentSighting.references.length>0;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState,this.referencesButton.setAttribute("aria-pressed",String(this.referencesShownState)),fe.setIcon(this.referencesButton,this.referencesShownState?Gt.PICTURES_ON:Gt.PICTURES_OFF);const e=this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=e,this.referencesButton.setAttribute("aria-label",e),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),fe.setIcon(this.tracesButton,this.tracesShownState?Gt.TRACES_ON:Gt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Oo(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",a=this.said.read(i.note),o=a?`${s} — ${a}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const a=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${a} — ${o}`:a,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(a=>a>0&&a<t))].sort((a,o)=>a-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let a=0;a<n.length-1;a++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[a+1]-n[a],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[a],end:n[a+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=fe.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,a=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=fe.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===a))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?mh(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=fe.MARK_SNAP_PX/i*e;let s;for(const a of this.milestoneMarks.children){const o=Number(a.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:a.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?mh(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=zn.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<fe.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(fe.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/fe.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/fe.EXPOSURE_STEP_PX),s=Math.min(fe.MAX_TRAVEL_STEPS,Math.max(i,n)),a=[];for(let o=0;o<s;o++)a.push(e.fromMs+e.ms*o/(s-1));return a}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[a,o]of i){const c=n.get(a);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=mi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:w2;this.canvasRenderer.setStarPoints(mi.starPointsOf(this.sighting.instrument));const n=(Ze(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),a=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,c]of o.shapes){const l=o.share,h=l===1?c:{...c,transparency:1-(1-c.transparency)*l};this.canvasRenderer.paintShape(this.shifted(h,a))}for(const[o,c]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...c,selected:!0}):this.canvasRenderer.paintMemberOutline(c):this.canvasRenderer.paintSelectionOnly(this.shifted(c,a)));if(this.selectionShown&&i.size>1){const o=pn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(c=>c.transparency<1).map(c=>this.shifted(c,a).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(Xv(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Yv(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*fe.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton(),this.flashPlayback())}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Gt.PLAY:Gt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){fe.icons.get(t)!==e&&(fe.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},fe.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,fe.setIcon(this.playPauseButton,t?Gt.PAUSE:Gt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear()}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(Lr),e=t===null?this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;fe.setIcon(this.observerMapButton,t?Gt.MAP_ON:Gt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Cr.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=Xe.including(this.observerPath.boundsAround(fe.OBSERVER_MAP_MIN_SPAN_M,fe.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?Xe.expand(t,fe.OBSERVER_MAP_IMAGERY_AHEAD):t,n=fe.OBSERVER_MAP_IMAGERY_PX*(e?1+2*fe.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=Og();try{const a=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=a,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?Xe.expand(t,fe.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,a=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!a}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],a=fe.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],a))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=Ze(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},fe.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?mh(this.currentSighting.milestones,t):void 0;for(const a of this.milestonesShown?Oo(this.currentSighting.milestones):[]){const o=Ze(this.currentSighting,a.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(a.label)??"",note:this.said.read(a.note),t:a.t,lat:o.lat,lng:o.lng,current:a===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?Is.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(mi.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(a=>({kind:a.kind,points:a.points,color:a.color,label:this.said.read(a.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Oo(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,fe.setIcon(this.milestonesButton,this.milestonesShown?Gt.MILESTONES_ON:Gt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=Ze(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Go(i,t),{lat:s,lng:a}=xn(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:a,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=Ze(this.currentSighting,this.currentTime),s=Is.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return be.bodyAt(this.currentSighting,t,this.steadyObserver)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=fe.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.muted=!this.mutedState}updateMuteButton(){fe.setIcon(this.muteButton,this.mutedState?Gt.MUTED:Gt.VOLUME);const t=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=t,this.muteButton.setAttribute("aria-label",t),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;fe.setIcon(this.fullscreenButton,t?Gt.EXIT_FULLSCREEN:Gt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Rs(Pr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=bg(Pr.preferencesFor(this),wg);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await a2(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=Gv(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?zu(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return gc(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?Ff(Nf(this.realStartMs+i)):gc(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?gc(this.currentSighting.timeline.duration):this.canShowClockTime?Ff(Nf(this.realStartMs+this.realDurationMs)):gc(this.realDurationMs)}}function Nf(r){const t=new Date(r);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function Ff(r){if(r.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return r.second?`${t(r.hour)}:${t(r.minute??0)}:${t(r.second)}`:`${t(r.hour)}:${t(r.minute??0)}`}function gc(r){const t=Math.round(r/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const Hu="rr0-ufo";function Ng(){customElements.get(Hu)||customElements.define(Hu,fe)}const E2="recordingissues";/**
1366
+ `)}`)}}class On{constructor(t){this.format=t}issues(t){const e=[];return this.object(t,this.format,"",e),e}object(t,e,i,n){if(!On.isObject(t)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:On.typeOf(t)});return}for(const[s,a]of Object.entries(t)){const o=i?`${i}.${s}`:s,c=e[s];c?this.field(a,c,o,n):n.push({kind:"unknown-key",path:o})}}field(t,e,i,n){if(On.isStated(t)){this.field(t.value,e,i,n);return}if(!(e.loose||t===void 0||t===null))switch(e.type){case"enum":(typeof t!="string"||!e.values?.includes(t))&&n.push({kind:"not-in-list",path:i,expected:(e.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(t)});return;case"object":e.fields?this.object(t,e.fields,i,n):On.isObject(t)||n.push({kind:"wrong-type",path:i,expected:"object",found:On.typeOf(t)});return;case"array":Array.isArray(t)?e.fields&&t.forEach((s,a)=>{const o=On.isStated(s)?s.value:s;this.object(o,e.fields,`${i}.${a}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:On.typeOf(t)});return;default:typeof t!==e.type&&n.push({kind:"wrong-type",path:i,expected:e.type,found:On.typeOf(t)})}}static isObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}static isStated(t){return On.isObject(t)&&"value"in t&&Object.keys(t).every(e=>e==="value"||e==="basis"||e==="rationale")}static typeOf(t){return Array.isArray(t)?"array":t===null?"null":typeof t}}class zn{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(t,e){const i=Number.isFinite(e)?Math.max(0,e):0,n=Math.max(0,t-i*1e3),s=Math.max(0,t-n);return{fromMs:n,toMs:t,ms:s,seconds:s/1e3}}static instants(t,e,i,n,s){if(!(n>0))return 1;const a=s>0?zn.travelDegOver(t,e,i,i+n*1e3)/s/zn.PIXELS_PER_INSTANT:0,o=zn.flashesOver(t,n)*zn.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(a,o));return c<2?1:Math.min(zn.MAX_INSTANTS,c)}static travelDegOver(t,e,i,n){let s=0;for(const a of t){if(!a.track||a.track.length<2)continue;const o=zn.directionAt(a,e,i),c=zn.directionAt(a,e,n),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));s=Math.max(s,Math.acos(l)*180/Math.PI)}return s}static flashesOver(t,e){let i=0;for(const n of t)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*e}static directionAt(t,e,i){const n=Go(t,i),s=n.eastM,a=n.altitudeM-e,o=n.northM,c=Math.hypot(s,a,o);return c===0?{x:0,y:1,z:0}:{x:s/c,y:a/c,z:o/c}}}function bg(r,t){for(const e of r){const i=e.toLowerCase().split("-")[0];if(t.includes(i))return i}return"en"}class Pr{static preferencesFor(t){const e=navigator.languages??[],i=this.declaredFor(t);return i?[i,...e]:e}static declaredFor(t){for(let e=t;e;){const i=e.closest("[lang]")?.getAttribute("lang")?.trim();if(i)return i;const n=e.getRootNode();e=n instanceof ShadowRoot?n.host:void 0}}}class Rs{constructor(t){this.preferences=t}read(t){if(t===void 0||typeof t=="string")return t===""?void 0:t;for(const i of this.preferences){const n=t[i]??t[Rs.base(i)];if(n)return n}const e=new Set(this.preferences.map(i=>Rs.base(i)));for(const[i,n]of Object.entries(t))if(n&&e.has(Rs.base(i)))return n;return Object.values(t).find(i=>i)??void 0}write(t,e,i){const n=e?.trim()?e.trim():void 0;if(t===void 0||typeof t=="string")return n;const s={...t},a=Object.keys(s).find(o=>o===i)??Object.keys(s).find(o=>Rs.base(o)===Rs.base(i))??i;return n===void 0?delete s[a]:s[a]=n,Object.keys(s).length===0?void 0:s}static base(t){return t.toLowerCase().split("-")[0]}}const wg=["en","fr","es","it"],s2={en:()=>an(()=>Promise.resolve().then(()=>o2),void 0,import.meta.url).then(r=>r.ufoMessages_en),fr:()=>an(()=>import("./UfoMessages_fr-BMafKxyw.js"),[],import.meta.url).then(r=>r.ufoMessages_fr),es:()=>an(()=>import("./UfoMessages_es-8Us-3wIq.js"),[],import.meta.url).then(r=>r.ufoMessages_es),it:()=>an(()=>import("./UfoMessages_it-C7cNoyQt.js"),[],import.meta.url).then(r=>r.ufoMessages_it)};function a2(r){return s2[r]()}function r2(r){switch(r){case"fr":return an(()=>import("./SceneNames_fr-DYU3H8s1.js"),[],import.meta.url).then(t=>t.sceneNames_fr);case"es":return an(()=>import("./SceneNames_es-DjVl7xge.js"),[],import.meta.url).then(t=>t.sceneNames_es);case"it":return an(()=>import("./SceneNames_it-Box-aRN9.js"),[],import.meta.url).then(t=>t.sceneNames_it);default:return Promise.resolve(void 0)}}const Eg={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",showTraces:"Show the investigator's lines",hideTraces:"Hide the investigator's lines",referenceOpacity:"Picture opacity",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Xr.EN},o2=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:Eg},Symbol.toStringTag,{value:"Module"})),Ag=Math.PI/180,c2=180/Math.PI,l2=256,Tg=19,h2=1.25;function Rg(r,t){return 156543.03392*Math.cos(r*Ag)/2**t}function Dg(r,t){return Rg(r,t)*l2}function u2(r,t){let e=0;for(;e<Tg&&Dg(r,e+1)>=t;)e++;return e}function Ig(r,t){return Dg(r,t)}function d2(r,t){const e=t*h2;let i=0;for(;i<Tg&&Rg(r,i)>e;)i++;return i}function pl(r){const t=r*Ag;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}function Cg(r,t,e){const i=2**e;return{x:(r+180)/360*i,y:pl(t)*i}}function Pg(r,t,e){const i=pl(r.north),n=pl(r.south);return{x:(t-r.west)/(r.east-r.west),y:(pl(e)-i)/(n-i)}}function f2(r,t,e){const{x:i,y:n}=Cg(r,t,e);return{x:Math.floor(i),y:Math.floor(n),z:e}}function p2(r){const t=2**r.z,e=r.x/t*360-180,i=(r.x+1)/t*360-180,n=Pf(r.y,t);return{south:Pf(r.y+1,t),north:n,west:e,east:i}}function Pf(r,t){const e=r/t;return Math.atan(Math.sinh(Math.PI*(1-2*e)))*c2}function Lg(r,t,e,i){const n=f2(r,t,e),s=Math.floor(i/2),a=[];for(let l=-s;l<=s;l++)for(let h=-s;h<=s;h++)a.push({x:n.x+h,y:n.y+l,z:e});const o=a.map(p2),c={south:Math.min(...o.map(l=>l.south)),north:Math.max(...o.map(l=>l.north)),west:Math.min(...o.map(l=>l.west)),east:Math.max(...o.map(l=>l.east))};return{tiles:a,bounds:c}}const m2="#2ec4ff";class Ea{constructor(t){this.ctx=t}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(t,e){let i,n=1/0;for(const s of this.targets){const a=Math.hypot(s.x-t,s.y-e);a>s.radius||a>n||(i=s,n=a)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(t){const{ctx:e}=this;e.save(),this.targets=[],e.clearRect(0,0,this.width,this.height),this.paintGround(t),this.paintNight(t.nightFraction),this.paintPath(t),this.paintTraces(t),t.position?(this.paintCone(t,t.position),this.paintDecor(t),this.paintMarkers(t),this.paintObserver(t,t.position)):(this.paintDecor(t),this.paintMarkers(t)),this.paintNorth(),this.paintFooter(t.bounds,t.attribution),e.restore()}toCanvas(t,e,i){const n=Pg(t,i,e);return{x:n.x*this.width,y:n.y*this.height}}paintGround(t){const{ctx:e}=this;e.fillStyle="#1d2321",e.fillRect(0,0,this.width,this.height);const i=t.imagery;if(!i)return;const n=this.toCanvas(t.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(t.bounds,i.bounds.south,i.bounds.east);e.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(t=0){if(t<=0)return;const{ctx:e}=this;e.save(),e.fillStyle=`rgba(6, 12, 30, ${Math.min(t,1)*.78})`,e.fillRect(0,0,this.width,this.height),e.restore()}paintDecor(t){const{ctx:e}=this;for(const i of t.decor){const n=this.toCanvas(t.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),e.beginPath(),e.rect(n.x-3.5,n.y-3.5,7,7),e.fillStyle="rgba(120, 220, 255, 0.85)",e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.7)",e.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),e.lineWidth=3,e.strokeStyle="rgba(0, 0, 0, 0.6)",e.stroke(),e.lineWidth=1.5,e.strokeStyle="rgba(120, 220, 255, 0.9)",e.stroke()}}paintPath(t){if(!t.path.moved)return;const{ctx:e}=this,i=t.path.points.map(n=>this.toCanvas(t.bounds,n.lat,n.lng));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))e.lineTo(n.x,n.y);e.lineJoin="round",e.lineCap="round",e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=5,e.stroke(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.stroke()}paintTraces(t){const{ctx:e}=this;for(const i of t.traces??[]){const n=i.points.map(a=>this.toCanvas(t.bounds,a.lat,a.lng));if(n.length===0)continue;const s=i.color??m2;if(i.kind==="point")e.beginPath(),e.moveTo(n[0].x,n[0].y-6),e.lineTo(n[0].x+6,n[0].y),e.lineTo(n[0].x,n[0].y+6),e.lineTo(n[0].x-6,n[0].y),e.closePath(),e.fillStyle=s,e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.8)",e.stroke();else{e.beginPath(),e.moveTo(n[0].x,n[0].y);for(const a of n.slice(1))e.lineTo(a.x,a.y);i.kind==="polygon"&&e.closePath(),e.lineJoin="round",e.setLineDash([]),e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=4.5,e.stroke(),e.setLineDash([9,5]),e.strokeStyle=s,e.lineWidth=2.5,e.stroke(),e.setLineDash([])}if(i.label){e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle";let a=n[0];if(i.kind==="line"&&t.position){const o=this.toCanvas(t.bounds,t.position.lat,t.position.lng);a=n.reduce((c,l)=>Math.hypot(l.x-o.x,l.y-o.y)>Math.hypot(c.x-o.x,c.y-o.y)?l:c)}this.paintOutlinedText(i.label,a.x+9,a.y-9)}}}paintCone(t,e){const{headingDeg:i,coneHalfAngleDeg:n}=t;if(i===void 0||n===void 0)return;const{ctx:s}=this,a=this.toCanvas(t.bounds,e.lat,e.lng),o=Math.hypot(this.width,this.height),c=(i-90)*Math.PI/180,l=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(a.x,a.y),s.arc(a.x,a.y,o,c-l,c+l),s.closePath();const h=s.createRadialGradient(a.x,a.y,0,a.x,a.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(t){const{ctx:e}=this;e.textAlign="center",e.textBaseline="middle",e.font="bold 10px sans-serif";for(const i of[...t.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(t.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:Ea.MARKER_RADIUS_PX}),e.beginPath(),e.arc(n.x,n.y,Ea.MARKER_RADIUS_PX,0,Math.PI*2),e.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",e.fill(),e.lineWidth=2,e.strokeStyle="rgba(255, 255, 255, 0.9)",e.stroke(),e.fillStyle=i.current?"#1d2321":"#fff",e.fillText(i.label,n.x,n.y)}}paintObserver(t,e){const{ctx:i}=this,n=this.toCanvas(t.bounds,e.lat,e.lng);t.observerLabel&&this.targets.push({kind:"observer",label:t.observerLabel,lat:e.lat,lng:e.lng,x:n.x,y:n.y,radius:8});const s=t.markers.some(a=>{if(!a.current)return!1;const o=Je(a.lat,a.lng,e.lat,e.lng);return Math.hypot(o.x,o.z)<=Ea.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?Ea.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:t}=this,e=this.width-14,i=16;t.beginPath(),t.moveTo(e,i-9),t.lineTo(e-4.5,i+5),t.lineTo(e,i+2),t.lineTo(e+4.5,i+5),t.closePath(),t.fillStyle="rgba(255, 255, 255, 0.92)",t.strokeStyle="rgba(0, 0, 0, 0.6)",t.lineWidth=1,t.fill(),t.stroke(),t.font="bold 9px sans-serif",t.textAlign="center",t.textBaseline="top",t.strokeText("N",e,i+6),t.fillText("N",e,i+6)}paintFooter(t,e){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=e?this.wrap(e,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const a=(t.south+t.north)/2,c=Math.abs(Je(a,t.east,a,t.west).x)/this.width,l=Ea.SCALE_STEPS_M.find(f=>f/c<=this.width/3);if(l===void 0)return;const h=l/c,u=8,d=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(u,d),i.lineTo(u+h,d),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(l>=1e3?`${l/1e3} km`:`${l} m`,u,d-3)}paintOutlinedText(t,e,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(t,e,i),n.fillStyle="#fff",n.fillText(t,e,i)}wrap(t,e){const i=[];let n="";for(const s of t.split(" ")){const a=n?`${n} ${s}`:s;n&&this.ctx.measureText(a).width>e?(i.push(n),n=s):n=a}return n&&i.push(n),i}}class Xe{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(t,e,i){const n=Math.min(Xe.MAX_ZOOM,Math.max(Xe.MIN_ZOOM,this.zoom*i)),s=this.centerX+(t-.5)/this.zoom,a=this.centerY+(e-.5)/this.zoom;this.centerX=s-(t-.5)/n,this.centerY=a-(e-.5)/n,this.zoom=n}panBy(t,e){this.centerX-=t/this.zoom,this.centerY-=e/this.zoom}refit(t,e){if(!this.changed)return;const i=this.boundsWithin(t),n=Xe.mercatorY01(e.north),s=Xe.mercatorY01(e.south),a=Xe.mercatorY01(i.north),o=Xe.mercatorY01(i.south);this.zoom=(e.east-e.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-e.west)/(e.east-e.west),this.centerY=((a+o)/2-n)/(s-n)}keepInView(t,e,i){if(!this.changed)return!1;const n=this.boundsWithin(t),s=Xe.mercatorY01(n.north),a=Xe.mercatorY01(n.south),o=(e.lng-n.west)/(n.east-n.west),c=(Xe.mercatorY01(e.lat)-s)/(a-s);return o>=i&&o<=1-i&&c>=i&&c<=1-i?!1:(this.panBy(.5-o,.5-c),!0)}boundsWithin(t){if(!this.changed)return t;const e=.5/this.zoom,i=Xe.mercatorY01(t.north),n=Xe.mercatorY01(t.south),s=t.east-t.west;return{west:t.west+(this.centerX-e)*s,east:t.west+(this.centerX+e)*s,north:Xe.latitudeAt(i+(this.centerY-e)*(n-i)),south:Xe.latitudeAt(i+(this.centerY+e)*(n-i))}}static including(t,e,i=3){const n=(t.north+t.south)/2,s=(t.east+t.west)/2,a=Je(n,t.east,n,s).x;let o=a;for(const c of e){const{x:l,z:h}=Je(c.lat,c.lng,n,s),u=Math.max(Math.abs(l),Math.abs(h));u<=a*i&&(o=Math.max(o,u*1.15))}return o<=a?t:{north:xn(0,-o,n,s).lat,south:xn(0,o,n,s).lat,east:xn(o,0,n,s).lng,west:xn(-o,0,n,s).lng}}static expand(t,e){const i=t.east-t.west,n=t.north-t.south;return{west:t.west-i*e,east:t.east+i*e,south:t.south-n*e,north:t.north+n*e}}static pointAt(t,e,i){const n=Xe.mercatorY01(t.north),s=Xe.mercatorY01(t.south);return{lat:Xe.latitudeAt(n+i*(s-n)),lng:t.west+e*(t.east-t.west)}}static mercatorY01(t){const e=t*Math.PI/180;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}static latitudeAt(t){return Math.atan(Math.sinh(Math.PI*(1-2*t)))*180/Math.PI}}const Sn=256,Lf=3,g2=32768;class v2{fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(t,e){const i=(t.south+t.north)/2,n=(t.west+t.east)/2,s=Math.abs(Je(i,t.east,i,t.west).x),a=Math.abs(Je(t.north,n,t.south,n).z),o=u2(i,Math.max(s,a)),{tiles:c}=Lg(n,i,o,Lf),l=Lf*Sn,h=new Float32Array(l*l),u=c[0];await Promise.all(c.map(f=>this.decodeTileInto(f,u,h,l)));const d=new Float32Array(e.width*e.height);for(let f=0;f<e.height;f++){const p=t.north+(t.south-t.north)*(f/(e.height-1));for(let v=0;v<e.width;v++){const m=t.west+(t.east-t.west)*(v/(e.width-1));d[f*e.width+v]=this.sampleAt(p,m,o,u,h,l)}}return{heights:d,width:e.width,height:e.height,bounds:t}}async decodeTileInto(t,e,i,n){const s=this.tileUrlTemplate.replace("{z}",String(t.z)).replace("{x}",String(t.x)).replace("{y}",String(t.y)),a=await this.fetchImpl(s);if(!a.ok)throw new Error(`Elevation tile fetch failed (${a.status}): ${s}`);const o=await createImageBitmap(await a.blob()),c=document.createElement("canvas");c.width=Sn,c.height=Sn;const l=c.getContext("2d");if(!l)throw new Error("2D canvas context unavailable");l.drawImage(o,0,0);const{data:h}=l.getImageData(0,0,Sn,Sn),u=(t.x-e.x)*Sn,d=(t.y-e.y)*Sn;for(let f=0;f<Sn;f++)for(let p=0;p<Sn;p++){const v=(f*Sn+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-g2,g=u+p,_=d+f;i[_*n+g]=m}}sampleAt(t,e,i,n,s,a){const{x:o,y:c}=Cg(e,t,i),l=(o-n.x)*Sn,h=(c-n.y)*Sn,u=Math.max(0,Math.min(a-1,Math.floor(l))),d=Math.max(0,Math.min(a-1,Math.floor(h))),f=Math.min(a-1,u+1),p=Math.min(a-1,d+1),v=l-u,m=h-d,g=s[d*a+u],_=s[d*a+f],y=s[p*a+u],M=s[p*a+f],b=g+(_-g)*v,w=y+(M-y)*v;return b+(w-b)*m}}const ml=256,M2=5;async function x2(r,t,e,i){const n=(r.south+r.north)/2,s=(r.west+r.east)/2,a=Math.abs(Je(n,r.east,n,r.west).x),o=Math.abs(Je(r.north,s,r.south,s).z),c=Math.max(a,o),{zoom:l,gridSize:h}=y2(n,c,Math.max(t.width,t.height)),{tiles:u,bounds:d}=Lg(s,n,l,h),f=h*ml,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=u[0];await Promise.all(u.map(async M=>{const b=e(M),w=await i(b);if(!w.ok)throw new Error(`Imagery tile fetch failed (${w.status}): ${b}`);const T=await createImageBitmap(await w.blob());v.drawImage(T,(M.x-m.x)*ml,(M.y-m.y)*ml)}));const g=Math.min(Math.max(t.width,t.height),f);if(g===f)return{source:p,width:f,height:f,bounds:d};const _=document.createElement("canvas");_.width=g,_.height=g;const y=_.getContext("2d");if(!y)throw new Error("2D canvas context unavailable");return y.drawImage(p,0,0,f,f,0,0,g,g),{source:_,width:g,height:g,bounds:d}}function y2(r,t,e){let i=d2(r,t/Math.max(1,e)),n=Of(r,i,t);for(;n>M2&&i>0;)i--,n=Of(r,i,t);return{zoom:i,gridSize:n,mPerPixel:Ig(r,i)/ml}}function Of(r,t,e){const i=Math.ceil(e/2/Ig(r,t));return Math.max(3,2*i+1)}class _2{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(t,e){return x2(t,e,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class Nn{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.endpoints=t.endpoints??Nn.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];way["highway"~"^(${Nn.DRIVABLE.join("|")})$"](${e});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||e.push({id:`osm-${i.id??e.length}`,name:s.name,surface:Nn.surfaceOf(s),widthM:Nn.widthOf(s),points:n.map(a=>({lat:a.lat,lng:a.lon}))})}return e}queued(t){const e=Nn.queue.then(t,t);return Nn.queue=e.catch(()=>{}),e}async ask(t){let e;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(t)}`);if(s.ok)return await s.json();if(e=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){e=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,Nn.RETRY_MS))}throw e??new Error("No Overpass instance answered")}static widthOf(t){const e=Number.parseFloat(t.width??t.est_width??"");if(Number.isFinite(e)&&e>0)return e;const i=Number.parseInt(t.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:Nn.WIDTH_M[t.highway]??Nn.DEFAULT_WIDTH_M}static surfaceOf(t){const e=t.surface;return e==="dirt"||e==="earth"||e==="mud"?"dirt":e==="gravel"||e==="fine_gravel"||e==="compacted"||e==="ground"||e==="sand"||e==="unpaved"?"gravel":e?"paved":t.highway==="track"?"gravel":"paved"}}const vh="https://ufoathome.org/roads/index.json";class p0{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??p0.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRoads(t);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(t){let e;try{e=await this.load()}catch{return}const i=e.find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){return this.index??=this.fetchFirstAvailable(),this.index}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.86.2")}`,e=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(e&&e!==vh?[e,vh]:[vh]).map(i=>i+t)}}function S2(){return{elevation:new v2,imagery:Og(),roads:b2()}}function Og(){return new _2}function b2(){return new p0({fallback:new Nn})}const w2=new Set,Lr="show-observer-map",Or="hide-milestones";class fe extends HTMLElement{static get observedAttributes(){return["src",Lr,Or]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new Xe;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=jl.create();issues=[];issueCheck=0;sightingAudio=new Qv;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=Eg;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");fe.setIcon(this.moreButton,t?Gt.UNFOLDED:Gt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<fe.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=Xe.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=Xe.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},fe.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=Xe.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Ev}</style>${wv}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new qo(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",e=>{e.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new Ea(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",e=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(e),this.beginTouchScrub(e)}),this.seekInput.addEventListener("pointerup",e=>{this.seekSnapArmed=!1,this.endTouchScrub(e)}),this.seekInput.addEventListener("pointercancel",e=>this.endTouchScrub(e)),this.seekInput.addEventListener("pointermove",e=>{this.nameMarkUnder(e),this.hoverSeek(e),this.touchScrub(e)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const e of["touchend","click"])this.stageElement.addEventListener(e,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",e=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}e.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",e=>{this.enableClickToPlay&&(e.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===Lr&&this.applyObserverMapDefault(),t===Or&&this.setMilestonesShown(!this.hasAttribute(Or))}async loadFromSrc(t){this.sightingData=await _g.json(t)}get sightingData(){return t2(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=i2(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await an(async()=>{const{default:a}=await import("./sightingSchema-D7VMkxdw.js");return{default:a}},[],import.meta.url);n=new On(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Xr.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(E2,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Xr.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}toggleReferences(){this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity)),this.updateReferencesButton()}updateReferencesButton(){const t=this.currentSighting.references.length>0;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState,this.referencesButton.setAttribute("aria-pressed",String(this.referencesShownState)),fe.setIcon(this.referencesButton,this.referencesShownState?Gt.PICTURES_ON:Gt.PICTURES_OFF);const e=this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=e,this.referencesButton.setAttribute("aria-label",e),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),fe.setIcon(this.tracesButton,this.tracesShownState?Gt.TRACES_ON:Gt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Oo(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",a=this.said.read(i.note),o=a?`${s} — ${a}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const a=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${a} — ${o}`:a,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(a=>a>0&&a<t))].sort((a,o)=>a-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let a=0;a<n.length-1;a++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[a+1]-n[a],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[a],end:n[a+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=fe.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,a=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=fe.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===a))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?mh(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=fe.MARK_SNAP_PX/i*e;let s;for(const a of this.milestoneMarks.children){const o=Number(a.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:a.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?mh(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=zn.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<fe.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(fe.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/fe.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/fe.EXPOSURE_STEP_PX),s=Math.min(fe.MAX_TRAVEL_STEPS,Math.max(i,n)),a=[];for(let o=0;o<s;o++)a.push(e.fromMs+e.ms*o/(s-1));return a}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[a,o]of i){const c=n.get(a);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=mi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:w2;this.canvasRenderer.setStarPoints(mi.starPointsOf(this.sighting.instrument));const n=(Ze(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),a=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,c]of o.shapes){const l=o.share,h=l===1?c:{...c,transparency:1-(1-c.transparency)*l};this.canvasRenderer.paintShape(this.shifted(h,a))}for(const[o,c]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...c,selected:!0}):this.canvasRenderer.paintMemberOutline(c):this.canvasRenderer.paintSelectionOnly(this.shifted(c,a)));if(this.selectionShown&&i.size>1){const o=pn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(c=>c.transparency<1).map(c=>this.shifted(c,a).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(Xv(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Yv(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*fe.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton(),this.flashPlayback())}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Gt.PLAY:Gt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){fe.icons.get(t)!==e&&(fe.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},fe.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,fe.setIcon(this.playPauseButton,t?Gt.PAUSE:Gt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear(),this.dispatchEvent(new CustomEvent("observermapchange",{bubbles:!0,composed:!0,detail:{open:t}}))}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(Lr),e=t===null?this.sighting.observerMap??this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;fe.setIcon(this.observerMapButton,t?Gt.MAP_ON:Gt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Cr.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=Xe.including(this.observerPath.boundsAround(fe.OBSERVER_MAP_MIN_SPAN_M,fe.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?Xe.expand(t,fe.OBSERVER_MAP_IMAGERY_AHEAD):t,n=fe.OBSERVER_MAP_IMAGERY_PX*(e?1+2*fe.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=Og();try{const a=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=a,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?Xe.expand(t,fe.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,a=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!a}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],a=fe.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],a))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=Ze(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},fe.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?mh(this.currentSighting.milestones,t):void 0;for(const a of this.milestonesShown?Oo(this.currentSighting.milestones):[]){const o=Ze(this.currentSighting,a.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(a.label)??"",note:this.said.read(a.note),t:a.t,lat:o.lat,lng:o.lng,current:a===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?Is.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(mi.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(a=>({kind:a.kind,points:a.points,color:a.color,label:this.said.read(a.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Oo(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,fe.setIcon(this.milestonesButton,this.milestonesShown?Gt.MILESTONES_ON:Gt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=Ze(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Go(i,t),{lat:s,lng:a}=xn(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:a,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=Ze(this.currentSighting,this.currentTime),s=Is.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return be.bodyAt(this.currentSighting,t,this.steadyObserver)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=fe.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.muted=!this.mutedState}updateMuteButton(){fe.setIcon(this.muteButton,this.mutedState?Gt.MUTED:Gt.VOLUME);const t=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=t,this.muteButton.setAttribute("aria-label",t),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;fe.setIcon(this.fullscreenButton,t?Gt.EXIT_FULLSCREEN:Gt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Rs(Pr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=bg(Pr.preferencesFor(this),wg);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await a2(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=Gv(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?zu(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return gc(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?Ff(Nf(this.realStartMs+i)):gc(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?gc(this.currentSighting.timeline.duration):this.canShowClockTime?Ff(Nf(this.realStartMs+this.realDurationMs)):gc(this.realDurationMs)}}function Nf(r){const t=new Date(r);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function Ff(r){if(r.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return r.second?`${t(r.hour)}:${t(r.minute??0)}:${t(r.second)}`:`${t(r.hour)}:${t(r.minute??0)}`}function gc(r){const t=Math.round(r/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const Hu="rr0-ufo";function Ng(){customElements.get(Hu)||customElements.define(Hu,fe)}const E2="recordingissues";/**
1367
1367
  * @license
1368
1368
  * Copyright 2010-2026 Three.js Authors
1369
1369
  * SPDX-License-Identifier: MIT
@@ -7213,7 +7213,7 @@ void main()
7213
7213
  if (ice <= 0.0) discard;
7214
7214
  gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
7215
7215
  }
7216
- `,transparent:!0,blending:Ai,depthWrite:!1,side:Ye,fog:!1}),this.object=new Tt(new ui(Oi.RADIUS,64,32),this.material),this.object.renderOrder=-1,this.object.frustumCulled=!1,this.object.visible=!1;const i=this.material.uniforms;this.deckUniforms={uSource:i.uSource,uUp:i.uUp,uStrength:i.uStrength,uTint:i.uTint,uMap:i.uMap,uGain:i.uGain,uHaloShown:{value:0}}}deckUniforms;shown=!1;hostedByDeck=!1;set hosted(t){this.hostedByDeck=t,this.show(this.shown)}show(t){this.shown=t,this.object.visible=t&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=t?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(t){this.urgent=t}set onReady(t){this.onRepaint=t}update(t,e,i,n,s,a){const o=this.material.uniforms;if(i<=0){o.uStrength.value=0,this.show(!1),this.stopWork();return}o.uSource.value.set(t.x,t.y,t.z).normalize(),o.uStrength.value=i,o.uTint.value.set(n[0],n[1],n[2]),o.uIceCover.value=s.cover,o.uIceHeight.value=s.layerHeight,this.show(this.everDisplayed),this.requestMap(e,a)}requestMap(t,e){if(!(!(Math.abs(t-this.mappedAltitudeDeg)<Oi.ALTITUDE_STEP_DEG)||!(Math.abs(e-this.mappedAlignment)<Oi.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(t,e)){this.next=void 0;return}if(!(!(Math.abs(t-this.pendingAltitudeDeg)<Oi.LEAP_ALTITUDE_DEG)||!(Math.abs(e-this.pendingAlignment)<Oi.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:t,alignment:e};return}}this.next=void 0,this.pendingAltitudeDeg=t,this.pendingAlignment=e,this.sky.begin(t,e),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(t,e){return this.tracing&&Math.abs(t-this.pendingAltitudeDeg)<Oi.ALTITUDE_STEP_DEG&&Math.abs(e-this.pendingAlignment)<Oi.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const t=()=>{if(this.workHandle=void 0,!this.tracing)return;const e=performance.now(),i=this.urgent?Oi.URGENT_BUDGET_MS:Oi.BUDGET_MS;do this.sky.trace(Oi.RAYS_PER_BATCH);while(this.sky.tracedRays<Oi.RAYS&&performance.now()-e<i);if(this.sky.tracedRays>=Oi.RAYS){this.publish(),this.tracing=!1,this.mappedAltitudeDeg=this.pendingAltitudeDeg,this.mappedAlignment=this.pendingAlignment;const s=this.next;s&&this.requestMap(s.sourceAltitudeDeg,s.alignment);return}this.workHandle=requestAnimationFrame(t)};this.workHandle=requestAnimationFrame(t)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const e=this.sky.harvest().data;for(let i=0,n=0;n<e.length;i+=4,n+=3)this.texels[i]=Xn.toHalfFloat(e[n]),this.texels[i+1]=Xn.toHalfFloat(e[n+1]),this.texels[i+2]=Xn.toHalfFloat(e[n+2]),this.texels[i+3]=1;this.texture.needsUpdate=!0,this.everDisplayed=!0,this.show(this.material.uniforms.uStrength.value>0),this.onRepaint?.()}dispose(){this.stopWork(),this.texture.dispose(),this.object.geometry.dispose(),this.material.dispose()}}class Si{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=Si.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(Si.ACROSS-1)*6;static RADIUS=840;static MIN_HALF_WIDTH_DEG=.05;static BRIGHT_HALF_WIDTH_DEG=.22;object;positions;colors;meteors=[];radiantAltitudeDeg=0;radiantAzimuthDeg=0;constructor(){const t=Si.MAX_CONCURRENT*Si.SEGMENTS*Si.VERTICES_PER_SEGMENT;this.positions=new Float32Array(t*3),this.colors=new Float32Array(t*3);const e=new ne;e.setAttribute("position",new Zt(this.positions,3)),e.setAttribute("color",new Zt(this.colors,3)),e.setDrawRange(0,0),this.object=new Tt(e,new yn({vertexColors:!0,transparent:!0,blending:Ai,depthWrite:!1,fog:!1,side:Yi})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(t,e,i){this.meteors=t,this.radiantAltitudeDeg=e,this.radiantAzimuthDeg=i}update(t){const e=this.object.geometry;if(this.meteors.length===0){e.setDrawRange(0,0);return}const i=za.aliveAt(this.meteors,t).slice(0,Si.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=Ke(o.altitudeDeg,o.azimuthDeg,1),[l,h]=this.basisAround(c),u=s.fromRadiantDeg+a*s.lengthDeg,d=Math.max(s.fromRadiantDeg,u-s.lengthDeg*.6),f=Math.min(1,(1-a)*2.5),p=this.turn(l,h,s.bearingDeg),v=(.15+.85*s.brightness)*f,m=y=>v*y**1.6,g=y=>this.onSphere(c,p,d+(u-d)*y),_=y=>Si.RADIUS*((Si.MIN_HALF_WIDTH_DEG+Si.BRIGHT_HALF_WIDTH_DEG*s.brightness*y)*Math.PI/180);for(let y=1;y<Si.POINTS;y++){const M=(y-1)/Si.SEGMENTS,b=y/Si.SEGMENTS;n=this.pushRibbon(n,g(M),g(b),_(M),_(b),m(M),m(b))}}e.setDrawRange(0,n),e.getAttribute("position").needsUpdate=!0,e.getAttribute("color").needsUpdate=!0}midpointOf(t){const e=this.radiantOf(t);if(!e)return;const i=Ke(e.altitudeDeg,e.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,t.bearingDeg),o=this.onSphere(i,a,t.fromRadiantDeg+t.lengthDeg/2),c=Math.hypot(o.x,o.y,o.z)||1;return{altitudeDeg:Math.asin(o.y/c)*180/Math.PI,azimuthDeg:(Math.atan2(o.x,-o.z)*180/Math.PI+360)%360}}radiantOf(t){return t.radiant?t.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(t,e,i,n,s,a,o){const c=this.normalise(this.cross(this.normalise(e),this.normalise(this.subtract(i,e))));for(let l=0;l<Si.ACROSS-1;l++){const h=l-1,u=l,d=this.across(e,c,n,h),f=this.across(i,c,s,h),p=this.across(e,c,n,u),v=this.across(i,c,s,u),m=(g,_)=>g===0?_:0;t=this.push(t,d,m(h,a)),t=this.push(t,f,m(h,o)),t=this.push(t,p,m(u,a)),t=this.push(t,f,m(h,o)),t=this.push(t,v,m(u,o)),t=this.push(t,p,m(u,a))}return t}across(t,e,i,n){return{x:t.x+e.x*i*n,y:t.y+e.y*i*n,z:t.z+e.z*i*n}}push(t,e,i){const n=t*3;this.positions[n]=e.x,this.positions[n+1]=e.y,this.positions[n+2]=e.z;const s=wt.relativeOfResponse(Math.max(0,Math.min(1,i)));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,t+1}turn(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:t.x*s+e.x*a,y:t.y*s+e.y*a,z:t.z*s+e.z*a}}onSphere(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(t.x*s+e.x*a)*Si.RADIUS,y:(t.y*s+e.y*a)*Si.RADIUS,z:(t.z*s+e.z*a)*Si.RADIUS}}basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(t,e));return[i,this.normalise(this.cross(t,i))]}subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}class Fe{constructor(t,e={}){this.size=t,this.span=Math.min(t.lengthM,Math.max(0,e.spanM??t.lengthM)),this.bank=(t.lengthM-this.span)/2,this.deck=Math.min(t.heightM,e.deckThicknessM??Fe.DEFAULT_DECK_THICKNESS_M),this.railHeight=e.railing?.heightM??Fe.DEFAULT_RAILING_HEIGHT_M,this.postSpacing=Math.max(.3,e.railing?.postSpacingM??Fe.DEFAULT_POST_SPACING_M),this.rails=Math.max(0,Math.round(e.railing?.rails??Fe.DEFAULT_RAILS))}static DEFAULT_DECK_THICKNESS_M=1.2;static DEFAULT_RAILING_HEIGHT_M=1.05;static DEFAULT_POST_SPACING_M=1.5;static DEFAULT_RAILS=2;static BANK_SLOPE=1.5;static ABUTMENT_THICKNESS_M=1;static POST_SIDE_M=.08;static RAIL_HEIGHT_M=.08;static RAIL_DEPTH_M=.06;static BANK_STATIONS=12;static NATURAL_SIZE=Object.freeze({widthM:9,lengthM:40,heightM:6.5});span;bank;deck;railHeight;postSpacing;rails;roadAt(t){const e=Math.abs(t)-this.span/2;return e<=0?this.size.heightM:this.bank<=0?0:Math.max(0,this.size.heightM*(1-e/this.bank))}build(){const{widthM:t,heightM:e}=this.size,i=this.span/2,n=[];if(this.span>0){n.push(Fe.box(t,this.deck,this.span,0,e-this.deck/2,0));for(const c of[-1,1]){const l=e-this.deck;l>0&&this.bank>0&&n.push(Fe.box(t+1,l,Fe.ABUTMENT_THICKNESS_M,0,l/2,c*(i-Fe.ABUTMENT_THICKNESS_M/2)))}}const s=[];this.span>0&&s.push(Fe.box(t,.04,this.span,0,e+.02,0));const a=[];for(const c of[-1,1])this.bank<=0||(a.push(this.embankment(c)),s.push(this.bankRoad(c)));const o=[];for(const c of[-1,1])o.push(...this.railing(c*(t/2-Fe.POST_SIDE_M)));return{concrete:Fe.merge(n),road:Fe.merge(s),earth:Fe.merge(a),railing:Fe.merge(o)}}embankment(t){const e=this.size.widthM/2,i=this.stations(t),n=[],s=(l,h,u,d)=>{n.push(l.x,l.y,l.z,h.x,h.y,h.z,u.x,u.y,u.z,l.x,l.y,l.z,u.x,u.y,u.z,d.x,d.y,d.z)},a=l=>{const h=this.roadAt(l),u=e+Fe.BANK_SLOPE*h;return{leftFoot:new R(-u,0,l),leftTop:new R(-e,h,l),rightTop:new R(e,h,l),rightFoot:new R(u,0,l)}};for(let l=1;l<i.length;l++){const h=a(i[l-1]),u=a(i[l]),d=t>0,f=(p,v,m,g)=>d?s(p,v,m,g):s(g,m,v,p);f(h.leftFoot,h.leftTop,u.leftTop,u.leftFoot),f(h.leftTop,h.rightTop,u.rightTop,u.leftTop),f(h.rightTop,h.rightFoot,u.rightFoot,u.rightTop)}const o=a(i[0]);t>0?s(o.leftFoot,o.rightFoot,o.rightTop,o.leftTop):s(o.leftTop,o.rightTop,o.rightFoot,o.leftFoot);const c=new ne;return c.setAttribute("position",new he(n,3)),c.computeVertexNormals(),c}bankRoad(t){const e=this.size.widthM/2,i=this.stations(t),n=[];for(let a=1;a<i.length;a++){const o=i[a-1],c=i[a],l=this.roadAt(o)+.02,h=this.roadAt(c)+.02,u=t>0?[[-e,l,o],[e,l,o],[e,h,c],[-e,h,c]]:[[-e,h,c],[e,h,c],[e,l,o],[-e,l,o]];for(const d of[0,2,1,0,3,2])n.push(...u[d])}const s=new ne;return s.setAttribute("position",new he(n,3)),s.computeVertexNormals(),s}stations(t){const e=[];for(let i=0;i<=Fe.BANK_STATIONS;i++)e.push(t*(this.span/2+this.bank*i/Fe.BANK_STATIONS));return e}railing(t){const e=this.size.lengthM/2,i=Math.max(1,Math.round(this.size.lengthM/this.postSpacing)),n=[];for(let o=0;o<=i;o++)n.push(-e+this.size.lengthM*o/i);const s=[],a=Fe.POST_SIDE_M;for(const o of n)s.push(Fe.box(a,this.railHeight,a,t,this.roadAt(o)+this.railHeight/2,o));for(let o=1;o<=this.rails;o++){const c=this.railHeight*o/this.rails-Fe.RAIL_HEIGHT_M/2;for(let l=1;l<n.length;l++){const h=new R(t,this.roadAt(n[l-1])+c,n[l-1]),u=new R(t,this.roadAt(n[l])+c,n[l]);s.push(Fe.beam(h,u))}}return s}static box(t,e,i,n,s,a){return new $i(t,e,i).translate(n,s,a)}static beam(t,e){const i=new R().subVectors(e,t),n=new $i(Fe.RAIL_DEPTH_M,Fe.RAIL_HEIGHT_M,i.length()),s=new rn().setFromUnitVectors(new R(0,0,1),i.clone().normalize()),a=new R().addVectors(t,e).multiplyScalar(.5);return n.applyMatrix4(new Qt().compose(a,s,new R(1,1,1)))}static merge(t){const e=t.map(c=>c.getIndex()?c.toNonIndexed():c),i=e.reduce((c,l)=>c+l.getAttribute("position").count,0),n=new Float32Array(i*3),s=new Float32Array(i*3);let a=0;for(const c of e){const l=c.getAttribute("position"),h=c.getAttribute("normal");n.set(l.array,a*3),h&&s.set(h.array,a*3),a+=l.count}const o=new ne;o.setAttribute("position",new he(n,3)),o.setAttribute("normal",new he(s,3));for(const c of t)c.dispose();for(const c of e)c.dispose();return o}}const lu=Math.PI/180;function ze(r,t,e,i,n=!1){const s=n?new yn({color:new st(...e)}):new Wa({color:new st(...e)}),a=new Tt(t,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const hu=.25,A5=.002,T5=100,R5=1500,D5=.25,I5=1e3,C5=.15;function P5(r){const t=/^#([0-9a-f]{6})$/i.exec(r);if(!t)return[1,1,1];const e=parseInt(t[1],16);return[(e>>16&255)/255,(e>>8&255)/255,(e&255)/255]}const L5=[.32,.32,.3],K1=[1,.85,.5],O5=[.25,.25,.25],Z1=[1,.97,.85],N5=[.55,.68,.72],rs=.03,os=.05,J1={front:0,behind:Math.PI,left:Math.PI/2,right:-Math.PI/2,"front-left":Math.PI/2,"behind-left":Math.PI/2,"front-right":-Math.PI/2,"behind-right":-Math.PI/2};function Vi(r,t){return r?.[t]}function cs(r,t,e,i,n,s,a,o){if(o===void 0)return;const c=new Wa({color:new st(...N5),transparent:!0,opacity:o/100}),l=new Tt(new $i(t,e,i),c);l.position.set(n,s,a),r.add(l)}const An=.05,uu=[.6,.58,.53],Sm=[.5,.5,.48];function Dr(r,t,e,i,n,s,a,o){const c=new Wa({color:new st(...o),side:Ye}),l=new Tt(new $i(t,e,i),c);l.position.set(n,s,a),r.add(l)}function F5(r,t,e,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(t?Dr(r,p,v,An,m,o+g,a,c):Dr(r,An,v,p,a,o+g,m,c))};h(e,l,0,i/2-l/2),h(e,l,0,-(i/2-l/2));const u=[...n].sort((p,v)=>p.center-v.center);let d=-e/2;for(const p of u){const m=p.center-p.main/2-d;h(m,s,d+m/2,0),d=p.center+p.main/2}const f=e/2-d;h(f,s,d+f/2,0)}function j1(r,t,e,i,n,s,a,o,c,l){const h=(i+n)/2,u=n-i,d=(f,p,v,m)=>{f.length===0?p?Dr(r,v,u,An,0,h,m,uu):Dr(r,An,u,v,m,h,0,uu):F5(r,p,v,u,f,s,m,h,uu)};d(a,!0,t*2,-e+An),d(o,!0,t*2,e-An),d(c,!1,e*2,-t+An),d(l,!1,e*2,t-An),Dr(r,t*2,An,e*2,0,i+An,0,Sm),Dr(r,t*2,An,e*2,0,n-An,0,Sm)}function a0(r,t,e,i){switch(r){case"front":return{x:0,z:-(e-i)};case"behind":return{x:0,z:e-i};case"left":return{x:-(t-i),z:0};case"right":return{x:t-i,z:0};case"front-left":return{x:-(t-i),z:-ls};case"front-right":return{x:t-i,z:-ls};case"behind-left":return{x:-(t-i),z:ls};case"behind-right":return{x:t-i,z:ls}}}function Q1(r,t,e,i,n,s,a){const o=c0();o.scale.setScalar(i),o.rotation.y=J1[t];const{x:c,z:l}=a0(t,n,s,a);o.position.set(c,e,l),r.add(o)}const r0=6,o0=6,ia=3,_o=1.4,So=ia*.5,tv=1.2,ev=.35,U5=.75,k5=1.6;function bm(r,t,e,i){const n=new Ce,s=Math.max(1,r+1),a=s*ia;ze(n,new $i(r0,a,o0),[.55,.54,.5],a/2);const o=r0/2,c=o0/2;for(let l=0;l<s;l++){const h=l*ia+ia/2;cs(n,_o,So,os,0,h,-c-rs,Vi(t,"front")),cs(n,_o,So,os,0,h,c+rs,Vi(t,"behind")),cs(n,os,So,_o,-o-rs,h,0,Vi(t,"left")),cs(n,os,So,_o,o+rs,h,0,Vi(t,"right"))}if(e){const l=Math.min(Math.max(i??0,0),s-1);Q1(n,e,l*ia,.72,o,c,tv);const h=u=>Vi(t,u)!==void 0?[{main:_o,center:0}]:[];j1(n,o,c,l*ia,(l+1)*ia,So,h("front"),h("behind"),h("left"),h("right"))}return n}function wm(){const r=new Ce,t=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[e,i,n,s]of t){const a=new ui(n,10,7);a.scale(1,.85,1),a.translate(e,0,i),ze(r,a,[.26,.28,.17],s)}return r}function z5(r){const t=new Ce,e=new Fe(pi.sizeOf(r),r.bridge).build();ze(t,e.concrete,[.6,.6,.58],0);const i=ze(t,e.road,[.2,.2,.21],0),n=ze(t,e.earth,[.3,.36,.22],0);for(const s of[i,n])s.material.side=Yi;return ze(t,e.railing,[.5,.52,.55],0),t}function Em(){const r=new Ce;return ze(r,new vs(.15,.22,2,8),[.32,.22,.14],1),ze(r,new Jr(1.4,3,8),[.16,.32,.14],3.5),r}const Am=.275,B5=.35,H5=.9,G5=34,V5=8,W5=1.4;function Tm(){const r=new Ce,t=new ui(Am,7,3,0,Math.PI*2,0,Math.PI/2);t.scale(1,B5/Am,1);const e=pi.repeatOnGrid(t,G5,H5,V5,W5),i=ze(r,e,[.26,.28,.22],0);return i.castShadow=!0,i.userData.cropBasePositions=e.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=t.getAttribute("position").count,t.dispose(),r}function Rm(){const r=new Ce,t=new ui(1,7,3,0,Math.PI*2,0,Math.PI/2);return ze(r,t,[.38,.36,.32],0),r}function Dm(r){const t=new Ce;return ze(t,new vs(.05,.08,5,8),[.28,.28,.3],2.5),ze(t,new ui(.25,12,8),r?K1:L5,5.1,!0),t}const X5=[.08,.08,.08],Js=.8,Sr=1,es=1.7,du=.6,ya=.4,nl=1.2,yr=.7,ls=.5,Y5=es;function Im(r,t,e){const i=new Ce;ze(i,new $i(1.8,1.4,4.2),[.45,.14,.14],.7),ze(i,new $i(Js*2,du,Sr*2),[.4,.12,.12],es);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=ze(i,new vs(.4,.4,.3,12),X5,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?Z1:O5;for(const s of[-.7,.7])ze(i,new ui(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(cs(i,nl,ya,os,0,es,-Sr-rs,Vi(t,"front")),cs(i,nl,ya,os,0,es,Sr+rs,Vi(t,"behind")),cs(i,os,ya,yr,-Js-rs,es,-ls,Vi(t,"front-left")),cs(i,os,ya,yr,-Js-rs,es,ls,Vi(t,"behind-left")),cs(i,os,ya,yr,Js+rs,es,-ls,Vi(t,"front-right")),cs(i,os,ya,yr,Js+rs,es,ls,Vi(t,"behind-right")),e){Q1(i,e,U5,.5,Js,Sr,ev);const s=(c,l)=>{const h=[];return Vi(t,c)!==void 0&&h.push({main:yr,center:-ls}),Vi(t,l)!==void 0&&h.push({main:yr,center:ls}),h},a=Vi(t,"front")!==void 0?[{main:nl,center:0}]:[],o=Vi(t,"behind")!==void 0?[{main:nl,center:0}]:[];j1(i,Js,Sr,es-du/2,es+du/2,ya,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Cm=new Map;function Pm(r,t){if(!r)return;const e=[[r.lengthM,t.lengthM],[r.heightM,t.heightM],[r.widthM,t.widthM]];for(const[i,n]of e)if(i!==void 0&&n>1e-6)return i/n}function fu(r,t){return t>1e-6?r/t:1}const iv=[.95,.9,.82],Lm=[.72,.74,.78];function Om(){const r=new Ce;ze(r,new vs(.25,.3,1.5,10),Lm,.75),ze(r,new ui(.26,10,8),Lm,1.74);const t=ze(r,new Jr(.07,.16,8),iv,1.74);return t.rotation.x=-Math.PI/2,t.position.z=-.22,r}function c0(){const r=new Ce;ze(r,new vs(.25,.3,1.5,10),[.3,.3,.35],.75),ze(r,new ui(.22,10,8),[.62,.52,.46],1.72);const t=ze(r,new Jr(.07,.16,8),iv,1.72);return t.rotation.x=-Math.PI/2,t.position.z=-.2,r}const q5=17,Nm=18.5,pu=[.16,.16,.18];function Fm(){const r=new Ce,t=ze(r,new vs(1.8,1.8,Nm*2,10),pu,0);t.rotation.x=Math.PI/2,ze(r,new $i(q5*2,.5,4.5),pu,0);const e=ze(r,new $i(.4,5.5,4),pu,3);return e.position.z=-Nm+2,r}class pi{static GROWS_FROM_GROUND=new Set(["tree","shrub","crop","mound"]);static groundUnderFootprint(t,e,i,n,s,a=0){const o=pi.sizeOf(t);if(a>o.heightM)return s(e,i);const c=(n??0)*Math.PI/180,l=Math.min(21,Math.max(2,Math.ceil(o.lengthM/.75)+1)),h=Math.min(21,Math.max(2,Math.ceil(o.widthM/.75)+1)),u=pi.GROWS_FROM_GROUND.has(t.kind);let d=u?1/0:-1/0;for(let f=0;f<l;f++){const p=(f/(l-1)-.5)*o.lengthM;for(let v=0;v<h;v++){const m=(v/(h-1)-.5)*o.widthM,g=e+Math.sin(c)*p+Math.cos(c)*m,_=i-Math.cos(c)*p+Math.sin(c)*m;d=u?Math.min(d,s(g,_)):Math.max(d,s(g,_))}}return Number.isFinite(d)?d:s(e,i)}static occupantView(t){const e=t.observerSide;if(!e)throw new Error("occupantView requires object.observerSide to be set");const{x:i,z:n}=t.kind==="vehicle"?a0(e,Js,Sr,ev):a0(e,r0/2,o0/2,tv),s=t.kind==="vehicle"?Y5:(t.occupiedFloor??0)*ia+k5,a=(t.headingDeg??0)-J1[e]/lu,o=this.scaleFor(t);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(t){return t.getObjectByName(pi.BODY_NAME)??t}static repeatOnGrid(t,e,i,n,s){const a=t.getAttribute("position"),o=t.getAttribute("normal"),c=t.getIndex();if(!c)throw new Error("repeatOnGrid needs an indexed geometry");const l=a.count,h=e*n,u=new Float32Array(l*h*3),d=new Float32Array(l*h*3),f=new Uint32Array(c.count*h),p=-((e-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let _=0;_<n;_++)for(let y=0;y<e;y++,m++){const M=v+_*s,b=p+y*i;for(let w=0;w<l;w++){const T=(m*l+w)*3;u[T]=a.getX(w)+M,u[T+1]=a.getY(w),u[T+2]=a.getZ(w)+b,d[T]=o.getX(w),d[T+1]=o.getY(w),d[T+2]=o.getZ(w)}for(let w=0;w<c.count;w++)f[m*c.count+w]=c.getX(w)+m*l}const g=new ne;return g.setAttribute("position",new he(u,3)),g.setAttribute("normal",new he(d,3)),g.setIndex(new I0(f,1)),g}static fitCropToGround(t,e){t.updateMatrixWorld(!0);const i=new R;t.traverse(n=>{const s=n,a=s.userData.cropBasePositions,o=s.userData.cropVerticesPerClump;if(!s.isMesh||!a||!o)return;const c=s.geometry.getAttribute("position"),l=new Qt().copy(s.matrixWorld).invert();for(let h=0;h<c.count;h+=o){i.set(a[h*3],0,a[h*3+2]).applyMatrix4(s.matrixWorld),i.y=e(i.x,i.z),i.applyMatrix4(l);for(let u=h;u<h+o;u++)c.setY(u,a[u*3+1]+i.y)}c.needsUpdate=!0,s.geometry.computeBoundingBox(),s.geometry.computeBoundingSphere()})}static paint(t,e){t.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(e)})}static build(t,e){const i=t.kind==="building"?bm(t.floors??gf,t.windows,t.observerSide,t.occupiedFloor):t.kind==="tree"?Em():t.kind==="shrub"?wm():t.kind==="bridge"?z5(t):t.kind==="crop"?Tm():t.kind==="mound"?Rm():t.kind==="streetlight"?Dm(e):t.kind==="vehicle"?Im(e,t.windows,t.observerSide):t.kind==="aircraft"?Fm():t.kind==="entity"?Om():c0();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Ce;return i.name=pi.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*lu),this.addLights(s,t.lights),s}static scaleFor(t){const e=t.sizeM;if(!e||t.kind==="bridge")return new R(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new R(e.widthM===void 0?1:fu(e.widthM,i.widthM),e.heightM===void 0?1:fu(e.heightM,i.heightM),e.lengthM===void 0?1:fu(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??gf)+1):0;if(t==="bridge")return Fe.NATURAL_SIZE;const n=`${t}:${i}`,s=Cm.get(n);if(s)return s;const a=t==="building"?bm(i-1,void 0,void 0,void 0):t==="tree"?Em():t==="shrub"?wm():t==="crop"?Tm():t==="mound"?Rm():t==="streetlight"?Dm(!1):t==="vehicle"?Im(!1,void 0,void 0):t==="aircraft"?Fm():t==="entity"?Om():c0(),o=new qi().setFromObject(a),c={widthM:o.max.x-o.min.x,heightM:o.max.y-o.min.y,lengthM:o.max.z-o.min.z};return this.dispose(a),Cm.set(n,c),c}static usesModel(t){return t.model!==void 0&&!(t.observerSide!==void 0&&Mg(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),a=new Ce;a.name=pi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*lu,i.updateMatrixWorld(!0);const o=new qi().setFromObject(i),c={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},l=Pm(e.sizeM,c)??Pm(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new R).multiplyScalar(l);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=e.kind==="aircraft"?h.y:o.min.y*l,i.traverse(u=>{u instanceof Tt&&(u.castShadow=!0,u.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):t.add(a),this.dispose(s)}static sizeOf(t){const e=this.naturalSize(t.kind,t.floors);return{widthM:t.sizeM?.widthM??e.widthM,lengthM:t.sizeM?.lengthM??e.lengthM,heightM:t.sizeM?.heightM??e.heightM}}static addLights(t,e){for(const i of e??[]){const n=P5(i.color),s=ze(t,new ui(hu,8,6),n,i.offsetM.y,!0);s.position.set(i.offsetM.x,i.offsetM.y,i.offsetM.z),s.userData={emissive:!0,lightId:i.id,lightColor:n},s.visible=!1;const a=s.material;a.blending=Ai,a.transparent=!0,a.depthWrite=!1,a.fog=!1}}static setLights(t,e,i,n,s=0,a=1,o=A5,c=[1,1,1]){if(!e||e.length===0)return;const l=new Map(e.map(f=>[f.id,f])),h=Math.max(1,n*o/hu),u=hu*h,d=a/(Math.PI*u*u);for(const f of t.children){if(!(f instanceof Tt))continue;const p=f.userData.lightId;if(!p)continue;const v=l.get(p);if(!v)continue;const m=s>0?xg(v,i,i+s):yv(v,i)?1:0;f.visible=m>0;const g=f.material,_=f.userData.lightColor;if(_){const y=m*T5*(v.intensity??1)*d;g.color.setRGB(_[0]*y*c[0],_[1]*y*c[1],_[2]*y*c[2])}f.scale.setScalar(h)}}static setLit(t,e,i,n=1){const[s,a,o]=e==="streetlight"?[R5,D5,K1]:[I5,C5,Z1],c=i?s*n/(Math.PI*a*a):0,l=[o[0]*c,o[1]*c,o[2]*c];t.traverse(h=>{const u=h.userData;!(h instanceof Tt)||!u.emissive||u.lightId||h.material.color.setRGB(...l)})}static dispose(t){t.traverse(e=>{if(!(e instanceof Tt))return;e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const mu="https://ufoathome.org/models/index.json";class $5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??K5()}async entries(t){const e=await this.load();return t?e.filter(i=>i.kind===t):e}async entry(t){return(await this.load()).find(e=>e.id===t)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function K5(){const r=`?v=${encodeURIComponent("0.86.1")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==mu?[t,mu]:[mu]).map(e=>e+r)}const Z5=[{id:"ufoathome",name:"UFO@home",credit:"3D models re-hosted by UFO@home, each under its own author's licence",creditUrl:"https://ufoathome.org/models/",create:()=>new $5}];async function Um(r){const{GLTFLoader:t}=await an(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-DYi1DaRQ.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(r,s=>i(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const nv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class mn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(t,e){this.mesh=new Tt(new Ki(2,2),new ue({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:mn.VERTEX,fragmentShader:mn.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ai,toneMapped:!1})),this.mesh.name=t,this.mesh.frustumCulled=!1,this.mesh.renderOrder=e,this.mesh.visible=!1}shine(t,e,i){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.material.uniforms.uRadius.value=e,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(t,e,i,n){const s=Math.max(t,n*mn.MIN_ANGLE_RAD),a=mn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(mn.MAX_SHARE,e/a)}}static conserving(t){return Math.sqrt(t/(mn.MAX_SHARE*mn.FILL*Math.PI))}static VERTEX=`
7216
+ `,transparent:!0,blending:Ai,depthWrite:!1,side:Ye,fog:!1}),this.object=new Tt(new ui(Oi.RADIUS,64,32),this.material),this.object.renderOrder=-1,this.object.frustumCulled=!1,this.object.visible=!1;const i=this.material.uniforms;this.deckUniforms={uSource:i.uSource,uUp:i.uUp,uStrength:i.uStrength,uTint:i.uTint,uMap:i.uMap,uGain:i.uGain,uHaloShown:{value:0}}}deckUniforms;shown=!1;hostedByDeck=!1;set hosted(t){this.hostedByDeck=t,this.show(this.shown)}show(t){this.shown=t,this.object.visible=t&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=t?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(t){this.urgent=t}set onReady(t){this.onRepaint=t}update(t,e,i,n,s,a){const o=this.material.uniforms;if(i<=0){o.uStrength.value=0,this.show(!1),this.stopWork();return}o.uSource.value.set(t.x,t.y,t.z).normalize(),o.uStrength.value=i,o.uTint.value.set(n[0],n[1],n[2]),o.uIceCover.value=s.cover,o.uIceHeight.value=s.layerHeight,this.show(this.everDisplayed),this.requestMap(e,a)}requestMap(t,e){if(!(!(Math.abs(t-this.mappedAltitudeDeg)<Oi.ALTITUDE_STEP_DEG)||!(Math.abs(e-this.mappedAlignment)<Oi.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(t,e)){this.next=void 0;return}if(!(!(Math.abs(t-this.pendingAltitudeDeg)<Oi.LEAP_ALTITUDE_DEG)||!(Math.abs(e-this.pendingAlignment)<Oi.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:t,alignment:e};return}}this.next=void 0,this.pendingAltitudeDeg=t,this.pendingAlignment=e,this.sky.begin(t,e),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(t,e){return this.tracing&&Math.abs(t-this.pendingAltitudeDeg)<Oi.ALTITUDE_STEP_DEG&&Math.abs(e-this.pendingAlignment)<Oi.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const t=()=>{if(this.workHandle=void 0,!this.tracing)return;const e=performance.now(),i=this.urgent?Oi.URGENT_BUDGET_MS:Oi.BUDGET_MS;do this.sky.trace(Oi.RAYS_PER_BATCH);while(this.sky.tracedRays<Oi.RAYS&&performance.now()-e<i);if(this.sky.tracedRays>=Oi.RAYS){this.publish(),this.tracing=!1,this.mappedAltitudeDeg=this.pendingAltitudeDeg,this.mappedAlignment=this.pendingAlignment;const s=this.next;s&&this.requestMap(s.sourceAltitudeDeg,s.alignment);return}this.workHandle=requestAnimationFrame(t)};this.workHandle=requestAnimationFrame(t)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const e=this.sky.harvest().data;for(let i=0,n=0;n<e.length;i+=4,n+=3)this.texels[i]=Xn.toHalfFloat(e[n]),this.texels[i+1]=Xn.toHalfFloat(e[n+1]),this.texels[i+2]=Xn.toHalfFloat(e[n+2]),this.texels[i+3]=1;this.texture.needsUpdate=!0,this.everDisplayed=!0,this.show(this.material.uniforms.uStrength.value>0),this.onRepaint?.()}dispose(){this.stopWork(),this.texture.dispose(),this.object.geometry.dispose(),this.material.dispose()}}class Si{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=Si.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(Si.ACROSS-1)*6;static RADIUS=840;static MIN_HALF_WIDTH_DEG=.05;static BRIGHT_HALF_WIDTH_DEG=.22;object;positions;colors;meteors=[];radiantAltitudeDeg=0;radiantAzimuthDeg=0;constructor(){const t=Si.MAX_CONCURRENT*Si.SEGMENTS*Si.VERTICES_PER_SEGMENT;this.positions=new Float32Array(t*3),this.colors=new Float32Array(t*3);const e=new ne;e.setAttribute("position",new Zt(this.positions,3)),e.setAttribute("color",new Zt(this.colors,3)),e.setDrawRange(0,0),this.object=new Tt(e,new yn({vertexColors:!0,transparent:!0,blending:Ai,depthWrite:!1,fog:!1,side:Yi})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(t,e,i){this.meteors=t,this.radiantAltitudeDeg=e,this.radiantAzimuthDeg=i}update(t){const e=this.object.geometry;if(this.meteors.length===0){e.setDrawRange(0,0);return}const i=za.aliveAt(this.meteors,t).slice(0,Si.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=Ke(o.altitudeDeg,o.azimuthDeg,1),[l,h]=this.basisAround(c),u=s.fromRadiantDeg+a*s.lengthDeg,d=Math.max(s.fromRadiantDeg,u-s.lengthDeg*.6),f=Math.min(1,(1-a)*2.5),p=this.turn(l,h,s.bearingDeg),v=(.15+.85*s.brightness)*f,m=y=>v*y**1.6,g=y=>this.onSphere(c,p,d+(u-d)*y),_=y=>Si.RADIUS*((Si.MIN_HALF_WIDTH_DEG+Si.BRIGHT_HALF_WIDTH_DEG*s.brightness*y)*Math.PI/180);for(let y=1;y<Si.POINTS;y++){const M=(y-1)/Si.SEGMENTS,b=y/Si.SEGMENTS;n=this.pushRibbon(n,g(M),g(b),_(M),_(b),m(M),m(b))}}e.setDrawRange(0,n),e.getAttribute("position").needsUpdate=!0,e.getAttribute("color").needsUpdate=!0}midpointOf(t){const e=this.radiantOf(t);if(!e)return;const i=Ke(e.altitudeDeg,e.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,t.bearingDeg),o=this.onSphere(i,a,t.fromRadiantDeg+t.lengthDeg/2),c=Math.hypot(o.x,o.y,o.z)||1;return{altitudeDeg:Math.asin(o.y/c)*180/Math.PI,azimuthDeg:(Math.atan2(o.x,-o.z)*180/Math.PI+360)%360}}radiantOf(t){return t.radiant?t.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(t,e,i,n,s,a,o){const c=this.normalise(this.cross(this.normalise(e),this.normalise(this.subtract(i,e))));for(let l=0;l<Si.ACROSS-1;l++){const h=l-1,u=l,d=this.across(e,c,n,h),f=this.across(i,c,s,h),p=this.across(e,c,n,u),v=this.across(i,c,s,u),m=(g,_)=>g===0?_:0;t=this.push(t,d,m(h,a)),t=this.push(t,f,m(h,o)),t=this.push(t,p,m(u,a)),t=this.push(t,f,m(h,o)),t=this.push(t,v,m(u,o)),t=this.push(t,p,m(u,a))}return t}across(t,e,i,n){return{x:t.x+e.x*i*n,y:t.y+e.y*i*n,z:t.z+e.z*i*n}}push(t,e,i){const n=t*3;this.positions[n]=e.x,this.positions[n+1]=e.y,this.positions[n+2]=e.z;const s=wt.relativeOfResponse(Math.max(0,Math.min(1,i)));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,t+1}turn(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:t.x*s+e.x*a,y:t.y*s+e.y*a,z:t.z*s+e.z*a}}onSphere(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(t.x*s+e.x*a)*Si.RADIUS,y:(t.y*s+e.y*a)*Si.RADIUS,z:(t.z*s+e.z*a)*Si.RADIUS}}basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(t,e));return[i,this.normalise(this.cross(t,i))]}subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}class Fe{constructor(t,e={}){this.size=t,this.span=Math.min(t.lengthM,Math.max(0,e.spanM??t.lengthM)),this.bank=(t.lengthM-this.span)/2,this.deck=Math.min(t.heightM,e.deckThicknessM??Fe.DEFAULT_DECK_THICKNESS_M),this.railHeight=e.railing?.heightM??Fe.DEFAULT_RAILING_HEIGHT_M,this.postSpacing=Math.max(.3,e.railing?.postSpacingM??Fe.DEFAULT_POST_SPACING_M),this.rails=Math.max(0,Math.round(e.railing?.rails??Fe.DEFAULT_RAILS))}static DEFAULT_DECK_THICKNESS_M=1.2;static DEFAULT_RAILING_HEIGHT_M=1.05;static DEFAULT_POST_SPACING_M=1.5;static DEFAULT_RAILS=2;static BANK_SLOPE=1.5;static ABUTMENT_THICKNESS_M=1;static POST_SIDE_M=.08;static RAIL_HEIGHT_M=.08;static RAIL_DEPTH_M=.06;static BANK_STATIONS=12;static NATURAL_SIZE=Object.freeze({widthM:9,lengthM:40,heightM:6.5});span;bank;deck;railHeight;postSpacing;rails;roadAt(t){const e=Math.abs(t)-this.span/2;return e<=0?this.size.heightM:this.bank<=0?0:Math.max(0,this.size.heightM*(1-e/this.bank))}build(){const{widthM:t,heightM:e}=this.size,i=this.span/2,n=[];if(this.span>0){n.push(Fe.box(t,this.deck,this.span,0,e-this.deck/2,0));for(const c of[-1,1]){const l=e-this.deck;l>0&&this.bank>0&&n.push(Fe.box(t+1,l,Fe.ABUTMENT_THICKNESS_M,0,l/2,c*(i-Fe.ABUTMENT_THICKNESS_M/2)))}}const s=[];this.span>0&&s.push(Fe.box(t,.04,this.span,0,e+.02,0));const a=[];for(const c of[-1,1])this.bank<=0||(a.push(this.embankment(c)),s.push(this.bankRoad(c)));const o=[];for(const c of[-1,1])o.push(...this.railing(c*(t/2-Fe.POST_SIDE_M)));return{concrete:Fe.merge(n),road:Fe.merge(s),earth:Fe.merge(a),railing:Fe.merge(o)}}embankment(t){const e=this.size.widthM/2,i=this.stations(t),n=[],s=(l,h,u,d)=>{n.push(l.x,l.y,l.z,h.x,h.y,h.z,u.x,u.y,u.z,l.x,l.y,l.z,u.x,u.y,u.z,d.x,d.y,d.z)},a=l=>{const h=this.roadAt(l),u=e+Fe.BANK_SLOPE*h;return{leftFoot:new R(-u,0,l),leftTop:new R(-e,h,l),rightTop:new R(e,h,l),rightFoot:new R(u,0,l)}};for(let l=1;l<i.length;l++){const h=a(i[l-1]),u=a(i[l]),d=t>0,f=(p,v,m,g)=>d?s(p,v,m,g):s(g,m,v,p);f(h.leftFoot,h.leftTop,u.leftTop,u.leftFoot),f(h.leftTop,h.rightTop,u.rightTop,u.leftTop),f(h.rightTop,h.rightFoot,u.rightFoot,u.rightTop)}const o=a(i[0]);t>0?s(o.leftFoot,o.rightFoot,o.rightTop,o.leftTop):s(o.leftTop,o.rightTop,o.rightFoot,o.leftFoot);const c=new ne;return c.setAttribute("position",new he(n,3)),c.computeVertexNormals(),c}bankRoad(t){const e=this.size.widthM/2,i=this.stations(t),n=[];for(let a=1;a<i.length;a++){const o=i[a-1],c=i[a],l=this.roadAt(o)+.02,h=this.roadAt(c)+.02,u=t>0?[[-e,l,o],[e,l,o],[e,h,c],[-e,h,c]]:[[-e,h,c],[e,h,c],[e,l,o],[-e,l,o]];for(const d of[0,2,1,0,3,2])n.push(...u[d])}const s=new ne;return s.setAttribute("position",new he(n,3)),s.computeVertexNormals(),s}stations(t){const e=[];for(let i=0;i<=Fe.BANK_STATIONS;i++)e.push(t*(this.span/2+this.bank*i/Fe.BANK_STATIONS));return e}railing(t){const e=this.size.lengthM/2,i=Math.max(1,Math.round(this.size.lengthM/this.postSpacing)),n=[];for(let o=0;o<=i;o++)n.push(-e+this.size.lengthM*o/i);const s=[],a=Fe.POST_SIDE_M;for(const o of n)s.push(Fe.box(a,this.railHeight,a,t,this.roadAt(o)+this.railHeight/2,o));for(let o=1;o<=this.rails;o++){const c=this.railHeight*o/this.rails-Fe.RAIL_HEIGHT_M/2;for(let l=1;l<n.length;l++){const h=new R(t,this.roadAt(n[l-1])+c,n[l-1]),u=new R(t,this.roadAt(n[l])+c,n[l]);s.push(Fe.beam(h,u))}}return s}static box(t,e,i,n,s,a){return new $i(t,e,i).translate(n,s,a)}static beam(t,e){const i=new R().subVectors(e,t),n=new $i(Fe.RAIL_DEPTH_M,Fe.RAIL_HEIGHT_M,i.length()),s=new rn().setFromUnitVectors(new R(0,0,1),i.clone().normalize()),a=new R().addVectors(t,e).multiplyScalar(.5);return n.applyMatrix4(new Qt().compose(a,s,new R(1,1,1)))}static merge(t){const e=t.map(c=>c.getIndex()?c.toNonIndexed():c),i=e.reduce((c,l)=>c+l.getAttribute("position").count,0),n=new Float32Array(i*3),s=new Float32Array(i*3);let a=0;for(const c of e){const l=c.getAttribute("position"),h=c.getAttribute("normal");n.set(l.array,a*3),h&&s.set(h.array,a*3),a+=l.count}const o=new ne;o.setAttribute("position",new he(n,3)),o.setAttribute("normal",new he(s,3));for(const c of t)c.dispose();for(const c of e)c.dispose();return o}}const lu=Math.PI/180;function ze(r,t,e,i,n=!1){const s=n?new yn({color:new st(...e)}):new Wa({color:new st(...e)}),a=new Tt(t,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const hu=.25,A5=.002,T5=100,R5=1500,D5=.25,I5=1e3,C5=.15;function P5(r){const t=/^#([0-9a-f]{6})$/i.exec(r);if(!t)return[1,1,1];const e=parseInt(t[1],16);return[(e>>16&255)/255,(e>>8&255)/255,(e&255)/255]}const L5=[.32,.32,.3],K1=[1,.85,.5],O5=[.25,.25,.25],Z1=[1,.97,.85],N5=[.55,.68,.72],rs=.03,os=.05,J1={front:0,behind:Math.PI,left:Math.PI/2,right:-Math.PI/2,"front-left":Math.PI/2,"behind-left":Math.PI/2,"front-right":-Math.PI/2,"behind-right":-Math.PI/2};function Vi(r,t){return r?.[t]}function cs(r,t,e,i,n,s,a,o){if(o===void 0)return;const c=new Wa({color:new st(...N5),transparent:!0,opacity:o/100}),l=new Tt(new $i(t,e,i),c);l.position.set(n,s,a),r.add(l)}const An=.05,uu=[.6,.58,.53],Sm=[.5,.5,.48];function Dr(r,t,e,i,n,s,a,o){const c=new Wa({color:new st(...o),side:Ye}),l=new Tt(new $i(t,e,i),c);l.position.set(n,s,a),r.add(l)}function F5(r,t,e,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(t?Dr(r,p,v,An,m,o+g,a,c):Dr(r,An,v,p,a,o+g,m,c))};h(e,l,0,i/2-l/2),h(e,l,0,-(i/2-l/2));const u=[...n].sort((p,v)=>p.center-v.center);let d=-e/2;for(const p of u){const m=p.center-p.main/2-d;h(m,s,d+m/2,0),d=p.center+p.main/2}const f=e/2-d;h(f,s,d+f/2,0)}function j1(r,t,e,i,n,s,a,o,c,l){const h=(i+n)/2,u=n-i,d=(f,p,v,m)=>{f.length===0?p?Dr(r,v,u,An,0,h,m,uu):Dr(r,An,u,v,m,h,0,uu):F5(r,p,v,u,f,s,m,h,uu)};d(a,!0,t*2,-e+An),d(o,!0,t*2,e-An),d(c,!1,e*2,-t+An),d(l,!1,e*2,t-An),Dr(r,t*2,An,e*2,0,i+An,0,Sm),Dr(r,t*2,An,e*2,0,n-An,0,Sm)}function a0(r,t,e,i){switch(r){case"front":return{x:0,z:-(e-i)};case"behind":return{x:0,z:e-i};case"left":return{x:-(t-i),z:0};case"right":return{x:t-i,z:0};case"front-left":return{x:-(t-i),z:-ls};case"front-right":return{x:t-i,z:-ls};case"behind-left":return{x:-(t-i),z:ls};case"behind-right":return{x:t-i,z:ls}}}function Q1(r,t,e,i,n,s,a){const o=c0();o.scale.setScalar(i),o.rotation.y=J1[t];const{x:c,z:l}=a0(t,n,s,a);o.position.set(c,e,l),r.add(o)}const r0=6,o0=6,ia=3,_o=1.4,So=ia*.5,tv=1.2,ev=.35,U5=.75,k5=1.6;function bm(r,t,e,i){const n=new Ce,s=Math.max(1,r+1),a=s*ia;ze(n,new $i(r0,a,o0),[.55,.54,.5],a/2);const o=r0/2,c=o0/2;for(let l=0;l<s;l++){const h=l*ia+ia/2;cs(n,_o,So,os,0,h,-c-rs,Vi(t,"front")),cs(n,_o,So,os,0,h,c+rs,Vi(t,"behind")),cs(n,os,So,_o,-o-rs,h,0,Vi(t,"left")),cs(n,os,So,_o,o+rs,h,0,Vi(t,"right"))}if(e){const l=Math.min(Math.max(i??0,0),s-1);Q1(n,e,l*ia,.72,o,c,tv);const h=u=>Vi(t,u)!==void 0?[{main:_o,center:0}]:[];j1(n,o,c,l*ia,(l+1)*ia,So,h("front"),h("behind"),h("left"),h("right"))}return n}function wm(){const r=new Ce,t=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[e,i,n,s]of t){const a=new ui(n,10,7);a.scale(1,.85,1),a.translate(e,0,i),ze(r,a,[.26,.28,.17],s)}return r}function z5(r){const t=new Ce,e=new Fe(pi.sizeOf(r),r.bridge).build();ze(t,e.concrete,[.6,.6,.58],0);const i=ze(t,e.road,[.2,.2,.21],0),n=ze(t,e.earth,[.3,.36,.22],0);for(const s of[i,n])s.material.side=Yi;return ze(t,e.railing,[.5,.52,.55],0),t}function Em(){const r=new Ce;return ze(r,new vs(.15,.22,2,8),[.32,.22,.14],1),ze(r,new Jr(1.4,3,8),[.16,.32,.14],3.5),r}const Am=.275,B5=.35,H5=.9,G5=34,V5=8,W5=1.4;function Tm(){const r=new Ce,t=new ui(Am,7,3,0,Math.PI*2,0,Math.PI/2);t.scale(1,B5/Am,1);const e=pi.repeatOnGrid(t,G5,H5,V5,W5),i=ze(r,e,[.26,.28,.22],0);return i.castShadow=!0,i.userData.cropBasePositions=e.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=t.getAttribute("position").count,t.dispose(),r}function Rm(){const r=new Ce,t=new ui(1,7,3,0,Math.PI*2,0,Math.PI/2);return ze(r,t,[.38,.36,.32],0),r}function Dm(r){const t=new Ce;return ze(t,new vs(.05,.08,5,8),[.28,.28,.3],2.5),ze(t,new ui(.25,12,8),r?K1:L5,5.1,!0),t}const X5=[.08,.08,.08],Js=.8,Sr=1,es=1.7,du=.6,ya=.4,nl=1.2,yr=.7,ls=.5,Y5=es;function Im(r,t,e){const i=new Ce;ze(i,new $i(1.8,1.4,4.2),[.45,.14,.14],.7),ze(i,new $i(Js*2,du,Sr*2),[.4,.12,.12],es);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=ze(i,new vs(.4,.4,.3,12),X5,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?Z1:O5;for(const s of[-.7,.7])ze(i,new ui(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(cs(i,nl,ya,os,0,es,-Sr-rs,Vi(t,"front")),cs(i,nl,ya,os,0,es,Sr+rs,Vi(t,"behind")),cs(i,os,ya,yr,-Js-rs,es,-ls,Vi(t,"front-left")),cs(i,os,ya,yr,-Js-rs,es,ls,Vi(t,"behind-left")),cs(i,os,ya,yr,Js+rs,es,-ls,Vi(t,"front-right")),cs(i,os,ya,yr,Js+rs,es,ls,Vi(t,"behind-right")),e){Q1(i,e,U5,.5,Js,Sr,ev);const s=(c,l)=>{const h=[];return Vi(t,c)!==void 0&&h.push({main:yr,center:-ls}),Vi(t,l)!==void 0&&h.push({main:yr,center:ls}),h},a=Vi(t,"front")!==void 0?[{main:nl,center:0}]:[],o=Vi(t,"behind")!==void 0?[{main:nl,center:0}]:[];j1(i,Js,Sr,es-du/2,es+du/2,ya,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Cm=new Map;function Pm(r,t){if(!r)return;const e=[[r.lengthM,t.lengthM],[r.heightM,t.heightM],[r.widthM,t.widthM]];for(const[i,n]of e)if(i!==void 0&&n>1e-6)return i/n}function fu(r,t){return t>1e-6?r/t:1}const iv=[.95,.9,.82],Lm=[.72,.74,.78];function Om(){const r=new Ce;ze(r,new vs(.25,.3,1.5,10),Lm,.75),ze(r,new ui(.26,10,8),Lm,1.74);const t=ze(r,new Jr(.07,.16,8),iv,1.74);return t.rotation.x=-Math.PI/2,t.position.z=-.22,r}function c0(){const r=new Ce;ze(r,new vs(.25,.3,1.5,10),[.3,.3,.35],.75),ze(r,new ui(.22,10,8),[.62,.52,.46],1.72);const t=ze(r,new Jr(.07,.16,8),iv,1.72);return t.rotation.x=-Math.PI/2,t.position.z=-.2,r}const q5=17,Nm=18.5,pu=[.16,.16,.18];function Fm(){const r=new Ce,t=ze(r,new vs(1.8,1.8,Nm*2,10),pu,0);t.rotation.x=Math.PI/2,ze(r,new $i(q5*2,.5,4.5),pu,0);const e=ze(r,new $i(.4,5.5,4),pu,3);return e.position.z=-Nm+2,r}class pi{static GROWS_FROM_GROUND=new Set(["tree","shrub","crop","mound"]);static groundUnderFootprint(t,e,i,n,s,a=0){const o=pi.sizeOf(t);if(a>o.heightM)return s(e,i);const c=(n??0)*Math.PI/180,l=Math.min(21,Math.max(2,Math.ceil(o.lengthM/.75)+1)),h=Math.min(21,Math.max(2,Math.ceil(o.widthM/.75)+1)),u=pi.GROWS_FROM_GROUND.has(t.kind);let d=u?1/0:-1/0;for(let f=0;f<l;f++){const p=(f/(l-1)-.5)*o.lengthM;for(let v=0;v<h;v++){const m=(v/(h-1)-.5)*o.widthM,g=e+Math.sin(c)*p+Math.cos(c)*m,_=i-Math.cos(c)*p+Math.sin(c)*m;d=u?Math.min(d,s(g,_)):Math.max(d,s(g,_))}}return Number.isFinite(d)?d:s(e,i)}static occupantView(t){const e=t.observerSide;if(!e)throw new Error("occupantView requires object.observerSide to be set");const{x:i,z:n}=t.kind==="vehicle"?a0(e,Js,Sr,ev):a0(e,r0/2,o0/2,tv),s=t.kind==="vehicle"?Y5:(t.occupiedFloor??0)*ia+k5,a=(t.headingDeg??0)-J1[e]/lu,o=this.scaleFor(t);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(t){return t.getObjectByName(pi.BODY_NAME)??t}static repeatOnGrid(t,e,i,n,s){const a=t.getAttribute("position"),o=t.getAttribute("normal"),c=t.getIndex();if(!c)throw new Error("repeatOnGrid needs an indexed geometry");const l=a.count,h=e*n,u=new Float32Array(l*h*3),d=new Float32Array(l*h*3),f=new Uint32Array(c.count*h),p=-((e-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let _=0;_<n;_++)for(let y=0;y<e;y++,m++){const M=v+_*s,b=p+y*i;for(let w=0;w<l;w++){const T=(m*l+w)*3;u[T]=a.getX(w)+M,u[T+1]=a.getY(w),u[T+2]=a.getZ(w)+b,d[T]=o.getX(w),d[T+1]=o.getY(w),d[T+2]=o.getZ(w)}for(let w=0;w<c.count;w++)f[m*c.count+w]=c.getX(w)+m*l}const g=new ne;return g.setAttribute("position",new he(u,3)),g.setAttribute("normal",new he(d,3)),g.setIndex(new I0(f,1)),g}static fitCropToGround(t,e){t.updateMatrixWorld(!0);const i=new R;t.traverse(n=>{const s=n,a=s.userData.cropBasePositions,o=s.userData.cropVerticesPerClump;if(!s.isMesh||!a||!o)return;const c=s.geometry.getAttribute("position"),l=new Qt().copy(s.matrixWorld).invert();for(let h=0;h<c.count;h+=o){i.set(a[h*3],0,a[h*3+2]).applyMatrix4(s.matrixWorld),i.y=e(i.x,i.z),i.applyMatrix4(l);for(let u=h;u<h+o;u++)c.setY(u,a[u*3+1]+i.y)}c.needsUpdate=!0,s.geometry.computeBoundingBox(),s.geometry.computeBoundingSphere()})}static paint(t,e){t.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(e)})}static build(t,e){const i=t.kind==="building"?bm(t.floors??gf,t.windows,t.observerSide,t.occupiedFloor):t.kind==="tree"?Em():t.kind==="shrub"?wm():t.kind==="bridge"?z5(t):t.kind==="crop"?Tm():t.kind==="mound"?Rm():t.kind==="streetlight"?Dm(e):t.kind==="vehicle"?Im(e,t.windows,t.observerSide):t.kind==="aircraft"?Fm():t.kind==="entity"?Om():c0();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Ce;return i.name=pi.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*lu),this.addLights(s,t.lights),s}static scaleFor(t){const e=t.sizeM;if(!e||t.kind==="bridge")return new R(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new R(e.widthM===void 0?1:fu(e.widthM,i.widthM),e.heightM===void 0?1:fu(e.heightM,i.heightM),e.lengthM===void 0?1:fu(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??gf)+1):0;if(t==="bridge")return Fe.NATURAL_SIZE;const n=`${t}:${i}`,s=Cm.get(n);if(s)return s;const a=t==="building"?bm(i-1,void 0,void 0,void 0):t==="tree"?Em():t==="shrub"?wm():t==="crop"?Tm():t==="mound"?Rm():t==="streetlight"?Dm(!1):t==="vehicle"?Im(!1,void 0,void 0):t==="aircraft"?Fm():t==="entity"?Om():c0(),o=new qi().setFromObject(a),c={widthM:o.max.x-o.min.x,heightM:o.max.y-o.min.y,lengthM:o.max.z-o.min.z};return this.dispose(a),Cm.set(n,c),c}static usesModel(t){return t.model!==void 0&&!(t.observerSide!==void 0&&Mg(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),a=new Ce;a.name=pi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*lu,i.updateMatrixWorld(!0);const o=new qi().setFromObject(i),c={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},l=Pm(e.sizeM,c)??Pm(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new R).multiplyScalar(l);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=e.kind==="aircraft"?h.y:o.min.y*l,i.traverse(u=>{u instanceof Tt&&(u.castShadow=!0,u.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):t.add(a),this.dispose(s)}static sizeOf(t){const e=this.naturalSize(t.kind,t.floors);return{widthM:t.sizeM?.widthM??e.widthM,lengthM:t.sizeM?.lengthM??e.lengthM,heightM:t.sizeM?.heightM??e.heightM}}static addLights(t,e){for(const i of e??[]){const n=P5(i.color),s=ze(t,new ui(hu,8,6),n,i.offsetM.y,!0);s.position.set(i.offsetM.x,i.offsetM.y,i.offsetM.z),s.userData={emissive:!0,lightId:i.id,lightColor:n},s.visible=!1;const a=s.material;a.blending=Ai,a.transparent=!0,a.depthWrite=!1,a.fog=!1}}static setLights(t,e,i,n,s=0,a=1,o=A5,c=[1,1,1]){if(!e||e.length===0)return;const l=new Map(e.map(f=>[f.id,f])),h=Math.max(1,n*o/hu),u=hu*h,d=a/(Math.PI*u*u);for(const f of t.children){if(!(f instanceof Tt))continue;const p=f.userData.lightId;if(!p)continue;const v=l.get(p);if(!v)continue;const m=s>0?xg(v,i,i+s):yv(v,i)?1:0;f.visible=m>0;const g=f.material,_=f.userData.lightColor;if(_){const y=m*T5*(v.intensity??1)*d;g.color.setRGB(_[0]*y*c[0],_[1]*y*c[1],_[2]*y*c[2])}f.scale.setScalar(h)}}static setLit(t,e,i,n=1){const[s,a,o]=e==="streetlight"?[R5,D5,K1]:[I5,C5,Z1],c=i?s*n/(Math.PI*a*a):0,l=[o[0]*c,o[1]*c,o[2]*c];t.traverse(h=>{const u=h.userData;!(h instanceof Tt)||!u.emissive||u.lightId||h.material.color.setRGB(...l)})}static dispose(t){t.traverse(e=>{if(!(e instanceof Tt))return;e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const mu="https://ufoathome.org/models/index.json";class $5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??K5()}async entries(t){const e=await this.load();return t?e.filter(i=>i.kind===t):e}async entry(t){return(await this.load()).find(e=>e.id===t)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function K5(){const r=`?v=${encodeURIComponent("0.86.2")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==mu?[t,mu]:[mu]).map(e=>e+r)}const Z5=[{id:"ufoathome",name:"UFO@home",credit:"3D models re-hosted by UFO@home, each under its own author's licence",creditUrl:"https://ufoathome.org/models/",create:()=>new $5}];async function Um(r){const{GLTFLoader:t}=await an(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-DYi1DaRQ.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(r,s=>i(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const nv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class mn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(t,e){this.mesh=new Tt(new Ki(2,2),new ue({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:mn.VERTEX,fragmentShader:mn.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ai,toneMapped:!1})),this.mesh.name=t,this.mesh.frustumCulled=!1,this.mesh.renderOrder=e,this.mesh.visible=!1}shine(t,e,i){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.material.uniforms.uRadius.value=e,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(t,e,i,n){const s=Math.max(t,n*mn.MIN_ANGLE_RAD),a=mn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(mn.MAX_SHARE,e/a)}}static conserving(t){return Math.sqrt(t/(mn.MAX_SHARE*mn.FILL*Math.PI))}static VERTEX=`
7217
7217
  uniform float uRadius;
7218
7218
  varying vec2 vOffset;
7219
7219
  void main() {
@@ -7842,4 +7842,4 @@ void main() {
7842
7842
  gl_FragColor = vec4(color, tex.a * uOpacity * (1.0 - blur * 0.5));
7843
7843
  }
7844
7844
  `;function hg(r){const e=document.createElement("canvas");e.width=128,e.height=128;const i=e.getContext("2d"),n=128/2-2,s=128/2,a=128/2,o="#010101",c="#f4f1e2";i.fillStyle=o,i.beginPath(),i.arc(s,a,n,0,Math.PI*2),i.fill();const l=Ir(r.illuminatedFraction,0,1),h=r.phaseFraction<.5,u=n*Math.abs(1-2*l),d=l<.5;return i.save(),i.beginPath(),i.arc(s,a,n,0,Math.PI*2),i.clip(),i.fillStyle=c,i.beginPath(),h?(i.arc(s,a,n,-Math.PI/2,Math.PI/2,!1),i.ellipse(s,a,u,n,0,Math.PI/2,-Math.PI/2,d)):(i.arc(s,a,n,Math.PI/2,-Math.PI/2,!1),i.ellipse(s,a,u,n,0,-Math.PI/2,Math.PI/2,d)),i.fill(),i.restore(),new ks(e)}function YE(r){const t=document.createElement("canvas");t.width=128,t.height=128;const e=t.getContext("2d");return e.fillStyle="rgba(0, 0, 0, 0.55)",e.beginPath(),e.arc(64,64,60,0,Math.PI*2),e.fill(),e.fillStyle="#ffffff",e.font="bold 52px sans-serif",e.textAlign="center",e.textBaseline="middle",e.fillText(r,64,68),new ks(t)}function Cu(r){let t=r;return function(){t|=0,t=t+1831565813|0;let i=Math.imul(t^t>>>15,1|t);return i=i+Math.imul(i^i>>>7,61|i)^i,((i^i>>>14)>>>0)/4294967296}}class Kl{constructor(t,e){this.source=t,this.create=e}scene;wanted;pumping=!1;disposed=!1;static PATIENCE_FRAMES=600;static SCENE_WIDTH_PX=320;paint(t,e){this.disposed||(this.wanted={t,canvas:e},this.pumping||this.pump())}recordingChanged(t){this.scene&&(this.scene.sightingData=t)}dispose(){this.disposed=!0,this.scene?.remove(),this.scene=void 0}ensureScene(){if(this.scene)return this.scene;const t=this.create();return t.setAttribute("max-pixel-ratio","1"),Object.assign(t.style,{position:"fixed",left:"-10000px",top:"0",width:`${Kl.SCENE_WIDTH_PX}px`,visibility:"hidden",pointerEvents:"none"}),document.body.appendChild(t),t.documentUrl=this.source.documentUrl,t.accountInTheRound=this.source.accountInTheRound,t.sightingData=this.source.sightingData,this.scene=t,t}async pump(){this.pumping=!0;try{for(;this.wanted&&!this.disposed;){const{t,canvas:e}=this.wanted;this.wanted=void 0;const i=this.ensureScene();i.interpretation!==this.source.interpretation&&(i.interpretation=this.source.interpretation),i.compareAccount!==this.source.compareAccount&&(i.compareAccount=this.source.compareAccount),i.showAt(t);for(let n=0;n<Kl.PATIENCE_FRAMES&&!this.wanted&&!this.disposed&&(await new Promise(s=>requestAnimationFrame(()=>s())),!this.wanted);n++)if(i.snapshotTo(e)){e.dataset.ready="true";break}}}finally{this.pumping=!1}}}const Pu=7.5,Lu=9;class is{static cache=new Map;static load(t){let e=is.cache.get(t);return e||(e=fetch(t).then(i=>i.arrayBuffer()).then(i=>is.parse(i)),is.cache.set(t,e)),e}static upTo(t,e){const i=t.filter((a,o)=>o===0||t[o-1].magnitudeLimit<e);if(i.length<=1)return is.load(t[0].url);const n=i.map(a=>a.url).join(`
7845
- `);let s=is.cache.get(n);return s||(s=Promise.all(i.map(a=>is.load(a.url))).then(a=>a.reduce((o,c)=>is.concat(o,c))),is.cache.set(n,s)),s}static parse(t){const e=t.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=e*Float32Array.BYTES_PER_ELEMENT;return{count:e,ra:new Float32Array(t,0*i,e),dec:new Float32Array(t,1*i,e),mag:new Float32Array(t,2*i,e),ci:new Float32Array(t,3*i,e)}}static concat(t,e){const i=(n,s)=>{const a=new Float32Array(n.length+s.length);return a.set(n,0),a.set(s,n.length),a};return{count:t.count+e.count,ra:i(t.ra,e.ra),dec:i(t.dec,e.dec),mag:i(t.mag,e.mag),ci:i(t.ci,e.ci)}}}class ug{constructor(t){this.names=t}body(t,e){return this.names?.bodies[t]??e}star(t){return this.names?.stars[t.name]??t.name}comet(t){return this.names?.comets[t.id]??t.name}nova(t){return this.names?.novae[t.id]??t.name}satelliteClass(t){return this.names?.satelliteClasses[t.id]??t.name}shower(t){return this.names?.showers[t.id]??t.name}lightRig(t){return this.names?.lightRigs[t.id]??t.name}instrument(t){return this.names?.instruments[t.id]??t.name}decorKind(t,e){return this.names?.decorKinds[t]??e}point(t){return ka.point(t,this.names?.compassPoints)}towards(t){return ka.towards(t,this.names)}}const qE="Global Meteor Network",$E="https://globalmeteornetwork.org/data/",KE="“Thunder” by Jerimee",ZE="https://creativecommons.org/licenses/by/3.0/",JE="CC BY 3.0";class tn{static fill(t,e){t.innerHTML="";const i=h=>t.appendChild(h),n=e.currentTerrainAttribution;n&&i(tn.text(n));const s=e.currentRoadAttribution;s&&i(tn.text(s));const a=e.ufoElement.observerMapCredit;a&&!n?.includes(a)&&i(tn.text(a));for(const h of e.decorModelCredits){const u=h.author?` — ${h.author}`:"",d=document.createElement("li");h.sourceUrl?d.append(tn.link(h.sourceUrl,h.title),document.createTextNode(`${u} (${h.license})`)):d.textContent=`${h.title}${u} (${h.license})`,i(d)}for(const h of e.ufoElement.sighting.references){if(!h.credit)continue;const u=document.createElement("li");h.creditUrl?u.appendChild(tn.link(h.creditUrl,h.credit)):u.textContent=h.credit,i(u)}if(e.ufoElement.sighting.traces.length>0){const h=new Rs(Pr.preferencesFor(e)),u=new Set(e.ufoElement.sighting.traces.map(d=>h.read(d.source)).filter(d=>!!d));for(const d of u)i(tn.text(d))}const o=e.satelliteState;if(o.status==="ready"&&o.credit){const h=document.createElement("li");h.appendChild(tn.link(o.creditUrl??"",o.credit)),i(h)}if(e.fireballState.status==="ready"&&e.fireballState.records.length>0){const h=document.createElement("li");h.append(tn.link($E,qE),document.createTextNode(" (CC BY 4.0)")),i(h)}const c=e.aircraftState;if(c.status==="ready"&&c.shown>0){const h=document.createElement("li");if(h.appendChild(tn.link(c.creditUrl,c.credit)),i(h),c.trailCredit){const u=document.createElement("li");u.appendChild(tn.link(c.trailCredit.creditUrl,c.trailCredit.credit)),i(u)}}const l=tn.text(`${KE} (`);l.append(tn.link(ZE,JE),document.createTextNode(")")),i(l)}static text(t){const e=document.createElement("li");return e.textContent=t,e}static link(t,e){const i=document.createElement("a");return i.href=t,i.target="_blank",i.rel="noopener",i.textContent=e,i}}const jE=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,QE=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,tA=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,eA=20,iA=1;class nA{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",t);return}}Fa.unlock(this.context)}setAmbient(t,e,i){if(this.requested={type:t,intensity:e,windSpeed:i},!this.context)return;this.paused&&(t="none",e=0,i=0);const n=t==="rain"||t==="hail"?t:"none";if(this.ambientVolume=n==="hail"?Math.min(1,e*1.3+.2):n==="rain"?e:0,n!==this.ambientKey){this.ambientKey=n;const a=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,n!=="none"&&this.startLoop(jE,this.ambientVolume).then(o=>this.applyIfCurrent(o,a,()=>this.ambientToken,c=>{this.ambientSource=c?.source,this.ambientGain=c?.gain,c&&(c.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(i/eA,1);const s=i>iA;if(s!==this.windActive){this.windActive=s;const a=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,s&&this.startLoop(QE,this.windVolume).then(o=>this.applyIfCurrent(o,a,()=>this.windToken,c=>{this.windSource=c?.source,this.windGain=c?.gain,c&&(c.gain.gain.value=this.windVolume)}))}else this.windGain&&(this.windGain.gain.value=this.windVolume)}setPaused(t){if(t===this.paused)return;this.paused=t;const{type:e,intensity:i,windSpeed:n}=this.requested;this.setAmbient(e,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(tA,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear()}applyIfCurrent(t,e,i,n){if(e!==i()){t?.source.stop();return}n(t)}async startLoop(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n,s.loop=!0;const a=i.createGain();return a.gain.value=e,s.connect(a).connect(this.output(i)),s.start(),{source:s,gain:a}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n;const a=i.createGain();a.gain.value=e,s.connect(a).connect(this.output(i)),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(t){const e=this.context;if(!e)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}stopSource(t,e){try{t?.stop()}catch{}t?.disconnect(),e?.disconnect()}}class Ts{constructor(t){this.elements=t;const{eccentricity:e,perihelionAu:i}=t,[n,s]=this.perifocalAxes(),a=Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2*(1+e)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,a),this.inverseSemiMajorAxis=(1-e)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(t){const e=t-this.elements.perihelionJd,i=this.universalAnomaly(e),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,a=1-i*i/s*Ts.stumpffC(n),o=e-i*i*i/Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2)*Ts.stumpffS(n);return{x:a*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:a*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:a*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(t){const e=this.positionAt(t);return Math.hypot(e.x,e.y,e.z)}universalAnomaly(t){if(t===0)return 0;const e=Math.sign(t),i=Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2)*Math.abs(t),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*Ts.stumpffS(c)+l*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let a=0;for(let o=0;o<Ts.MAX_ITERATIONS&&s-a>1e-13*Math.max(1,s);o++){const c=(a+s)/2;n(c)<i?a=c:s=c}return e*(a+s)/2}perifocalAxes(){const t=this.elements.ascendingNodeDeg*Math.PI/180,e=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(t),s=Math.sin(t),a=Math.cos(e),o=Math.sin(e),c=Math.cos(i),l=Math.sin(i);return[{x:n*a-s*o*c,y:s*a+n*o*c,z:o*l},{x:-n*o-s*a*c,y:-s*o+n*a*c,z:a*l}]}scale(t,e){return{x:t.x*e,y:t.y*e,z:t.z*e}}static stumpffC(t){if(Math.abs(t)<1e-6)return 1/2-t/24+t*t/720;if(t>0)return(1-Math.cos(Math.sqrt(t)))/t;const e=Math.sqrt(-t);return(Math.cosh(e)-1)/-t}static stumpffS(t){if(Math.abs(t)<1e-6)return 1/6-t/120+t*t/5040;if(t>0){const i=Math.sqrt(t);return(i-Math.sin(i))/(i*i*i)}const e=Math.sqrt(-t);return(Math.sinh(e)-e)/(e*e*e)}}const rv=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672960498922706,perihelionAu:.5872100477652511,inclinationDeg:162.218798367122,ascendingNodeDeg:58.56208298700436,argumentOfPerihelionDeg:111.7366940639061,perihelionJd:2.4187816784171113e6},peakMagnitude:0,peakOn:"1910-05-20",absoluteMagnitude:4.72,activityExponent:4,tailLengthDeg:100,tailLengthAu:.1638,note:"Passed 0.15 au from Earth on 20 May 1910, and the Earth crossed the outer tail the day before — the apparition that produced a genuine public panic."},{id:"brooks-1911",designation:"C/1911 O1",name:"Comet Brooks",orbit:{eccentricity:.9876404970138669,perihelionAu:.4898172916113738,inclinationDeg:33.34043866978714,ascendingNodeDeg:293.7022074981857,argumentOfPerihelionDeg:153.5578007321686,perihelionJd:2.4193378856140426e6},peakMagnitude:2,peakOn:"1911-10-25",absoluteMagnitude:5.59,activityExponent:4},{id:"skjellerup-maristany-1927",designation:"C/1927 X1",name:"Comet Skjellerup-Maristany",orbit:{eccentricity:.999839726885059,perihelionAu:.1761569619628186,inclinationDeg:85.1125991950808,ascendingNodeDeg:78.24360172472711,argumentOfPerihelionDeg:47.15877857390136,perihelionJd:2.4252326808989984e6},peakMagnitude:-6,peakOn:"1927-12-15",absoluteMagnitude:1.19,activityExponent:4,note:"One of the few comets of the century seen in full daylight."},{id:"de-kock-paraskevopoulos-1941",designation:"C/1941 B2",name:"Comet de Kock-Paraskevopoulos",orbit:{eccentricity:.9991026715181549,perihelionAu:.7900329662827822,inclinationDeg:168.2039226531089,ascendingNodeDeg:43.10609347214336,argumentOfPerihelionDeg:268.6990344196369,perihelionJd:2430022157765061e-9},peakMagnitude:2,peakOn:"1941-02-05",absoluteMagnitude:5.01,activityExponent:4},{id:"southern-1947",designation:"C/1947 X1",name:"the Southern Comet",orbit:{eccentricity:.9998424430916737,perihelionAu:.1100045955093761,inclinationDeg:138.5113919632757,ascendingNodeDeg:337.3114969669252,argumentOfPerihelionDeg:196.1820121395961,perihelionJd:2.4325220864727003e6},peakMagnitude:-3,peakOn:"1947-12-08",absoluteMagnitude:3.01,activityExponent:4,note:"A bright southern-hemisphere comet of December 1947, the month the American sighting wave of that year was still being argued over."},{id:"eclipse-1948",designation:"C/1948 V1",name:"the Eclipse Comet",orbit:{eccentricity:.9999130678247334,perihelionAu:.1354437057263306,inclinationDeg:23.11668597152911,ascendingNodeDeg:211.0454985994762,argumentOfPerihelionDeg:107.2474157073104,perihelionJd:2.4328519265329437e6},peakMagnitude:-2,peakOn:"1948-11-01",absoluteMagnitude:4.79,activityExponent:4,note:"Found during the total solar eclipse of 1 November 1948, which is how a comet that bright had gone unnoticed: it had been hidden in the Sun's glare."},{id:"arend-roland-1957",designation:"C/1956 R1",name:"Comet Arend-Roland",orbit:{eccentricity:1.0002570255357,perihelionAu:.3160532361485914,inclinationDeg:119.9440863251822,ascendingNodeDeg:215.8548157717755,argumentOfPerihelionDeg:308.775920364167,perihelionJd:2.4359365327396123e6},peakMagnitude:.5,peakOn:"1957-04-25",absoluteMagnitude:3.96,activityExponent:4,note:"Showed a spike pointing back TOWARD the Sun in late April 1957 — a real anti-tail, and much reported at the time."},{id:"mrkos-1957",designation:"C/1957 P1",name:"Comet Mrkos",orbit:{eccentricity:.9993521583504134,perihelionAu:.3549238508212375,inclinationDeg:93.9433042053929,ascendingNodeDeg:68.32441518619923,argumentOfPerihelionDeg:40.31823675802871,perihelionJd:243605193752228e-8},peakMagnitude:1,peakOn:"1957-08-05",absoluteMagnitude:5.07,activityExponent:4,note:"The second bright naked-eye comet of 1957, four months after Arend-Roland."},{id:"seki-lines-1962",designation:"C/1962 C1",name:"Comet Seki-Lines",orbit:{eccentricity:1.000003791331562,perihelionAu:.03139689112215131,inclinationDeg:65.01487186102287,ascendingNodeDeg:304.6776602796538,argumentOfPerihelionDeg:11.47295326312573,perihelionJd:2437756163010178e-9},peakMagnitude:-2.5,peakOn:"1962-04-01",absoluteMagnitude:9.3,activityExponent:4},{id:"ikeya-seki-1965",designation:"C/1965 S1",name:"Comet Ikeya-Seki",orbit:{eccentricity:.9999141178248997,perihelionAu:.007785966366889336,inclinationDeg:141.8642315267051,ascendingNodeDeg:346.9951764632611,argumentOfPerihelionDeg:69.04909813996062,perihelionJd:2.4390546837018197e6},peakMagnitude:-10,peakOn:"1965-10-21",alsoRecordedMagnitude:2,alsoRecordedOn:"1965-10-30",absoluteMagnitude:5.26,activityExponent:4.002,tailLengthDeg:25,tailLengthAu:.5048,note:"A sungrazer that passed 450 000 km above the Sun's surface and was seen beside it in broad daylight — the brightest comet of the twentieth century. It then stood in the dawn sky for a fortnight with a tail some 25 degrees long, which is the second magnitude recorded here."},{id:"bennett-1970",designation:"C/1969 Y1",name:"Comet Bennett",orbit:{eccentricity:.9962979048768408,perihelionAu:.5376209981502136,inclinationDeg:90.03975717147327,ascendingNodeDeg:224.6576652531314,argumentOfPerihelionDeg:354.1494209173161,perihelionJd:2.4406655455270996e6},peakMagnitude:0,peakOn:"1970-03-26",absoluteMagnitude:3.36,activityExponent:4},{id:"white-ortiz-bolelli-1970",designation:"C/1970 K1",name:"Comet White-Ortiz-Bolelli",orbit:{eccentricity:.9999488875801225,perihelionAu:.00884411465256722,inclinationDeg:138.9520738221631,ascendingNodeDeg:336.8194095816687,argumentOfPerihelionDeg:61.10224765396615,perihelionJd:2.4407209807728203e6},peakMagnitude:1,peakOn:"1970-05-22",absoluteMagnitude:4.35,activityExponent:4},{id:"kohoutek-1973",designation:"C/1973 E1",name:"Comet Kohoutek",orbit:{eccentricity:1.000007152175185,perihelionAu:.1424250377812859,inclinationDeg:14.30414984159355,ascendingNodeDeg:258.4893339663974,argumentOfPerihelionDeg:37.79772760699667,perihelionJd:2442044930687027e-9},peakMagnitude:0,peakOn:"1974-01-05",absoluteMagnitude:4.89,activityExponent:4,note:"Announced in advance as the comet of the century and remembered for disappointing: it was an ordinary naked-eye object, not the spectacle the press had promised."},{id:"west-1976",designation:"C/1975 V1",name:"Comet West",orbit:{eccentricity:1.000017859625611,perihelionAu:.1966006188461085,inclinationDeg:43.07319920579427,ascendingNodeDeg:118.9189245655447,argumentOfPerihelionDeg:358.4315101259072,perihelionJd:2442833721841768e-9},peakMagnitude:-3,peakOn:"1976-02-25",absoluteMagnitude:4.41,activityExponent:4,tailLengthDeg:30,tailLengthAu:.4325,note:"Broke into four pieces at perihelion. Barely reported at the time — the press had been burned by Kohoutek two years earlier."},{id:"iras-araki-alcock-1983",designation:"C/1983 H1",name:"Comet IRAS-Araki-Alcock",orbit:{eccentricity:.9898409731606003,perihelionAu:.9913412593828502,inclinationDeg:73.25000846947029,ascendingNodeDeg:49.10235754476374,argumentOfPerihelionDeg:192.8506176754439,perihelionJd:2.4454757545235856e6},peakMagnitude:1.7,peakOn:"1983-05-11",absoluteMagnitude:9.04,activityExponent:4,note:"Passed 0.031 au from Earth on 11 May 1983, one of the closest cometary approaches on record: it crossed a quarter of the sky in a night, which no other comet in this list did."},{id:"halley-1986",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672792271749998,perihelionAu:.5871034488173393,inclinationDeg:162.2422242700916,ascendingNodeDeg:58.85993640671803,argumentOfPerihelionDeg:111.8655480539208,perihelionJd:2.4464709589610207e6},peakMagnitude:2.1,peakOn:"1986-03-10",absoluteMagnitude:2.71,activityExponent:4,note:"The worst-placed return in two thousand years — famous, expected, and for most observers a faint smudge."},{id:"hyakutake-1996",designation:"C/1996 B2",name:"Comet Hyakutake",orbit:{eccentricity:.9997295133739305,perihelionAu:.2302272039470452,inclinationDeg:124.923592343765,ascendingNodeDeg:188.0454295899424,argumentOfPerihelionDeg:130.1724036582639,perihelionJd:2.4502048946148166e6},peakMagnitude:0,peakOn:"1996-03-25",absoluteMagnitude:4.75,activityExponent:4,tailLengthDeg:80,tailLengthAu:1,note:"Passed 0.10 au from Earth in March 1996, five weeks BEFORE perihelion, with a tail measured at some 80 degrees — the longest of the modern era."},{id:"hale-bopp-1997",designation:"C/1995 O1",name:"Comet Hale-Bopp",orbit:{eccentricity:.9951314746156615,perihelionAu:.9141695067003724,inclinationDeg:89.43017155012492,ascendingNodeDeg:282.470602866853,argumentOfPerihelionDeg:130.5872524854533,perihelionJd:2450539633099368e-9},peakMagnitude:-.8,peakOn:"1997-04-01",absoluteMagnitude:-1.06,activityExponent:4,tailLengthDeg:20,tailLengthAu:.9938,note:"Visible to the naked eye for about eighteen months, longer than any comet on record."},{id:"mcnaught-2007",designation:"C/2006 P1",name:"Comet McNaught",orbit:{eccentricity:1.00001811603225,perihelionAu:.1707325614080681,inclinationDeg:77.83726446452654,ascendingNodeDeg:267.4149080498975,argumentOfPerihelionDeg:155.9756130642756,perihelionJd:2454113298753579e-9},peakMagnitude:-5.5,peakOn:"2007-01-13",absoluteMagnitude:2.53,activityExponent:4,tailLengthDeg:35,tailLengthAu:.5009,note:"The brightest comet since Ikeya-Seki, seen in daylight beside the Sun in January 2007."},{id:"lovejoy-2011",designation:"C/2011 W3",name:"Comet Lovejoy",orbit:{eccentricity:.999915056276912,perihelionAu:.005553783989325053,inclinationDeg:134.3558712062691,ascendingNodeDeg:326.3693517957772,argumentOfPerihelionDeg:53.50991655176601,perihelionJd:2455911511809431e-9},peakMagnitude:-3,peakOn:"2011-12-16",alsoRecordedMagnitude:1.5,alsoRecordedOn:"2011-12-22",absoluteMagnitude:3.51,activityExponent:1.194,note:"A sungrazer that was expected to be destroyed at perihelion and came out the other side, to stand in the southern dawn sky for the rest of December — which is the second magnitude recorded here."},{id:"panstarrs-2013",designation:"C/2011 L4",name:"Comet PANSTARRS",orbit:{eccentricity:1.000032542889696,perihelionAu:.301544229714915,inclinationDeg:84.2081978367921,ascendingNodeDeg:65.66588626213694,argumentOfPerihelionDeg:333.6516444379993,perihelionJd:2456361669960698e-9},peakMagnitude:1,peakOn:"2013-03-10",absoluteMagnitude:5.98,activityExponent:4},{id:"neowise-2020",designation:"C/2020 F3",name:"Comet NEOWISE",orbit:{eccentricity:.9991782081129224,perihelionAu:.2946512466331692,inclinationDeg:128.9375043020912,ascendingNodeDeg:61.01042991771634,argumentOfPerihelionDeg:37.2786526292898,perihelionJd:2.4590341788972816e6},peakMagnitude:.9,peakOn:"2020-07-08",absoluteMagnitude:5.79,activityExponent:4,tailLengthDeg:10,tailLengthAu:.1808,note:"The first comet since Hale-Bopp that ordinary observers in the northern hemisphere saw without being told where to look."},{id:"tsuchinshan-atlas-2024",designation:"C/2023 A3",name:"Comet Tsuchinshan-ATLAS",orbit:{eccentricity:1.000020192843226,perihelionAu:.3914228969475176,inclinationDeg:139.1105462619479,ascendingNodeDeg:21.55945689078845,argumentOfPerihelionDeg:308.4913086299446,perihelionJd:2460581242087108e-9},peakMagnitude:0,peakOn:"2024-10-14",absoluteMagnitude:3.97,activityExponent:4,tailLengthDeg:20,tailLengthAu:.1902,note:"Briefly reported far brighter around 9 October 2024, when it stood almost between the observer and the Sun and forward-scattered the light through its own dust — a geometry this catalog's brightness model does not attempt, so what is stored is the ordinary evening-sky peak a few days later."}];class sA{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(t){const e=this.julianDayOf(t);return rv.filter(i=>Math.abs(e-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(t,e){return this.aroundDate(t).map(i=>this.appearanceOf(i,t,e)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(t,e,i){const n=Qe(e),s=this.earthPositionAt(n),a=this.apparentPositionOf(t,2451545+n.tt,s),o=this.subtract(a,s),c=this.length(a),l=this.length(o),h=this.tailEndAt(t,a,s,c,n,e,i),u=this.horizontalOf(o,n,e,i);return{apparition:t,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(t,c,l)}}static magnitudeAt(t,e,i){const n=t.absoluteMagnitude+5*Math.log10(i)+2.5*t.activityExponent*Math.log10(e);return Math.max(n,t.peakMagnitude)}static tailEndAt(t,e,i,n,s,a,o){if(t.tailLengthAu===void 0)return{};const c=1+t.tailLengthAu/n,l=this.subtract({x:e.x*c,y:e.y*c,z:e.z*c},i),h=this.subtract(e,i);return{tailEnd:this.horizontalOf(l,s,a,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(t,e,i){const n=this.orbitOf(t);let s=n.positionAt(e);for(let a=0;a<2;a++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(e-o)}return s}static horizontalOf(t,e,i,n){const s=Wr(Kw(),new ke(t.x,t.y,t.z,e)),a=Wr(Y1(e),s),o=Rw(e,new Z0(n.lat,n.lng,n.elevationM)),c=new ke(a.x-o.x,a.y-o.y,a.z-o.z,e),l=j0(c);return Q0(l.ra,l.dec,i,n)}static earthPositionAt(t){return Wr($w(),la(Et.Earth,t))}static julianDayOf(t){return 2451545+Qe(t).tt}static orbitOf(t){const e=this.orbits.get(t.id);if(e)return e;const i=new Ts(t.orbit);return this.orbits.set(t.id,i),i}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}static length(t){return Math.hypot(t.x,t.y,t.z)}static angleBetween(t,e){const i=(t.x*e.x+t.y*e.y+t.z*e.z)/(this.length(t)*this.length(e)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const Ou=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class dg{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(t){const e=this.julianDayOf(t);return Ou.filter(i=>this.magnitudeAt(i,e)!==void 0)}static appearancesAt(t,e){const i=this.julianDayOf(t),n=[];for(const s of Ou){const a=this.magnitudeAt(s,i);a!==void 0&&n.push({outburst:s,position:Hn.ofJ2000(s.raHours,s.decDeg,t,e),magnitude:a})}return n.sort((s,a)=>s.magnitude-a.magnitude)}static brightestAt(t,e){return this.appearancesAt(t,e)[0]}static byId(t){return Ou.find(e=>e.id===t)}static magnitudeAt(t,e){const i=t.lightCurve,n=e-t.startJd;if(i.length===0||n<i[0][0]||n>i[i.length-1][0])return;let s=1;for(;s<i.length-1&&i[s][0]<n;)s++;const[a,o]=i[s-1]??i[0],[c,l]=i[s]??i[0];if(c===a)return o;const h=Math.min(1,Math.max(0,(n-a)/(c-a)));return o+h*(l-o)}static julianDayOf(t){return t.getTime()/864e5+this.UNIX_EPOCH_JD}}const aA=[{id:"quadrantids",code:"QUA",name:"Quadrantids",radiantRaHours:15.33,radiantDecDeg:49.7,start:{month:12,day:28},peak:{month:1,day:3},end:{month:1,day:12},peakZhr:110,velocityKmS:41,populationIndex:2.1},{id:"lyrids",code:"LYR",name:"April Lyrids",radiantRaHours:18.13,radiantDecDeg:33.3,start:{month:4,day:16},peak:{month:4,day:22},end:{month:4,day:25},peakZhr:18,velocityKmS:49,populationIndex:2.1},{id:"eta-aquariids",code:"ETA",name:"eta Aquariids",radiantRaHours:22.53,radiantDecDeg:-1,start:{month:4,day:19},peak:{month:5,day:6},end:{month:5,day:28},peakZhr:50,velocityKmS:66,populationIndex:2.4},{id:"alpha-capricornids",code:"CAP",name:"alpha Capricornids",radiantRaHours:20.47,radiantDecDeg:-9.2,start:{month:7,day:3},peak:{month:7,day:30},end:{month:8,day:15},peakZhr:5,velocityKmS:23,populationIndex:2.5},{id:"southern-delta-aquariids",code:"SDA",name:"Southern delta Aquariids",radiantRaHours:22.67,radiantDecDeg:-16.4,start:{month:7,day:12},peak:{month:7,day:30},end:{month:8,day:23},peakZhr:25,velocityKmS:41,populationIndex:3.2},{id:"perseids",code:"PER",name:"Perseids",radiantRaHours:3.22,radiantDecDeg:58,start:{month:7,day:17},peak:{month:8,day:12},end:{month:8,day:24},peakZhr:100,velocityKmS:59,populationIndex:2.2},{id:"southern-taurids",code:"STA",name:"Southern Taurids",radiantRaHours:3.47,radiantDecDeg:13,start:{month:9,day:10},peak:{month:10,day:10},end:{month:11,day:20},peakZhr:5,velocityKmS:27,populationIndex:2.3},{id:"draconids",code:"DRA",name:"October Draconids",radiantRaHours:17.47,radiantDecDeg:54,start:{month:10,day:6},peak:{month:10,day:8},end:{month:10,day:10},peakZhr:10,velocityKmS:20,populationIndex:2.6},{id:"orionids",code:"ORI",name:"Orionids",radiantRaHours:6.35,radiantDecDeg:15.6,start:{month:10,day:2},peak:{month:10,day:21},end:{month:11,day:7},peakZhr:20,velocityKmS:66,populationIndex:2.5},{id:"northern-taurids",code:"NTA",name:"Northern Taurids",radiantRaHours:3.87,radiantDecDeg:22,start:{month:10,day:20},peak:{month:11,day:12},end:{month:12,day:10},peakZhr:5,velocityKmS:29,populationIndex:2.3},{id:"leonids",code:"LEO",name:"Leonids",radiantRaHours:10.13,radiantDecDeg:21.6,start:{month:11,day:6},peak:{month:11,day:17},end:{month:11,day:30},peakZhr:15,velocityKmS:71,populationIndex:2.5},{id:"geminids",code:"GEM",name:"Geminids",radiantRaHours:7.47,radiantDecDeg:32.3,start:{month:12,day:4},peak:{month:12,day:14},end:{month:12,day:17},peakZhr:150,velocityKmS:35,populationIndex:2.6},{id:"ursids",code:"URS",name:"Ursids",radiantRaHours:14.47,radiantDecDeg:75.3,start:{month:12,day:17},peak:{month:12,day:22},end:{month:12,day:26},peakZhr:10,velocityKmS:33,populationIndex:3}],Zl=6.5;class Nu{static activeAt(t){return aA.flatMap(e=>{const i=this.nearness(e,t);return i<=0?[]:[{shower:e,zhr:e.peakZhr*i,nearness:i}]})}static nearness(t,e){const i=this.dayOfYear(e),n=this.dayOfYear(this.asDate(t.start)),s=this.dayOfYear(this.asDate(t.peak)),a=this.dayOfYear(this.asDate(t.end)),o=this.wrappedDelta(i,s),c=this.wrappedDelta(s,n),l=this.wrappedDelta(a,s);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(t,e,i,n=Zl){if(e<=0)return 0;const s=Zl-n;return t*Math.sin(e*Math.PI/180)/Math.pow(i,s)}static radiantPosition(t,e,i){return Hn.ofJ2000(t.radiantRaHours,t.radiantDecDeg,e,i)}static dayOfYear(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Math.floor((Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())-e)/864e5)+1}static asDate(t){return new Date(Date.UTC(2001,t.month-1,t.day))}static wrappedDelta(t,e){const i=t-e;return i>182?i-365:i<-182?i+365:i}}class ai{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(t,e){const i=Qe(t),n=new lh(0,Aw(t).elon-90,1),s=Wr(Jw(i),J0(n,i)),a=j0(s);return Q0(a.ra,a.dec,t,e)}static observedRatePerHour(t,e=Zl){const i=ai.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(t*Math.PI/180)),n=Zl-e;return(ai.QUIET_RATE_PER_HOUR+i)/Math.pow(ai.POPULATION_INDEX,n)}static schedule(t){const e=new dh(t.seed^1542469173);return za.schedule(t).map(i=>{const n=ai.toCartesian({altitudeDeg:Math.asin(e.next())*180/Math.PI,azimuthDeg:e.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,a=ai.turnAround(n,e.between(0,360)),o={x:n.x*Math.cos(s)+a.x*Math.sin(s),y:n.y*Math.cos(s)+a.y*Math.sin(s),z:n.z*Math.cos(s)+a.z*Math.sin(s)};return{...i,radiant:ai.toHorizontal(o),bearingDeg:ai.bearingFrom(o,n)}})}static turnAround(t,e){const[i,n]=ai.basisAround(t),s=e*Math.PI/180;return{x:i.x*Math.cos(s)+n.x*Math.sin(s),y:i.y*Math.cos(s)+n.y*Math.sin(s),z:i.z*Math.cos(s)+n.z*Math.sin(s)}}static bearingFrom(t,e){const[i,n]=ai.basisAround(t),s=t.x*e.x+t.y*e.y+t.z*e.z,a=ai.normalise({x:e.x-t.x*s,y:e.y-t.y*s,z:e.z-t.z*s});return(Math.atan2(a.x*n.x+a.y*n.y+a.z*n.z,a.x*i.x+a.y*i.y+a.z*i.z)*180/Math.PI%360+360)%360}static basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=ai.normalise(ai.cross(t,e));return[i,ai.normalise(ai.cross(t,i))]}static toHorizontal(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,t.y/e)))*180/Math.PI,azimuthDeg:(Math.atan2(t.x,-t.z)*180/Math.PI%360+360)%360}}static appearanceOf(t){const e=ai.toCartesian(t.radiant??{altitudeDeg:90,azimuthDeg:0}),i=ai.turnAround(e,t.bearingDeg),n=t.fromRadiantDeg*Math.PI/180;return ai.toHorizontal({x:e.x*Math.cos(n)+i.x*Math.sin(n),y:e.y*Math.cos(n)+i.y*Math.sin(n),z:e.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180,n=Math.cos(e);return{x:n*Math.sin(i),y:Math.sin(e),z:-n*Math.cos(i)}}static cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}static normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}static TYPICAL_VELOCITY_KM_S=40}const fg="https://ufoathome.org/tle/index.json";class Li{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Li.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/tle/index.json",location.href).href),t.includes(fg)||t.push(fg),t}static FIRST_SNAPSHOT="2021-02-22";async covers(t){const e=Date.parse(`${Li.FIRST_SNAPSHOT}T00:00:00Z`)-Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS;if(t.getTime()<e)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>t.getTime()>=Date.parse(n.from)-Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS&&t.getTime()<=Date.parse(n.to)+Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS):!1}async at(t){const e=await this.loadIndex();if(!e)return;const{index:i,base:n}=e,s=[],a=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,t,i,n);s.push(...c),a.push(this.coverageOf(o,t,i,c.length>0))}return{objects:s,coverage:a,credit:i.credit,creditUrl:i.source}}async kindAt(t,e,i,n){const s=e.getTime(),a=i.binDays*Li.DAY_MS,o=Math.floor(s/a),c=s-o*a<a/2?o-1:o+1,l=new Set(i.kinds[t].bins),h=[o,c].map(v=>new Date(v*a).toISOString().slice(0,10)).filter(v=>l.has(v));if(h.length===0)return[];const[u,...d]=await Promise.all([this.json(new URL(`objects-${t}.json`,n).href),...h.map(v=>this.binary(new URL(`${t}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of Li.decode(v,i.recordBytes)){const g=f.get(m.norad);(!g||Math.abs(m.epochMs-s)<Math.abs(g.epochMs-s))&&f.set(m.norad,m)}const p=[];for(const v of f.values()){const m=Math.abs(v.epochMs-s)/Li.DAY_MS;if(m>Li.MAX_ELEMENT_AGE_DAYS)continue;const g=u[v.norad]??{name:String(v.norad)};g.launch&&Date.parse(`${g.launch}T00:00:00Z`)>s||p.push({norad:v.norad,name:g.name,kind:t,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(t,e,i,n){const{from:s,to:a}=i.kinds[t],o=e.getTime(),c=Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(a)+c?"after":"gap";return{kind:t,status:l,from:s,to:a}}static decode(t,e){const i=new DataView(t),n=[];for(let s=0;s+e<=t.byteLength;s+=e)n.push({norad:i.getUint32(s,!0),epochMs:i.getFloat64(s+4,!0),bstar:i.getFloat32(s+12,!0),inclinationDeg:i.getFloat32(s+16,!0),raanDeg:i.getFloat32(s+20,!0),eccentricity:i.getFloat32(s+24,!0),argOfPerigeeDeg:i.getFloat32(s+28,!0),meanAnomalyDeg:i.getFloat32(s+32,!0),meanMotion:i.getFloat64(s+36,!0)});return n}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;return{index:await e.json(),base:t}}catch{}})(),this.index}json(t){return this.cached(t,async e=>e.json())}binary(t){return this.cached(t,async e=>e.arrayBuffer())}cached(t,e){let i=this.files.get(t);return i||(i=this.fetchImpl(t).then(n=>{if(!n.ok)throw new Error(`${t}: ${n.status}`);return e(n)}),i.catch(()=>this.files.delete(t)),this.files.set(t,i)),i}}class rA{lowerM;upperM;add(t,e){if(!(t<=0)){if(e.behindM!==void 0){const i=De.sizeMAt(e.behindM,t);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(e.inFrontM!==void 0){const i=De.sizeMAt(e.inFrontM,t);this.upperM=this.upperM===void 0?i:Math.min(this.upperM,i)}}}get sizeRange(){return{minM:this.lowerM,maxM:this.upperM}}get empty(){return this.lowerM===void 0&&this.upperM===void 0}get contradictory(){return this.lowerM!==void 0&&this.upperM!==void 0&&this.lowerM>this.upperM}distanceRangeAt(t){return t<=0?{}:{minM:this.lowerM===void 0?void 0:De.distanceMAt(this.lowerM,t),maxM:this.upperM===void 0?void 0:De.distanceMAt(this.upperM,t)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ha{static DEG_PER_SECOND=360/86164.0905;static degOver(t){return Math.max(0,t)*Ha.DEG_PER_SECOND}static instants(t,e){if(!(e>0))return 1;const i=Ha.degOver(t)/e;return i<1?1:Math.min(Ha.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class Hi{static EYE={apertureMm:7,exposureSeconds:.1,resolutionArcsec:60};static WAVELENGTH_M=55e-8;static ARCSEC_PER_RADIAN=180*3600/Math.PI;static UNKNOWN_CAMERA_FOCAL_MM=50;static UNKNOWN_CAMERA_DETAIL_UM=20;static get skyDriftArcsecPerSecond(){return Ha.DEG_PER_SECOND*3600}static graspOf(t,e={}){const i=e.exposureSeconds??t.exposureSeconds,n=e.fNumber??t.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return Hi.EYE;const s=e.focalLengthMm??t.frame?.focalLengthMm??Hi.UNKNOWN_CAMERA_FOCAL_MM,a=s/n,o=Hi.resolutionArcsec(t,s,a);return{apertureMm:a,exposureSeconds:Math.min(i,Hi.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(t,e,i){const s=(t.detailUm??Hi.UNKNOWN_CAMERA_DETAIL_UM)/1e3/e*Hi.ARCSEC_PER_RADIAN,a=1.22*Hi.WAVELENGTH_M/(i/1e3)*Hi.ARCSEC_PER_RADIAN;return Math.max(s,a)}static trailLimitedSeconds(t){return t/Hi.skyDriftArcsecPerSecond}static gainOverEye(t,e={}){const i=Hi.graspOf(t,e),n=Hi.EYE,s=(i.apertureMm/n.apertureMm)**2,a=i.exposureSeconds/n.exposureSeconds,o=(n.resolutionArcsec/i.resolutionArcsec)**2;return 1.25*Math.log10(s*a*o)}static gainFor(t,e){const i=e.fieldOfViewDeg===void 0?void 0:mi.focalLengthMmFor(t,e.fieldOfViewDeg);return Hi.gainOverEye(t,{fNumber:e.fNumber,focalLengthMm:i,exposureSeconds:e.exposureSeconds})}}const pg=111320,To=Math.PI/180,oA=1.02,cA=1;class Ho{static of(t,e){const i=Ho.sightings(t,e);if(i.length<2)return;const n=Ho.baseline(i);if(!n)return;const{near:s,far:a,closedM:o}=n,c=Math.tan(a.widthDeg/2*To)===0?0:Math.tan(s.widthDeg/2*To)/Math.tan(a.widthDeg/2*To);if(c<oA)return;const l=o/(c-1),h=De.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:De.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:a.t,toT:s.t,closedM:o}}static sightings(t,e){return t.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===e)?.shape,s=n?.angular?.widthDeg,a=Ze(t,i.t);return s===void 0||s<=0||a?.lat===void 0||a.lng===void 0?[]:[{t:i.t,widthDeg:s,lat:a.lat,lng:a.lng,sightAzimuthDeg:n?.aim?.azimuthDeg??a.headingDeg}]}).sort((i,n)=>i.t-n.t)}static baseline(t){let e;for(const i of t)for(const n of t){if(i.t>=n.t)continue;const s=Ho.closedAlongSight(i,n),[a,o,c]=s>=0?[n,i,s]:[i,n,-s];c<cA||a.widthDeg<=o.widthDeg||(!e||c>e.closedM)&&(e={near:a,far:o,closedM:c})}return e}static closedAlongSight(t,e){const i=(e.lat-t.lat)*pg,n=(e.lng-t.lng)*pg*Math.cos(t.lat*To),s=(t.sightAzimuthDeg??0)*To;return i*Math.cos(s)+n*Math.sin(s)}}class Bi{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(t){if(t.statedM!==void 0&&t.statedM>0)return{distanceM:Bi.atLeastNearest(t.statedM),basis:"stated"};if(t.hypothesisM!==void 0&&t.hypothesisM>0)return{distanceM:Bi.atLeastNearest(t.hypothesisM),basis:"hypothesis"};if(t.derivedM!==void 0&&t.derivedM>0)return{distanceM:Bi.atLeastNearest(t.derivedM),basis:"derived"};const e=Bi.largest(t.range?.minM,t.crossing?.behindM),i=Bi.smallest(t.range?.maxM,t.crossing?.inFrontM),n=e===void 0?void 0:e*Bi.MARGIN,s=i===void 0?void 0:i/Bi.MARGIN;return n!==void 0&&s!==void 0?{distanceM:Bi.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:Bi.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<Bi.CONVENTIONAL_M?{distanceM:Bi.atLeastNearest(s),basis:"bounded"}:{distanceM:Bi.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(t){return Math.max(Bi.NEAREST_M,t)}static largest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.max(...e)}static smallest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.min(...e)}}const Fu=Math.PI/180;class ie{constructor(t,e,i){this.body=t,this.ground=e;const n=[...t.track].sort((s,a)=>s.t-a.t);this.keys=this.place(n,i);for(const s of n)ie.collect(this.motionKeys,s.t,s.motions),ie.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(t,e,i){for(const[n,s]of Object.entries(i??{})){const a=t.get(n)??[];a.push({t:e,value:s}),t.set(n,a)}}motionsAt(t){return ie.channelsAt(this.motionKeys,t,0)}lightsAt(t){return this.lightKeys.size>0?ie.channelsAt(this.lightKeys,t,void 0):void 0}static channelsAt(t,e,i){const n={};for(const[s,a]of t){let o=a.length-1;for(;o>=0&&a[o].t>e;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const c=a[o],l=a[Math.min(o+1,a.length-1)],h=l===c||l.t===c.t?0:Math.min(1,(e-c.t)/(l.t-c.t));n[s]=ie.lerp(c.value,l.value,h)}return n}static eyeOf(t,e,i){const n=Ze(t,0),s=Ze(t,e),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?Je(s.lat,s.lng,n.lat,n.lng):void 0,c=o?o.x:0,l=o?-o.z:0;return{eastM:c,northM:l,upM:i.heightAt(c,l)+ie.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(t,e,i,n){const s=ie.directionOf(e,i),a=l=>t.upM+s.upM*l-n.heightAt(t.eastM+s.eastM*l,t.northM+s.northM*l);let o=0,c=0;for(;c<ie.MAX_RANGE_M;){if(c=o+Math.max(.5,o*.01),a(c)<=0){for(let l=0;l<30;l++){const h=(o+c)/2;a(h)<=0?c=h:o=h}return c}o=c}}static directionOf(t,e){const i=t*Fu,n=e*Fu;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(t){const e=this.keys;if(e.length===0||t<e[0].t)return;let i=e.length-1;for(;i>0&&e[i].t>t;)i--;const n=e[i];if(!n.present)return;const s=e[Math.min(i+1,e.length-1)],a=s===n||s.t===n.t?0:Math.min(1,(t-n.t)/(s.t-n.t)),o=ie.lerp(n.eastM,s.eastM,a),c=ie.lerp(n.northM,s.northM,a),l={widthM:ie.lerp(n.sizeM.widthM,s.sizeM.widthM,a),lengthM:ie.lerp(n.sizeM.lengthM,s.sizeM.lengthM,a),heightM:ie.lerp(n.sizeM.heightM,s.sizeM.heightM,a)},h={headingDeg:ie.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,a),pitchDeg:ie.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,a),rollDeg:ie.lerp(n.attitude.rollDeg,s.attitude.rollDeg,a)};let u;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const d=ie.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,a);u=this.groundUnderFootprint(o,c,l,h.headingDeg)+d+l.heightM/2}else u=ie.lerp(this.centreUpOf(n),this.centreUpOf(s),a);return{id:this.body.id,model:this.body.model,explains:this.body.explains??[],outlineNode:this.body.outlineNode,eastM:o,northM:c,upM:u,sizeM:l,attitude:h,appearance:{color:(a<1?n:s).appearance.color,albedo:ie.lerp(n.appearance.albedo,s.appearance.albedo,a),luminanceCdM2:ie.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,a)},flame:ie.flameBetween(n.flame,s.flame,a),motions:this.motionsAt(t),lights:this.lightsAt(t),throwsFlame:this.body.track.some(d=>d.flame!==void 0&&d.flame.luminanceCdM2>0)}}static flameBetween(t,e,i){if(!t||t.luminanceCdM2<=0)return i>=1&&e&&e.luminanceCdM2>0?e:void 0;const n=t,s=e??t,a={...i<1?n:s,lengthM:ie.lerp(n.lengthM,s.lengthM,i),widthM:ie.lerp(n.widthM,s.widthM,i),luminanceCdM2:ie.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return a.luminanceCdM2>0?a:void 0}centreUpOf(t){return"upM"in t.vertical?t.vertical.upM:this.groundUnderFootprint(t.eastM,t.northM,t.sizeM,t.attitude.headingDeg)+t.vertical.aboveGroundM+t.sizeM.heightM/2}groundUnderFootprint(t,e,i,n){const s=n*Fu,a={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(t,e);for(const[l,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const u=l*i.widthM/2,d=h*i.lengthM/2;c=Math.max(c,this.ground.heightAt(t+a.eastM*u+o.eastM*d,e+a.northM*u+o.northM*d))}return c}place(t,e){const i=[];let n;for(const s of t){const a=s.sizeM??n?.sizeM??ie.DEFAULT_SIZE,o={headingDeg:s.attitude?.headingDeg??n?.attitude.headingDeg??0,pitchDeg:s.attitude?.pitchDeg??n?.attitude.pitchDeg??0,rollDeg:s.attitude?.rollDeg??n?.attitude.rollDeg??0},c={color:s.appearance?.color??n?.appearance.color??ie.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??ie.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??ie.DEFAULT_APPEARANCE.luminanceCdM2},l=this.positionOf(s,e)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s)??n.vertical});if(!l)continue;const h=s.flame??n?.flame,u=s.present??n?.present??!0;n={t:s.t,...l,sizeM:a,attitude:o,appearance:c,flame:h,present:u},i.push(n)}return i}verticalOf(t){if(t.onGround)return{aboveGroundM:0};if(t.altitudeAboveGroundM!==void 0)return{aboveGroundM:t.altitudeAboveGroundM}}positionOf(t,e){if(t.eastM!==void 0&&t.northM!==void 0)return{eastM:t.eastM,northM:t.northM,vertical:this.verticalOf(t)??{aboveGroundM:0}};if(t.azimuthDeg===void 0||t.altitudeDeg===void 0)return;const i=e(t.t);if(!i)return;const n=t.distanceM??(t.onGround?ie.lineOfSightMeetsGround(i,t.azimuthDeg,t.altitudeDeg,this.ground):void 0);if(n===void 0)return;const s=ie.directionOf(t.azimuthDeg,t.altitudeDeg),a=i.eastM+s.eastM*n,o=i.northM+s.northM*n;return{eastM:a,northM:o,vertical:this.verticalOf(t)??{upM:i.upM+s.upM*n}}}static lerp(t,e,i){return t+(e-t)*i}static lerpAngle(t,e,i){const n=((e-t)%360+540)%360-180;return((t+n*i)%360+360)%360}}class me{static A=6378137;static E2=.00669437999014;static DEG=Math.PI/180;static STANDARD_DISTANCE_KM=100;static DEFAULT_COLOR="#ffb347";static DEFAULT_TRAIN_S=1.5;static FADE_MS=600;static TRAIN_POINTS=8;static leadAt(t,e){const i=t.track;if(i.length<2||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-2&&i[n+1].t<e;)n++;const s=i[n],a=i[n+1],o=a.t-s.t,c=o>0?(e-s.t)/o:0,[l,h]=me.alongGreatCircle(s,a,c);return{lat:l,lng:h,heightM:(s.altitudeKm+(a.altitudeKm-s.altitudeKm)*c)*1e3}}static viewsAt(t,e,i){const n=[];for(const s of t){const a=s.track[0]?.t??0,o=s.track[s.track.length-1]?.t??0;s.fragments.forEach((c,l)=>{const h=c.fromT??a,u=c.untilT??o;if(e<h||e>u)return;const d=(c.lagS??0)*1e3,f=me.leadAt(s,e-d);if(!f)return;const p=me.seenFrom(i,f);if(p.altitudeDeg<0)return;const v=Math.min(me.FADE_MS,(u-h)/4),m=v>0?Math.min(1,(e-h)/v,(u-e)/v):1,g=-2.5*Math.log10(Math.max(m,.001)),_=c.absoluteMagnitude+5*Math.log10(p.distanceKm/me.STANDARD_DISTANCE_KM)+g,y=[p],M=(c.trainS??me.DEFAULT_TRAIN_S)*1e3;for(let b=1;b<=me.TRAIN_POINTS;b++){const w=Math.min(M*b/me.TRAIN_POINTS,e-h),T=me.leadAt(s,e-d-w);if(!T||(y.push(me.seenFrom(i,T)),w>=e-h))break}n.push({reentryId:s.id,fragmentId:c.id??String(l),head:p,magnitude:_,color:c.color??me.DEFAULT_COLOR,train:y})})}return n}static seenFrom(t,e){const i=me.ecef(t),n=me.ecef(e),s=n[0]-i[0],a=n[1]-i[1],o=n[2]-i[2],c=t.lat*me.DEG,l=t.lng*me.DEG,h=-Math.sin(l)*s+Math.cos(l)*a,u=-Math.sin(c)*Math.cos(l)*s-Math.sin(c)*Math.sin(l)*a+Math.cos(c)*o,d=Math.cos(c)*Math.cos(l)*s+Math.cos(c)*Math.sin(l)*a+Math.sin(c)*o,f=Math.hypot(h,u,d);return{altitudeDeg:Math.asin(d/f)/me.DEG,azimuthDeg:(Math.atan2(h,u)/me.DEG+360)%360,distanceKm:f/1e3}}static ecef(t){const e=t.lat*me.DEG,i=t.lng*me.DEG,n=Math.sin(e),s=me.A/Math.sqrt(1-me.E2*n*n);return[(s+t.heightM)*Math.cos(e)*Math.cos(i),(s+t.heightM)*Math.cos(e)*Math.sin(i),(s*(1-me.E2)+t.heightM)*n]}static alongGreatCircle(t,e,i){const n=h=>{const u=h.lat*me.DEG,d=h.lng*me.DEG;return[Math.cos(u)*Math.cos(d),Math.cos(u)*Math.sin(d),Math.sin(u)]},s=n(t),a=n(e),o=Math.max(-1,Math.min(1,s[0]*a[0]+s[1]*a[1]+s[2]*a[2])),c=Math.acos(o);let l;if(c<1e-12)l=s;else{const h=Math.sin((1-i)*c)/Math.sin(c),u=Math.sin(i*c)/Math.sin(c);l=[s[0]*h+a[0]*u,s[1]*h+a[1]*u,s[2]*h+a[2]*u]}return[Math.atan2(l[2],Math.hypot(l[0],l[1]))/me.DEG,Math.atan2(l[1],l[0])/me.DEG]}}class nf{static FIRST_DAY="2022-01-01";static mayCover(t){return new Date(t).toISOString().slice(0,10)>=nf.FIRST_DAY}}class lA{constructor(t,e,i){this.citation=t,this.covers=e,this.load=i}loading;mayCover(t){return this.covers(t)}async between(t,e,i,n){try{return await(await this.provider()).between(t,e,i,n)}catch{return{status:"failed"}}}async describe(t,e){try{return await(await this.provider()).describe?.(t,e)}catch{return}}provider(){if(!this.loading){const t=this.load();this.loading=t,t.catch(()=>{this.loading===t&&(this.loading=void 0)})}return this.loading}}const hA="Aircraft positions: adsb.lol feeders and contributors, Open Database License 1.0 (https://www.adsb.lol/docs/open-data/historical/)",uA=[{id:"adsb-lol",name:"adsb.lol",credit:"adsb.lol feeders and contributors, ODbL 1.0",creditUrl:"https://www.adsb.lol/docs/open-data/historical/",create:()=>new lA(hA,r=>nf.mayCover(r),async()=>new(await an(async()=>{const{AdsbLolArchiveProvider:r}=await import("./AdsbLolArchiveProvider-2vNkvjL5.js");return{AdsbLolArchiveProvider:r}},[],import.meta.url)).AdsbLolArchiveProvider)}];class Gi{static MAX_GAP_S=60;static FT_TO_M=.3048;static EARTH_RADIUS_KM=6371;static seenFrom(t,e,i){const n=Gi.positionAt(t,i);if(!n)return;const s=me.seenFrom(e,n.geo);if(!(s.altitudeDeg<0))return{track:t,sky:s,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg,angularRateDegPerS:Gi.angularRate(t,e,i)}}static viewsAt(t,e,i){return t.flatMap(n=>Gi.seenFrom(n,e,i)??[])}static groundDistanceKm(t,e){const i=Math.PI/180,n=Math.sin((e.lat-t.lat)*i/2)**2+Math.cos(t.lat*i)*Math.cos(e.lat*i)*Math.sin((e.lng-t.lng)*i/2)**2;return 2*Gi.EARTH_RADIUS_KM*Math.asin(Math.min(1,Math.sqrt(n)))}static wrapLongitude(t){return((t+180)%360+360)%360-180}static positionAt(t,e){const i=t.points;if(i.length===0||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-1&&i[n+1].t<=e;)n++;const s=i[n],a=i[n+1]??s,o=a.t-s.t;if(o>Gi.MAX_GAP_S*1e3)return;const c=o>0?(e-s.t)/o:0,l=s.altitudeFt+(a.altitudeFt-s.altitudeFt)*c,h=(a.lng-s.lng+540)%360-180;return{geo:{lat:s.lat+(a.lat-s.lat)*c,lng:Gi.wrapLongitude(s.lng+h*c),heightM:l*Gi.FT_TO_M},altitudeFt:l,groundSpeedKt:s.groundSpeedKt,trackDeg:s.trackDeg}}static angularRate(t,e,i){const n=Gi.positionAt(t,i-500),s=Gi.positionAt(t,i+500);if(!n||!s)return;const a=Gi.unit(me.seenFrom(e,n.geo)),o=Gi.unit(me.seenFrom(e,s.geo)),c=Math.min(1,Math.max(-1,a[0]*o[0]+a[1]*o[1]+a[2]*o[2]));return Math.acos(c)*180/Math.PI}static unit(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180;return[Math.cos(e)*Math.sin(i),Math.cos(e)*Math.cos(i),Math.sin(e)]}}const mg="https://ufoathome.org/fireballs/index.json";class hs{static FIRST_MONTH="2018-12";static STRIKING_MAGNITUDE=-1;static COLOR="#eef2ff";static TRAIN_S=.3;fetchImpl;indexUrls;index;months=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??hs.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/fireballs/index.json",location.href).href),t.includes(mg)||t.push(mg),t}static mayCover(t){return new Date(t).toISOString().slice(0,7)>=hs.FIRST_MONTH}async credit(){return(await this.loadIndex())?.index.credit}async between(t,e){if(!hs.mayCover(e))return;const i=await this.loadIndex();if(!i)return;const n=new Set([new Date(t).toISOString().slice(0,7),new Date(e).toISOString().slice(0,7)]);return[...n].some(a=>a>=i.index.from&&a<=i.index.to)?(await Promise.all([...n].filter(a=>i.index.months.includes(a)).map(a=>this.monthOf(a,i.base)))).flat().filter(a=>a.t>=t&&a.t<=e):void 0}static seenFrom(t,e){const i=hs.peakFraction(t),n={lat:t.from[0]+(t.to[0]-t.from[0])*i,lng:t.from[1]+(t.to[1]-t.from[1])*i,heightM:t.peakHeightKm*1e3},s=me.seenFrom(e,n);if(!(s.altitudeDeg<0))return{record:t,peak:s,magnitude:t.peakMagnitude+5*Math.log10(s.distanceKm/me.STANDARD_DISTANCE_KM)}}static asReentry(t,e){const i=t.t-e,n=i+Math.max(t.durationS,.1)*1e3;return{id:`gmn-${t.id}`,track:[{t:i,lat:t.from[0],lng:t.from[1],altitudeKm:t.from[2]},{t:n,lat:t.to[0],lng:t.to[1],altitudeKm:t.to[2]}],fragments:[{absoluteMagnitude:t.peakMagnitude,color:hs.COLOR,trainS:hs.TRAIN_S}]}}static peakFraction(t){const e=t.from[2]-t.to[2];return Math.abs(e)<1e-6?.5:Math.min(1,Math.max(0,(t.from[2]-t.peakHeightKm)/e))}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}monthOf(t,e){let i=this.months.get(t);return i||(i=this.fetchImpl(new URL(`${t}.json`,e).href).then(n=>n.ok?n.json():[]).catch(()=>[]),this.months.set(t,i)),i}}const _r=Math.PI/180,Ro=180/Math.PI;class si{constructor(t){this.timeline=t}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(t,e,i,n){const s=[];for(const a of e){const o=si.projectionOf(a,i,n?.(a));if(o)for(const c of a.explains){const l=this.timeline.getInterpolatedShapeAt(t,c);!l||l.transparency>=1||s.push({...si.compare(c,a.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(t,e,i,n){const s=[],a=i.aim?si.separationDeg(i.aim,n.aim):void 0;if(a!==void 0){const l=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;a>Math.max(si.DIRECTION_TOLERANCE_DEG,l)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,c=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!si.withinSize(o)&&s.push("width"),c!==void 0&&!si.withinSize(c)&&s.push("height"),{sourceId:t,bodyId:e,stated:i,predicted:n,separationDeg:a,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(t,e,i){const n=i&&i.length>0?i:si.outlineOf(t),s=i&&i.length>0?si.centreOf(i):t,a=si.normalized({eastM:s.eastM-e.eastM,northM:s.northM-e.northM,upM:s.upM-e.upM});if(!a)return;const o=si.normalized({eastM:a.northM,northM:-a.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=si.cross(o,a);let l=1/0,h=-1/0,u=1/0,d=-1/0;for(const f of n){const p={eastM:f.eastM-e.eastM,northM:f.northM-e.northM,upM:f.upM-e.upM},v=si.dot(p,a);if(v<=0)return;const m=Math.atan2(si.dot(p,o),v),g=Math.atan2(si.dot(p,c),v);l=Math.min(l,m),h=Math.max(h,m),u=Math.min(u,g),d=Math.max(d,g)}return{aim:{azimuthDeg:(Math.atan2(a.eastM,a.northM)*Ro+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,a.upM)))*Ro},angular:{widthDeg:(h-l)*Ro,heightDeg:(d-u)*Ro}}}static centreOf(t){const e=i=>(Math.min(...t.map(n=>n[i]))+Math.max(...t.map(n=>n[i])))/2;return{eastM:e("eastM"),northM:e("northM"),upM:e("upM")}}static separationDeg(t,e){const i=t.altitudeDeg*_r,n=e.altitudeDeg*_r,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((t.azimuthDeg-e.azimuthDeg)*_r);return Math.acos(Math.max(-1,Math.min(1,s)))*Ro}static withinSize(t){return t<=si.SIZE_TOLERANCE&&t>=1/si.SIZE_TOLERANCE}static outlineOf(t){const e=t.sizeM.widthM/2,i=t.sizeM.lengthM/2,n=t.sizeM.heightM/2,s=[],a=t.model.url===void 0?t.model.id:void 0;if(a!==void 0&&a!=="box"&&nv.includes(a))for(let u=0;u<=si.RINGS;u++){const d=u/si.RINGS*Math.PI;for(let f=0;f<si.SEGMENTS;f++){const p=f/si.SEGMENTS*2*Math.PI;s.push([e*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-e,e])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=t.attitude.headingDeg*_r,l=t.attitude.pitchDeg*_r,h=t.attitude.rollDeg*_r;return s.map(([u,d,f])=>{const p=u*Math.cos(h)+f*Math.sin(h),v=-u*Math.sin(h)+f*Math.cos(h),m=d*Math.cos(l)-v*Math.sin(l),g=d*Math.sin(l)+v*Math.cos(l);return{eastM:t.eastM+p*Math.cos(c)+m*Math.sin(c),northM:t.northM-p*Math.sin(c)+m*Math.cos(c),upM:t.upM+g}})}static dot(t,e){return t.eastM*e.eastM+t.northM*e.northM+t.upM*e.upM}static cross(t,e){return{eastM:t.northM*e.upM-t.upM*e.northM,northM:t.upM*e.eastM-t.eastM*e.upM,upM:t.eastM*e.northM-t.northM*e.eastM}}static normalized(t){const e=Math.hypot(t.eastM,t.northM,t.upM);return e>1e-9?{eastM:t.eastM/e,northM:t.northM/e,upM:t.upM/e}:void 0}}Ng();const dA={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},fA="{name} — mag {mag}, {alt}° above the horizon",pA="{name} — satellite, mag {mag}, {height} km up",mA="satellites-change",gA="fireballs-change",vA="aircraft-change",MA="rr0-confrontation",xA="{name} — mag {mag}, {alt}° below the horizontal",Uu="Credits",gg="comet:",vg="nova:",yA={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",crop:"Crop row",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},_A=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,SA=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,bA=-18,wA={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},ku={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class Ve extends HTMLElement{creditsButton;set ownCredits(t){this.creditsButton.hidden=!t}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",Lr,Or]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new Li;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;static fireballArchive=new hs;fireballs;static aircraftProviders=new Map;static SOUND_LOOKBACK_MS=3e5;static NO_CONTRAILS=[];static upperAirProviders=new Map;static NO_PRESENCE=new Map;aircraftSource=uA[0];static trafficRuntimeLoading;static trafficRuntime;static loadTrafficRuntime(){return Ve.trafficRuntimeLoading??=an(()=>import("./trafficRuntime-_pIg6nkw.js"),__vite__mapDeps([2,1]),import.meta.url).then(t=>Ve.trafficRuntime=t),Ve.trafficRuntimeLoading.catch(()=>{Ve.trafficRuntimeLoading=void 0}),Ve.trafficRuntimeLoading}traffic;lastSun;decorMemo;starCatalogDepth=0;weatherAudio=new nA;vehicleAudio=new Mv;aircraftAudio;vehicleHearing=new Al;animateWhilePausedValue=!1;set animateWhilePaused(t){t!==this.animateWhilePausedValue&&(this.animateWhilePausedValue=t,this.syncAnimationsToPlayback())}get animateWhilePaused(){return this.animateWhilePausedValue}thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=t=>{this.sceneRenderer.setCompassHovered(!0);const e=this.ufoElement.canvasElement,i=e.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(t.clientX-i.left)/i.width*e.width,s=(t.clientY-i.top)/i.height*e.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const a=(t.clientX-i.left)/i.width*2-1,o=-((t.clientY-i.top)/i.height*2-1),c=this.naming,l=c.names,h=this.sceneRenderer.pickBodyAt(a,o);if(h){this.showHoverTooltip(t,this.bodyName(h));return}const u=this.sceneRenderer.pickDecorAt(a,o),d=u?this.ufoElement.sighting.decor.find(m=>m.id===u):void 0;if(d){this.showHoverTooltip(t,this.said.read(d.title)||c.decorKind(d.kind,yA[d.kind]));return}const f=this.trafficTooltipAt(a,o);if(f){this.showHoverTooltip(t,f);return}const p=this.sceneRenderer.pickSatelliteAt(a,o);if(p){this.showHoverTooltip(t,(l?.satelliteTooltip??pA).replace("{name}",p.name).replace("{mag}",p.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(p.heightKm).toLocaleString()));return}const v=this.sceneRenderer.pickStarAt(a,o);if(v){const m=v.star.mag,g=v.altitudeDeg,_=g<0?l?.starTooltipBelow??xA:l?.starTooltip??fA;this.showHoverTooltip(t,_.replace("{name}",c.star(v.star)).replace("{mag}",m.toLocaleString(void 0,{maximumFractionDigits:Math.abs(m)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(g)))));return}this.hoverTooltip.hidden=!0};bodyName(t){const e=t.startsWith(gg)?t.slice(gg.length):void 0,i=e?rv.find(a=>a.id===e):void 0;if(i)return this.naming.comet(i);const n=t.startsWith(vg)?dg.byId(t.slice(vg.length)):void 0;if(n)return this.naming.nova(n);const s=dA[t];return s===void 0?t:this.naming.body(t,s)}get naming(){return this.sceneNaming}sceneNaming=new ug;namesLanguage="en";async loadSceneNames(){const t=bg(Pr.preferencesFor(this),wg);if(t===this.namesLanguage)return;this.namesLanguage=t;const e=await r2(t);t===this.namesLanguage&&this.applySceneNaming(new ug(e))}renderLoaderText(t,e){let i=0;const n=(s,a)=>{s.setAttribute("aria-label",a),s.replaceChildren(),a.split(" ").forEach((o,c)=>{c>0&&s.append(" ");const l=document.createElement("span");l.className="scene-loader-word",l.setAttribute("aria-hidden","true");for(const h of o){const u=document.createElement("span");u.className="scene-loader-letter",u.style.setProperty("--i",String(i++)),u.textContent=h,l.append(u)}s.append(l),i++})};n(this.loaderNotVideo,t),i+=6,n(this.loaderNote,e)}applySceneNaming(t){this.sceneNaming=t;const e=t.names?.credits??Uu;this.creditsButton.title=e,this.creditsButton.setAttribute("aria-label",e),t.names&&this.renderLoaderText(t.names.notAVideo,t.names.isASimulation),this.sceneRenderer.setCompassPoints(t.names?.compassPoints)}showHoverTooltip(t,e){this.hoverTooltip.textContent=e,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${t.clientX-i.left+12}px`,this.hoverTooltip.style.top=`${t.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(t){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),gi.thunderDelayMs(t))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(uc(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;handlePageGesture=()=>{this.ufoElement.playbackState==="playing"&&this.handleFirstInteraction()};unlockIfAlreadyActivated(){this.interacted||navigator.userActivation?.hasBeenActive&&this.handleFirstInteraction()}static GESTURES=["pointerdown","pointerup","touchend","click","keydown"];handleTimeUpdate=t=>{this.lastTimeMs=t.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now())};syncAnimationsToPlayback(){const t=this.ufoElement.playbackState==="playing",e=t||this.animateWhilePaused;this.sceneRenderer.setAnimationsRunning(e,t),this.weatherAudio.setPaused(!t),this.vehicleAudio.setPaused(!t),this.aircraftAudio?.setPaused(!t),t&&this.unlockIfAlreadyActivated(),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${bv}</style>${Sv}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.frameElement=this.shadow.getElementById("frame"),this.sceneCanvas=this.shadow.getElementById("scene-canvas"),this.sceneRenderer=new Se(this.sceneCanvas);const e=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.renderLoaderText("This is not a video","It is a real-time simulation."),this.sceneRenderer.onFirstFrameHold=s=>{e.hidden=!s,this.ufoElement.captionHeld=s},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(Hu),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.detail)),this.ufoElement.style.setProperty("--ufo-canvas-background","transparent"),this.ufoElement.style.setProperty("--ufo-canvas-border","none"),this.ufoElement.fullscreenTarget=this.stageElement,this.shadow.getElementById("ufo-slot").replaceWith(this.ufoElement),this.ufoElement.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&tn.fill(n,this)}),this.creditsButton.title=Uu,this.creditsButton.setAttribute("aria-label",Uu),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,a)=>this.seekPreviewOf(a).paint(s,a),this.ufoElement.addEventListener("mutedchange",()=>this.weatherAudio.setLevel(this.ufoElement.level)),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.addEventListener("traceview",s=>this.sceneRenderer.setTracesShown(s.detail.shown)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of Ve.GESTURES)this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Rs(Pr.preferencesFor(this))}saidTexts;traceLabelsFor;traceLabels(t){const e=Pr.preferencesFor(this).join();if(this.traceLabelsFor?.traces!==t||this.traceLabelsFor.language!==e){const i=new Map;for(const n of t){const s=this.said.read(n.title);s&&i.set(n.id,s)}this.traceLabelsFor={traces:t,language:e,labels:i}}return this.traceLabelsFor.labels}connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),document.addEventListener("fullscreenchange",this.handleFullscreenChange);for(const e of Ve.GESTURES)document.addEventListener(e,this.handlePageGesture,!0);const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange);for(const t of Ve.GESTURES)document.removeEventListener(t,this.handlePageGesture,!0);this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),this.vehicleAudio.dispose(),this.aircraftAudio?.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),(t==="star-catalog-src"||t==="deep-star-catalog-src")&&i!==e&&this.isConnected&&this.loadStars(),t==="show-compass"&&i!==e&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),t==="max-pixel-ratio"&&i!==e){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(t===Lr||t===Or)&&i!==e&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const t of[Lr,Or]){const e=this.getAttribute(t);e===null?this.ufoElement.removeAttribute(t):this.ufoElement.setAttribute(t,e)}}setCompassForced(t){this.sceneRenderer.setCompassForced(t)}lookToward(t){const e=Ze(this.ufoElement.sighting,this.lastTimeMs);if(t.kind==="observer"||e?.lat===void 0||e.lng===void 0||e.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=Je(t.lat,t.lng,e.lat,e.lng);if(Math.hypot(i,n)<1)return this.setLookOffset(0,0);const s=(Math.atan2(i,-n)*180/Math.PI+360)%360;this.setLookOffset(((s-e.headingDeg)%360+540)%360-180,-e.pitchDeg)}setLookOffset(t,e){this.sceneRenderer.setLookOffset(t,e),this.ufoElement.setLookOffset(t,e),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(t,e){this.sceneRenderer.setIndoorLook(t,e)}setCloudRendering(t){this.sceneRenderer.setCloudRendering(t)}setWeather(t){this.sceneRenderer.setWeather(t),this.weatherAudio.setAmbient(t.precipitationType,t.precipitationIntensity*(t.precipitationAmount??1),t.windSpeed)}pickCloudAt(t,e){return this.sceneRenderer.pickCloudAt(t,e)}cloudDirectionAt(t,e){return this.sceneRenderer.cloudDirectionAt(t,e)}pickDecorAt(t,e){return this.sceneRenderer.pickDecorAt(t,e)}bodyScreenBox(t){return this.sceneRenderer.bodyScreenBox(t)}pickPlacedBodyAt(t,e){return this.sceneRenderer.pickPlacedBodyAt(t,e)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume()}async loadFromSrc(t){const e=_g.json(t);this.holdForNewScene(e);const i=await e;this.documentUrl=new URL(t,location.href).href,this.sightingData=i}holdForNewScene(t){this.sceneRenderer.holdForNewScene(t)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(t){this.sceneRenderer.documentUrl=t}get sightingData(){return this.ufoElement.sightingData}set sightingData(t){this.ufoElement.sightingData=t,this.seekPreview?.recordingChanged(t),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(t){const e=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(t.width/e);return t.height!==i&&(t.height=i),this.seekPreview??=new Kl(this,()=>document.createElement(h0))}showAt(t){this.ufoElement.currentTime=t,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(t){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const e=t.getContext("2d");return e?(e.drawImage(this.sceneCanvas,0,0,t.width,t.height),!0):!1}referenceAspect(t){return this.sceneRenderer.referenceAspect(t)}screenPointOf(t){return this.sceneRenderer.screenPointOf(t)}directionAt(t,e){return this.sceneRenderer.directionAt(t,e)}referenceFailedToLoad(t){return this.sceneRenderer.referenceFailedToLoad(t)}applyReferenceView(t){this.sceneRenderer.setReferencesShown(t.shown);for(const e of this.ufoElement.sighting.references)this.sceneRenderer.setReferenceView(e.id,{opacity:t.opacity})}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}setTerrainProviders(t){this.sceneRenderer.setTerrainProviders(t)}setDecorModelProvider(t){this.sceneRenderer.setDecorModelProvider(t)}get decorModelCredits(){return this.sceneRenderer.currentDecorModelCredits}applyFrameFormat(){const t=this.ufoElement.sighting.instrument,e=De.CANVAS_HEIGHT_PX,i=mi.frameWidthPx(t,e);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${e}`)}resizeToStage(){const t=this.frameElement.getBoundingClientRect(),e=Math.max(1,Math.round(t.width)),i=Math.max(1,Math.round(t.height));this.sceneCanvas.width=e,this.sceneCanvas.height=i,this.sceneRenderer.resize(e,i)}async loadStars(){const t=[{magnitudeLimit:Pu,url:this.getAttribute("star-catalog-src")??_A},{magnitudeLimit:Lu,url:this.getAttribute("deep-star-catalog-src")??SA}],e=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=e>Pu?Lu:Pu;const n=await is.upTo(t,e);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Lu||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const t=this.ufoElement.sighting,e=Hi.gainFor(t.instrument,{fNumber:Ze(t,0)?.fNumber,fieldOfViewDeg:sn.fovOf(t,0),exposureSeconds:t.exposure});return bl(bA,e)}updateAstronomy(t){this.ensureStarsDeepEnough(),this.applySceneAt(t);const e=zn.windowEndingAt(t,this.exposureSeconds()),i=e.seconds,n=this.degreesPerPixelAt(t),s=Ha.instants(i,n),a=Math.max(s,this.ufoElement.exposureTimes(t).length,zn.instants(this.decorWithTraffic(this.ufoElement.sighting),Ze(this.ufoElement.sighting,t)?.elevationM??0,e.fromMs,i,n));if(a<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(a,o=>this.applySceneAt(e.fromMs+e.ms*o/(a-1),{sky:Math.floor(o*s/a)!==Math.floor((o-1)*s/a),stepMs:e.ms/a}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(t){const e=this.sceneCanvas.height;return e<=0?0:sn.fovOf(this.ufoElement.sighting,t)/e}applySceneAt(t,e){const i=this.ufoElement.sighting;this.setWeather(uc(i,t)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),e||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,t)),e||this.pushAircraftSound(i,t),this.updateMeteorShower(i,t),this.updateLightning(i,t,e!==void 0),this.sceneRenderer.setDecor(this.decorWithTraffic(i)),this.sceneRenderer.setDecorPresence(this.traffic?.set?.presence??Ve.NO_PRESENCE),this.sceneRenderer.setDecorSunlight(this.trafficSunlight(t)),this.sceneRenderer.setContrails(this.traffic?.contrails??Ve.NO_CONTRAILS),this.sceneRenderer.setContrailSunlight(this.contrailSunlight(t));const n=Ze(i,t);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=Ze(i,0),a=eo(i,0),o=Object.fromEntries(Tl(eo(i,t)).map(M=>[M.id,Mf(t,i.weatherTrack,a,s,n,M.id)]));this.sceneRenderer.setCloudOffset(Mf(t,i.weatherTrack,a,s,n),o),this.sceneRenderer.setObserverPose(n??ku),this.sceneRenderer.setLensOptics(this.lensOpticsAt(t)),this.sceneRenderer.setInstrumentGain(Hi.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:sn.fovOf(i,t),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(be.bodyAt(i,t,this.ufoElement.steadyObserver)),this.sceneRenderer.updateDecorAnchoring(Ze(i,0),n,t),this.placeBodiesAt(t,e===void 0),this.sceneRenderer.updateDecorLitState(t,e?.stepMs??0),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng,()=>{this.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.sceneRenderer.setTraces(i.traces,this.traceLabels(i.traces)),this.pushPhenomenaAt(t);const c=n?.lat??ku.lat,l=n?.lng??ku.lng,h=yo(i.event.time??{},l,i.event.utcOffsetHours),u={lat:c,lng:l,elevationM:n?.elevationM??0};this.pushSatellitesAt(h,t,u),this.ensureFireballs(h);const d=[...this.interpretationShown?.reentries??[],...this.fireballs?.reentries??[]];if(this.sceneRenderer.setReentries(d.length===0?[]:me.viewsAt(d,t,{lat:c,lng:l,heightM:u.elevationM})),e&&!e.sky)return;if(!h){this.sceneRenderer.setAstronomy(wA);return}const f=new Date(h.getTime()+t),p=Math.max(1,Math.round(.25*this.degreesPerPixelAt(t)/Ha.DEG_PER_SECOND*1e3)),v=Math.max(1e-8,this.degreesPerPixelAt(t)*.1),m=`${Math.floor(f.getTime()/p)}|${Math.round(c/v)}|${Math.round(l/v)}|${Math.round(u.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(m===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=m;const g={...tl("Sun",f,u),magnitude:cu("Sun",f)};this.lastSun={altitudeDeg:g.altitudeDeg,azimuthDeg:g.azimuthDeg};const _={...tl("Moon",f,u),phase:Qw(f),magnitude:cu("Moon",f)},y=jw.map(M=>({body:M,position:tl(M,f,u),magnitude:cu(M,f)}));this.sceneRenderer.setAstronomy({sun:g,moon:_,planets:y,comet:this.cometAt(f,u),novae:dg.appearancesAt(f,u).map(({outburst:M,position:b,magnitude:w})=>({id:M.id,position:b,magnitude:w})),stars:this.starCatalog?{catalog:this.starCatalog,date:f,observer:u}:void 0,frame:{date:f,observer:u}}),this.ufoElement.setSunAltitude(g.altitudeDeg)}pushSatellitesAt(t,e,i){if(this.ensureSatellites(t),!t||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(t.getTime()+e),s=[];for(const a of this.satellites.passes.positionsAt(n,i,-1))a.magnitude!==void 0&&s.push({norad:a.object.norad,name:a.object.name,position:{altitudeDeg:a.altitudeDeg,azimuthDeg:a.azimuthDeg},magnitude:a.magnitude,heightKm:a.heightKm});this.sceneRenderer.setSatellites(s)}ensureFireballs(t){const e=this.ufoElement.sighting,i=Math.max((e.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),n=t?.getTime(),s=n===void 0?"":`${n}+${i}`;if(this.fireballs?.key===s)return;if(n===void 0||!hs.mayCover(n+i)){this.fireballs={key:s,status:"outside",reentries:[]};return}const a={key:s,status:"loading",reentries:[]};this.fireballs=a,Ve.fireballArchive.between(n,n+i).then(o=>{a.status=o?"ready":"unavailable",a.records=o??[],a.reentries=a.records.map(c=>hs.asReentry(c,n)),!(this.fireballs!==a||!this.isConnected)&&(this.dispatchEvent(new CustomEvent(gA)),a.reentries.length>0&&this.updateAstronomy(this.lastTimeMs))})}decorWithTraffic(t){const e=this.ensureTraffic(t);if(!e||e.objects.length===0)return t.decor;const i=this.decorMemo;if(i&&i.base===t.decor&&i.traffic===e.objects)return i.merged;const n=[...t.decor,...e.objects];return this.decorMemo={base:t.decor,traffic:e.objects,merged:n},n}ensureTraffic(t){const e=Ze(t,0),i=e?.lng===void 0?void 0:yo(t.event.time??{},e.lng,t.event.utcOffsetHours),n=Math.max((t.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),s=i?.getTime(),a=s===void 0||e?.lat===void 0||e.lng===void 0?"":`${this.aircraftSource.id}|${s}+${n}|${e.lat.toFixed(3)},${e.lng.toFixed(3)}|${Math.round(e.elevationM??0)}`;if(this.traffic?.key===a)return this.traffic.set;if(a===""||s===void 0||e?.lat===void 0||e.lng===void 0){this.traffic={key:a,status:"outside"};return}let o=Ve.aircraftProviders.get(this.aircraftSource.id);if(o||Ve.aircraftProviders.set(this.aircraftSource.id,o=this.aircraftSource.create()),o.mayCover&&!o.mayCover(s+n)){this.traffic={key:a,status:"outside"};return}const c={key:a,status:"loading",startMs:s,observer:{lat:e.lat,lng:e.lng}};this.traffic=c;const l={lat:e.lat,lng:e.lng,heightM:e.elevationM??0},h=Gi.MAX_GAP_S*1e3,u=Ve.SOUND_LOOKBACK_MS,d={lat:e.lat,lng:e.lng,elevationM:e.elevationM??0},f=(p,v)=>p.TrafficDecor.from(c.tracks??[],l,s,p.TrafficDecor.MAX_OBJECTS,{models:v,sunElevationAt:m=>this.sunElevationAt(m,d)});o.between(l,s-u,s+n+h).then(async p=>{if(this.traffic!==c)return;if(p.status!=="found"){c.status=p.status==="outside"?"outside":"unavailable",this.announceTraffic();return}let v;try{v=await Ve.loadTrafficRuntime()}catch{this.traffic===c&&(c.status="unavailable",this.announceTraffic());return}this.traffic===c&&(c.status="ready",c.tracks=p.tracks,c.set=f(v),this.startAircraftSound(c,v),this.announceTraffic(),this.describeTraffic(o,c,v,f),c.set.shown>0&&this.readUpperAir(c,v,s-u,s+n+h))})}trafficSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||i.startMs===void 0||!i.observer)return e;for(const[a,o]of n.presence){if(t<o.fromMs||t>o.untilMs)continue;const c=n.flights.get(a),l=c?Gi.positionAt(c,i.startMs+t):void 0;l&&e.set(a,{heightM:l.geo.heightM,sunElevationDeg:gn.sunElevationDeg(s,i.observer,l.geo)})}return e}trafficTooltipAt(t,e){const i=this.sceneRenderer.pickTrafficAt(t,e),n=i?this.trafficInfoAt(i):void 0;if(!n)return;const s=this.naming,a=Ve.trafficRuntime;return a?.TrafficTooltip.text(n,s.names?.trafficTooltip??a.TrafficTooltip.ENGLISH,o=>s.towards(o))}trafficInfoAt(t){const e=this.traffic,i=e?.set?.flights.get(t);if(!e||!i||e.startMs===void 0||!e.observer)return;const n=Ve.trafficRuntime;if(!n)return;const s=e.descriptions?.get(Bn.keyOf(i)),a=Ze(this.ufoElement.sighting,this.lastTimeMs),o={lat:e.observer.lat,lng:e.observer.lng,heightM:a?.elevationM??0},c=n.AmbientNoise.dbA(uc(this.ufoElement.sighting,this.lastTimeMs)),l=n.TrafficInfos.at(i,s,o,e.startMs+this.lastTimeMs,{ambientDbA:c}),h=l&&this.contrailAt(t,this.lastTimeMs);return l&&h?{...l,contrail:h}:l}contrailAt(t,e){const i=this.traffic?.contrails?.find(s=>s.id===t);if(!i)return;let n;for(const s of i.points){if(s.tMs>e)break;n=s}return n?.forms?{persistent:n.persistent,iceRelativeHumidity:n.iceRelativeHumidity}:void 0}startAircraftSound(t,e){this.aircraftAudio||(this.aircraftAudio=new e.AircraftAudio,this.interacted&&this.aircraftAudio.resume(),this.aircraftAudio.setPaused(this.ufoElement.playbackState!=="playing")),this.sortOutAudible(t,e)}sortOutAudible(t,e){!t.set||!t.observer||(t.audible=e.TrafficSound.candidates(t.set.flights,t.descriptions??new Map,Bn.keyOf,{...t.observer,heightM:0},{ambientDbA:e.AmbientNoise.BASE_DB_A}))}pushAircraftSound(t,e){const i=this.aircraftAudio;if(!i)return;const n=Ve.trafficRuntime,s=this.traffic,a=s?.set;if(!n||!s||!a||!s.audible||s.startMs===void 0||!s.observer){i.setVoices([]);return}const o=Ze(t,e),c={lat:s.observer.lat,lng:s.observer.lng,heightM:o?.elevationM??0},l=uc(t,e),h=n.TrafficSound.voices(s.audible,a.flights,s.descriptions??new Map,Bn.keyOf,c,s.startMs+e,{ambientDbA:n.AmbientNoise.dbA(l),referenceAmplitude:n.AmbientNoise.referenceAmplitude(l)});i.setVoices(h,o?.headingDeg??0)}announceTraffic(){this.isConnected&&(this.dispatchEvent(new CustomEvent(vA)),this.updateAstronomy(this.lastTimeMs))}async describeTraffic(t,e,i,n){if(!t.describe||!e.set||!e.tracks)return;const s=new Set([...e.set.flights.values()].map(l=>Bn.keyOf(l))),a=e.tracks.filter(l=>s.has(Bn.keyOf(l))&&l.points.length>0),o=new Map,c=new Map;await Promise.all(a.map(async l=>{const h=new Date(l.points[0].t).toISOString().slice(0,10),u=await t.describe(l,h).catch(()=>{});u&&(c.set(Bn.keyOf(l),u),o.set(Bn.keyOf(l),i.AircraftModels.of(u)))})),!(this.traffic!==e||o.size===0)&&(e.descriptions=c,e.models=o,e.set=n(i,o),this.planContrails(e,i),this.sortOutAudible(e,i),this.announceTraffic())}async readUpperAir(t,e,i,n){if(!t.observer)return;const s=this.upperAirSource??e.UPPER_AIR_SOURCES[0];let a=Ve.upperAirProviders.get(s.id);a||Ve.upperAirProviders.set(s.id,a=s.create());const o=await a.between(t.observer,i,n);this.traffic!==t||o.status!=="found"||(t.air=o.samples,t.airSource=o.source,this.planContrails(t,e),this.announceTraffic())}planContrails(t,e){!t.set||!t.air||t.startMs===void 0||(t.contrails=e.AircraftContrails.plan(t.set,t.models,t.air,t.startMs))}contrailSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||!i.contrails?.length||i.startMs===void 0||!i.observer)return e;for(const a of i.contrails){const o=n.presence.get(a.id),c=n.flights.get(a.id);if(!o||!c)continue;const l=Gi.positionAt(c,i.startMs+Math.min(o.untilMs,Math.max(o.fromMs,t)));l&&e.set(a.id,{heightM:l.geo.heightM,sunElevationDeg:gn.sunElevationDeg(s,i.observer,l.geo)})}return e}sunElevationAt(t,e){const i=tl("Sun",new Date(t.t),e);return gn.sunElevationDeg(i,e,t)}upperAirSource;setUpperAirSource(t){t.id!==this.upperAirSource?.id&&(this.upperAirSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}setAircraftSource(t){t.id!==this.aircraftSource.id&&(this.aircraftSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}get aircraftState(){const t=this.traffic?.contrails?.length?this.upperAirSource??Ve.trafficRuntime?.UPPER_AIR_SOURCES[0]:void 0;return{trailCredit:t&&{credit:t.credit,creditUrl:t.creditUrl},status:this.traffic?.status??"none",total:this.traffic?.set?.total??0,shown:this.traffic?.set?.shown??0,credit:this.aircraftSource.credit,creditUrl:this.aircraftSource.creditUrl}}get fireballState(){return{status:this.fireballs?.status??"none",records:this.fireballs?.records??[]}}ensureSatellites(t){const e=t?String(t.getTime()):"";if(e===this.satellitesFor)return;this.satellitesFor=e,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!t){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=a=>{i===this.satelliteRequest&&(this.satelliteStatus=a,this.isConnected&&this.dispatchEvent(new CustomEvent(mA)))},s=Ve.tleArchive;(async()=>{if(!await s.covers(t))return n("outside");const[a,o]=await Promise.all([s.at(t),an(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!a)return n("unavailable");this.satellites={snapshot:a,passes:new o.SatellitePasses(a.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const t=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:t?.coverage,credit:t?.credit,creditUrl:t?.creditUrl}}satellitePassesDuring(t){const e=this.satellites,i=this.ufoElement.sighting,n=Ze(i,0),s=i.event.place?.[0],a=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!e||a===void 0||o===void 0)return[];const c=yo(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(t,0),4*36e5),h={lat:a,lng:o,elevationM:n?.elevationM??0},u=JSON.stringify([this.satellitesFor,c.getTime(),a,o,h.elevationM,l]);if(this.satellitePassesMemo?.key===u)return this.satellitePassesMemo.passes;const d=Math.max(10,Math.ceil(l/1e3/600)),f=e.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(t,e){const i=sA.brightestAt(t,e);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(t){const e=this.ufoElement.sighting;e!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=e);const i=e.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,a=this.projectionAt(t),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(t,p);if(!v)continue;const m={...v,bounds:{...v.bounds,x:v.bounds.x+s.x,y:v.bounds.y+s.y}};o.set(p,m);const g=v.aim?this.sceneRenderer.screenPointOf(kn.directionOf(v.aim,this.directionScratch)):{ndcX:(m.bounds.x+m.bounds.width/2)/n.width*2-1,ndcY:-((m.bounds.y+m.bounds.height/2)/n.height*2-1)},_=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,y=_?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(_||v.aim)&&l.delete(p);const M=v.angular?.widthDeg??a.pxToDeg(v.bounds.width),b=this.sizeEstimateOf(p);b.add(M,y);const w=Ho.of(e,p);c.set(p,Bi.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:w&&M>0?De.distanceMAt(w.widthM,M):void 0,range:b.distanceRangeAt(M),crossing:y}))}for(const[p,v]of o)for(const[m,g]of o){if(m===p||g.transparency>=1||g.bounds.width*g.bounds.height<=v.bounds.width*v.bounds.height||!(v.bounds.x>=g.bounds.x&&v.bounds.y>=g.bounds.y&&v.bounds.x+v.bounds.width<=g.bounds.x+g.bounds.width&&v.bounds.y+v.bounds.height<=g.bounds.y+g.bounds.height))continue;const y=c.get(m);y&&c.set(p,{distanceM:y.distanceM*.999,basis:y.basis});break}this.depths=c;const h=i.sourceIds,u=[];for(const[p,v]of o)u.push({sourceId:p,shape:v,distanceM:c.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:l.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(Ze(e,t)?.rollDeg??0)+be.bodyAt(e,t,this.ufoElement.steadyObserver).rollDeg;this.sceneRenderer.setPhenomena(u,{projection:a,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:mi.starPointsOf(e.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(t){this.interpretationShown=t,this.updateAstronomy(this.lastTimeMs)}get accountInTheRound(){return this.inTheRound}set accountInTheRound(t){this.inTheRound=t}get compareAccount(){return this.comparing}set compareAccount(t){this.comparing=t,this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(t,e,i){const n=this.sceneRenderer.bodyGround,s=ie.eyeOf(this.ufoElement.sighting,i,n);return s?ie.lineOfSightMeetsGround(s,t,e,n):void 0}bodyReading(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=d=>ie.eyeOf(n,d,i),a=new ie(t,i,s).at(e),o=s(e);if(!a||!o)return;const c=a.eastM-o.eastM,l=a.northM-o.northM,h=a.upM-o.upM,u=Math.hypot(c,l);return{azimuthDeg:(Math.atan2(c,l)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,u)*180/Math.PI,distanceM:Math.hypot(u,h),eastM:a.eastM,northM:a.northM,aboveGroundM:a.upM-a.sizeM.heightM/2-i.heightAt(a.eastM,a.northM),sizeM:a.sizeM,attitude:a.attitude,appearance:a.appearance}}directionToBody(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>ie.eyeOf(n,p,i),a=new ie(t,i,s),o=a.at(e)?e:t.track[0]?.t,c=o===void 0?void 0:a.at(o),l=o===void 0?void 0:s(o);if(!c||!l)return;const h=c.eastM-l.eastM,u=c.northM-l.northM,d=c.upM-l.upM,f=Math.hypot(h,u);if(!(f===0&&d===0))return{azimuthDeg:(Math.atan2(h,u)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(d,f)*180/Math.PI}}placeBodiesAt(t,e){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],a=[];const o=this.sceneRenderer.bodyGround,c=p=>ie.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new ie(p,o,c).at(t)).filter(p=>p!==void 0));const l=eo(n,t),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,t/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(t):void 0;if(d&&(a=new si(n.timeline).at(t,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=a,!e)return;const f=JSON.stringify(a);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(MA,{detail:a})))}setDistanceHypothesis(t,e){e===void 0||!(e>0)?this.distanceHypotheses.delete(t):this.distanceHypotheses.set(t,e),this.updateAstronomy(this.lastTimeMs)}depthOf(t){return this.depths.get(t)}sizeRangeOf(t){return this.sizeEstimateOf(t).sizeRange}distanceRangeAt(t,e){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(e,t);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(e).pxToDeg(i.bounds.width);return this.sizeEstimateOf(t).distanceRangeAt(n)}sizeContradictory(t){return this.sizeEstimateOf(t).contradictory}updateMeteorShower(t,e){this.ensureMeteorSchedule(t),this.sceneRenderer.updateMeteors(e)}updateLightning(t,e,i){if(this.ensureLightningSchedule(t),this.sceneRenderer.updateLightning(e),i)return;const n=this.lastLightningT;if(this.lastLightningT=e,n===void 0||e<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(a=>a.t>n&&a.t<=e).pop();s&&eo(t,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(t){const e=eo(t,0).precipitationIntensity,i=`${this.meteorInputsOf(t)}|${e}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=t.event.time,s=t.event.place?.[0],a=n?.year!==void 0?yo(n,s?.lng??0,t.event.utcOffsetHours):void 0,o=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,c=Math.round((a?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=gi.schedule({durationMs:o,seed:c,intensity:e}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(t){const e=this.meteorInputsOf(t);e!==this.meteorScheduleFor&&(this.meteorScheduleFor=e,this.scheduleMeteors(t))}meteorInputsOf(t){const e=t.event.place?.[0],i=t.event.time;return JSON.stringify([e?.lat,e?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,t.event.utcOffsetHours,t.event.durationSeconds,t.timeline.duration])}scheduleMeteors(t){const e=t.event.place?.[0],i=t.event.time,n=e?.lat!==void 0&&e.lng!==void 0&&i?.year!==void 0?yo(i,e.lng,t.event.utcOffsetHours):void 0;if(!n||e?.lat===void 0||e.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:e.lat,lng:e.lng,elevationM:0},a=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(e.lat*1e3),c=ai.schedule({ratePerHour:ai.observedRatePerHour(ai.apexPosition(n,s).altitudeDeg),durationMs:a,velocityKmS:ai.TYPICAL_VELOCITY_KM_S,seed:o}),l=Nu.activeAt(n).map(u=>{const d=Nu.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:Nu.observedRatePerHour(u.zhr,d.altitudeDeg,u.shower.populationIndex)}}).sort((u,d)=>d.rate-u.rate)[0];if(!l||l.rate<=0){this.sceneRenderer.setMeteorShower(c,0,0);return}const h=za.schedule({ratePerHour:l.rate,durationMs:a,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(t){this.ensureMeteorSchedule(this.ufoElement.sighting);const e=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,a)=>a.brightness-s.brightness);if(e.length===0)return;const i=e[t%e.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(t){const e=this.ufoElement.sighting,i=e.instrument,n=i.frame,s=Ze(e,t),a=s?.fNumber??i.fNumber;if(!n||a===void 0)return;const o=mi.focalLengthMmFor(i,sn.fovOf(e,t));if(o!==void 0)return{focalLengthMm:o,fNumber:a,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(t){const e=this.ufoElement.sighting;return Is.of(e.instrument,De.CANVAS_HEIGHT_PX,sn.fovOf(e,t))}sizeEstimateOf(t){let e=this.sizeEstimates.get(t);return e||(e=new rA,this.sizeEstimates.set(t,e)),e}}const h0="rr0-scene";function EA(){Ng(),customElements.get(h0)||customElements.define(h0,Ve)}EA();export{FA as $,Fa as A,qi as B,st as C,m2 as D,NA as E,he as F,Ce as G,rx as H,zA as I,Ll as J,Xi as K,GA as L,Tt as M,UA as N,m1 as O,r1 as P,Ip as Q,me as R,Fs as S,Bn as T,nx as U,R as V,OA as W,CA as X,rn as Y,dp as Z,He as _,Gi as a,BA as a0,i1 as a1,Ca as a2,vc as a3,yh as a4,$2 as a5,ce as a6,Ie as a7,Zo as a8,Zu as a9,Ti as aa,Us as ab,tx as ac,Ta as ad,Ae as ae,IA as af,PA as ag,a1 as ah,LA as ai,nn as aj,Yn as ak,s1 as al,wp as am,$M as an,Il as ao,Td as ap,Ei as aq,f1 as ar,O0 as as,N0 as at,oe as au,ha as av,ac as aw,HA as b,Ul as c,ue as d,as as e,Mt as f,pt as g,ae as h,Qt as i,DA as j,ne as k,ss as l,yl as m,ks as n,ho as o,Je as p,Zt as q,yn as r,Yi as s,hA as t,nf as u,AA as v,RA as w,TA as x,rc as y,kA as z};
7845
+ `);let s=is.cache.get(n);return s||(s=Promise.all(i.map(a=>is.load(a.url))).then(a=>a.reduce((o,c)=>is.concat(o,c))),is.cache.set(n,s)),s}static parse(t){const e=t.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=e*Float32Array.BYTES_PER_ELEMENT;return{count:e,ra:new Float32Array(t,0*i,e),dec:new Float32Array(t,1*i,e),mag:new Float32Array(t,2*i,e),ci:new Float32Array(t,3*i,e)}}static concat(t,e){const i=(n,s)=>{const a=new Float32Array(n.length+s.length);return a.set(n,0),a.set(s,n.length),a};return{count:t.count+e.count,ra:i(t.ra,e.ra),dec:i(t.dec,e.dec),mag:i(t.mag,e.mag),ci:i(t.ci,e.ci)}}}class ug{constructor(t){this.names=t}body(t,e){return this.names?.bodies[t]??e}star(t){return this.names?.stars[t.name]??t.name}comet(t){return this.names?.comets[t.id]??t.name}nova(t){return this.names?.novae[t.id]??t.name}satelliteClass(t){return this.names?.satelliteClasses[t.id]??t.name}shower(t){return this.names?.showers[t.id]??t.name}lightRig(t){return this.names?.lightRigs[t.id]??t.name}instrument(t){return this.names?.instruments[t.id]??t.name}decorKind(t,e){return this.names?.decorKinds[t]??e}point(t){return ka.point(t,this.names?.compassPoints)}towards(t){return ka.towards(t,this.names)}}const qE="Global Meteor Network",$E="https://globalmeteornetwork.org/data/",KE="“Thunder” by Jerimee",ZE="https://creativecommons.org/licenses/by/3.0/",JE="CC BY 3.0";class tn{static fill(t,e){t.innerHTML="";const i=h=>t.appendChild(h),n=e.currentTerrainAttribution;n&&i(tn.text(n));const s=e.currentRoadAttribution;s&&i(tn.text(s));const a=e.ufoElement.observerMapCredit;a&&!n?.includes(a)&&i(tn.text(a));for(const h of e.decorModelCredits){const u=h.author?` — ${h.author}`:"",d=document.createElement("li");h.sourceUrl?d.append(tn.link(h.sourceUrl,h.title),document.createTextNode(`${u} (${h.license})`)):d.textContent=`${h.title}${u} (${h.license})`,i(d)}for(const h of e.ufoElement.sighting.references){if(!h.credit)continue;const u=document.createElement("li");h.creditUrl?u.appendChild(tn.link(h.creditUrl,h.credit)):u.textContent=h.credit,i(u)}if(e.ufoElement.sighting.traces.length>0){const h=new Rs(Pr.preferencesFor(e)),u=new Set(e.ufoElement.sighting.traces.map(d=>h.read(d.source)).filter(d=>!!d));for(const d of u)i(tn.text(d))}const o=e.satelliteState;if(o.status==="ready"&&o.credit){const h=document.createElement("li");h.appendChild(tn.link(o.creditUrl??"",o.credit)),i(h)}if(e.fireballState.status==="ready"&&e.fireballState.records.length>0){const h=document.createElement("li");h.append(tn.link($E,qE),document.createTextNode(" (CC BY 4.0)")),i(h)}const c=e.aircraftState;if(c.status==="ready"&&c.shown>0){const h=document.createElement("li");if(h.appendChild(tn.link(c.creditUrl,c.credit)),i(h),c.trailCredit){const u=document.createElement("li");u.appendChild(tn.link(c.trailCredit.creditUrl,c.trailCredit.credit)),i(u)}}const l=tn.text(`${KE} (`);l.append(tn.link(ZE,JE),document.createTextNode(")")),i(l)}static text(t){const e=document.createElement("li");return e.textContent=t,e}static link(t,e){const i=document.createElement("a");return i.href=t,i.target="_blank",i.rel="noopener",i.textContent=e,i}}const jE=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,QE=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,tA=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,eA=20,iA=1;class nA{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",t);return}}Fa.unlock(this.context)}setAmbient(t,e,i){if(this.requested={type:t,intensity:e,windSpeed:i},!this.context)return;this.paused&&(t="none",e=0,i=0);const n=t==="rain"||t==="hail"?t:"none";if(this.ambientVolume=n==="hail"?Math.min(1,e*1.3+.2):n==="rain"?e:0,n!==this.ambientKey){this.ambientKey=n;const a=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,n!=="none"&&this.startLoop(jE,this.ambientVolume).then(o=>this.applyIfCurrent(o,a,()=>this.ambientToken,c=>{this.ambientSource=c?.source,this.ambientGain=c?.gain,c&&(c.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(i/eA,1);const s=i>iA;if(s!==this.windActive){this.windActive=s;const a=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,s&&this.startLoop(QE,this.windVolume).then(o=>this.applyIfCurrent(o,a,()=>this.windToken,c=>{this.windSource=c?.source,this.windGain=c?.gain,c&&(c.gain.gain.value=this.windVolume)}))}else this.windGain&&(this.windGain.gain.value=this.windVolume)}setPaused(t){if(t===this.paused)return;this.paused=t;const{type:e,intensity:i,windSpeed:n}=this.requested;this.setAmbient(e,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(tA,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear()}applyIfCurrent(t,e,i,n){if(e!==i()){t?.source.stop();return}n(t)}async startLoop(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n,s.loop=!0;const a=i.createGain();return a.gain.value=e,s.connect(a).connect(this.output(i)),s.start(),{source:s,gain:a}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n;const a=i.createGain();a.gain.value=e,s.connect(a).connect(this.output(i)),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(t){const e=this.context;if(!e)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}stopSource(t,e){try{t?.stop()}catch{}t?.disconnect(),e?.disconnect()}}class Ts{constructor(t){this.elements=t;const{eccentricity:e,perihelionAu:i}=t,[n,s]=this.perifocalAxes(),a=Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2*(1+e)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,a),this.inverseSemiMajorAxis=(1-e)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(t){const e=t-this.elements.perihelionJd,i=this.universalAnomaly(e),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,a=1-i*i/s*Ts.stumpffC(n),o=e-i*i*i/Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2)*Ts.stumpffS(n);return{x:a*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:a*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:a*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(t){const e=this.positionAt(t);return Math.hypot(e.x,e.y,e.z)}universalAnomaly(t){if(t===0)return 0;const e=Math.sign(t),i=Math.sqrt(Ts.SUN_GM_AU3_PER_DAY2)*Math.abs(t),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*Ts.stumpffS(c)+l*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let a=0;for(let o=0;o<Ts.MAX_ITERATIONS&&s-a>1e-13*Math.max(1,s);o++){const c=(a+s)/2;n(c)<i?a=c:s=c}return e*(a+s)/2}perifocalAxes(){const t=this.elements.ascendingNodeDeg*Math.PI/180,e=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(t),s=Math.sin(t),a=Math.cos(e),o=Math.sin(e),c=Math.cos(i),l=Math.sin(i);return[{x:n*a-s*o*c,y:s*a+n*o*c,z:o*l},{x:-n*o-s*a*c,y:-s*o+n*a*c,z:a*l}]}scale(t,e){return{x:t.x*e,y:t.y*e,z:t.z*e}}static stumpffC(t){if(Math.abs(t)<1e-6)return 1/2-t/24+t*t/720;if(t>0)return(1-Math.cos(Math.sqrt(t)))/t;const e=Math.sqrt(-t);return(Math.cosh(e)-1)/-t}static stumpffS(t){if(Math.abs(t)<1e-6)return 1/6-t/120+t*t/5040;if(t>0){const i=Math.sqrt(t);return(i-Math.sin(i))/(i*i*i)}const e=Math.sqrt(-t);return(Math.sinh(e)-e)/(e*e*e)}}const rv=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672960498922706,perihelionAu:.5872100477652511,inclinationDeg:162.218798367122,ascendingNodeDeg:58.56208298700436,argumentOfPerihelionDeg:111.7366940639061,perihelionJd:2.4187816784171113e6},peakMagnitude:0,peakOn:"1910-05-20",absoluteMagnitude:4.72,activityExponent:4,tailLengthDeg:100,tailLengthAu:.1638,note:"Passed 0.15 au from Earth on 20 May 1910, and the Earth crossed the outer tail the day before — the apparition that produced a genuine public panic."},{id:"brooks-1911",designation:"C/1911 O1",name:"Comet Brooks",orbit:{eccentricity:.9876404970138669,perihelionAu:.4898172916113738,inclinationDeg:33.34043866978714,ascendingNodeDeg:293.7022074981857,argumentOfPerihelionDeg:153.5578007321686,perihelionJd:2.4193378856140426e6},peakMagnitude:2,peakOn:"1911-10-25",absoluteMagnitude:5.59,activityExponent:4},{id:"skjellerup-maristany-1927",designation:"C/1927 X1",name:"Comet Skjellerup-Maristany",orbit:{eccentricity:.999839726885059,perihelionAu:.1761569619628186,inclinationDeg:85.1125991950808,ascendingNodeDeg:78.24360172472711,argumentOfPerihelionDeg:47.15877857390136,perihelionJd:2.4252326808989984e6},peakMagnitude:-6,peakOn:"1927-12-15",absoluteMagnitude:1.19,activityExponent:4,note:"One of the few comets of the century seen in full daylight."},{id:"de-kock-paraskevopoulos-1941",designation:"C/1941 B2",name:"Comet de Kock-Paraskevopoulos",orbit:{eccentricity:.9991026715181549,perihelionAu:.7900329662827822,inclinationDeg:168.2039226531089,ascendingNodeDeg:43.10609347214336,argumentOfPerihelionDeg:268.6990344196369,perihelionJd:2430022157765061e-9},peakMagnitude:2,peakOn:"1941-02-05",absoluteMagnitude:5.01,activityExponent:4},{id:"southern-1947",designation:"C/1947 X1",name:"the Southern Comet",orbit:{eccentricity:.9998424430916737,perihelionAu:.1100045955093761,inclinationDeg:138.5113919632757,ascendingNodeDeg:337.3114969669252,argumentOfPerihelionDeg:196.1820121395961,perihelionJd:2.4325220864727003e6},peakMagnitude:-3,peakOn:"1947-12-08",absoluteMagnitude:3.01,activityExponent:4,note:"A bright southern-hemisphere comet of December 1947, the month the American sighting wave of that year was still being argued over."},{id:"eclipse-1948",designation:"C/1948 V1",name:"the Eclipse Comet",orbit:{eccentricity:.9999130678247334,perihelionAu:.1354437057263306,inclinationDeg:23.11668597152911,ascendingNodeDeg:211.0454985994762,argumentOfPerihelionDeg:107.2474157073104,perihelionJd:2.4328519265329437e6},peakMagnitude:-2,peakOn:"1948-11-01",absoluteMagnitude:4.79,activityExponent:4,note:"Found during the total solar eclipse of 1 November 1948, which is how a comet that bright had gone unnoticed: it had been hidden in the Sun's glare."},{id:"arend-roland-1957",designation:"C/1956 R1",name:"Comet Arend-Roland",orbit:{eccentricity:1.0002570255357,perihelionAu:.3160532361485914,inclinationDeg:119.9440863251822,ascendingNodeDeg:215.8548157717755,argumentOfPerihelionDeg:308.775920364167,perihelionJd:2.4359365327396123e6},peakMagnitude:.5,peakOn:"1957-04-25",absoluteMagnitude:3.96,activityExponent:4,note:"Showed a spike pointing back TOWARD the Sun in late April 1957 — a real anti-tail, and much reported at the time."},{id:"mrkos-1957",designation:"C/1957 P1",name:"Comet Mrkos",orbit:{eccentricity:.9993521583504134,perihelionAu:.3549238508212375,inclinationDeg:93.9433042053929,ascendingNodeDeg:68.32441518619923,argumentOfPerihelionDeg:40.31823675802871,perihelionJd:243605193752228e-8},peakMagnitude:1,peakOn:"1957-08-05",absoluteMagnitude:5.07,activityExponent:4,note:"The second bright naked-eye comet of 1957, four months after Arend-Roland."},{id:"seki-lines-1962",designation:"C/1962 C1",name:"Comet Seki-Lines",orbit:{eccentricity:1.000003791331562,perihelionAu:.03139689112215131,inclinationDeg:65.01487186102287,ascendingNodeDeg:304.6776602796538,argumentOfPerihelionDeg:11.47295326312573,perihelionJd:2437756163010178e-9},peakMagnitude:-2.5,peakOn:"1962-04-01",absoluteMagnitude:9.3,activityExponent:4},{id:"ikeya-seki-1965",designation:"C/1965 S1",name:"Comet Ikeya-Seki",orbit:{eccentricity:.9999141178248997,perihelionAu:.007785966366889336,inclinationDeg:141.8642315267051,ascendingNodeDeg:346.9951764632611,argumentOfPerihelionDeg:69.04909813996062,perihelionJd:2.4390546837018197e6},peakMagnitude:-10,peakOn:"1965-10-21",alsoRecordedMagnitude:2,alsoRecordedOn:"1965-10-30",absoluteMagnitude:5.26,activityExponent:4.002,tailLengthDeg:25,tailLengthAu:.5048,note:"A sungrazer that passed 450 000 km above the Sun's surface and was seen beside it in broad daylight — the brightest comet of the twentieth century. It then stood in the dawn sky for a fortnight with a tail some 25 degrees long, which is the second magnitude recorded here."},{id:"bennett-1970",designation:"C/1969 Y1",name:"Comet Bennett",orbit:{eccentricity:.9962979048768408,perihelionAu:.5376209981502136,inclinationDeg:90.03975717147327,ascendingNodeDeg:224.6576652531314,argumentOfPerihelionDeg:354.1494209173161,perihelionJd:2.4406655455270996e6},peakMagnitude:0,peakOn:"1970-03-26",absoluteMagnitude:3.36,activityExponent:4},{id:"white-ortiz-bolelli-1970",designation:"C/1970 K1",name:"Comet White-Ortiz-Bolelli",orbit:{eccentricity:.9999488875801225,perihelionAu:.00884411465256722,inclinationDeg:138.9520738221631,ascendingNodeDeg:336.8194095816687,argumentOfPerihelionDeg:61.10224765396615,perihelionJd:2.4407209807728203e6},peakMagnitude:1,peakOn:"1970-05-22",absoluteMagnitude:4.35,activityExponent:4},{id:"kohoutek-1973",designation:"C/1973 E1",name:"Comet Kohoutek",orbit:{eccentricity:1.000007152175185,perihelionAu:.1424250377812859,inclinationDeg:14.30414984159355,ascendingNodeDeg:258.4893339663974,argumentOfPerihelionDeg:37.79772760699667,perihelionJd:2442044930687027e-9},peakMagnitude:0,peakOn:"1974-01-05",absoluteMagnitude:4.89,activityExponent:4,note:"Announced in advance as the comet of the century and remembered for disappointing: it was an ordinary naked-eye object, not the spectacle the press had promised."},{id:"west-1976",designation:"C/1975 V1",name:"Comet West",orbit:{eccentricity:1.000017859625611,perihelionAu:.1966006188461085,inclinationDeg:43.07319920579427,ascendingNodeDeg:118.9189245655447,argumentOfPerihelionDeg:358.4315101259072,perihelionJd:2442833721841768e-9},peakMagnitude:-3,peakOn:"1976-02-25",absoluteMagnitude:4.41,activityExponent:4,tailLengthDeg:30,tailLengthAu:.4325,note:"Broke into four pieces at perihelion. Barely reported at the time — the press had been burned by Kohoutek two years earlier."},{id:"iras-araki-alcock-1983",designation:"C/1983 H1",name:"Comet IRAS-Araki-Alcock",orbit:{eccentricity:.9898409731606003,perihelionAu:.9913412593828502,inclinationDeg:73.25000846947029,ascendingNodeDeg:49.10235754476374,argumentOfPerihelionDeg:192.8506176754439,perihelionJd:2.4454757545235856e6},peakMagnitude:1.7,peakOn:"1983-05-11",absoluteMagnitude:9.04,activityExponent:4,note:"Passed 0.031 au from Earth on 11 May 1983, one of the closest cometary approaches on record: it crossed a quarter of the sky in a night, which no other comet in this list did."},{id:"halley-1986",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672792271749998,perihelionAu:.5871034488173393,inclinationDeg:162.2422242700916,ascendingNodeDeg:58.85993640671803,argumentOfPerihelionDeg:111.8655480539208,perihelionJd:2.4464709589610207e6},peakMagnitude:2.1,peakOn:"1986-03-10",absoluteMagnitude:2.71,activityExponent:4,note:"The worst-placed return in two thousand years — famous, expected, and for most observers a faint smudge."},{id:"hyakutake-1996",designation:"C/1996 B2",name:"Comet Hyakutake",orbit:{eccentricity:.9997295133739305,perihelionAu:.2302272039470452,inclinationDeg:124.923592343765,ascendingNodeDeg:188.0454295899424,argumentOfPerihelionDeg:130.1724036582639,perihelionJd:2.4502048946148166e6},peakMagnitude:0,peakOn:"1996-03-25",absoluteMagnitude:4.75,activityExponent:4,tailLengthDeg:80,tailLengthAu:1,note:"Passed 0.10 au from Earth in March 1996, five weeks BEFORE perihelion, with a tail measured at some 80 degrees — the longest of the modern era."},{id:"hale-bopp-1997",designation:"C/1995 O1",name:"Comet Hale-Bopp",orbit:{eccentricity:.9951314746156615,perihelionAu:.9141695067003724,inclinationDeg:89.43017155012492,ascendingNodeDeg:282.470602866853,argumentOfPerihelionDeg:130.5872524854533,perihelionJd:2450539633099368e-9},peakMagnitude:-.8,peakOn:"1997-04-01",absoluteMagnitude:-1.06,activityExponent:4,tailLengthDeg:20,tailLengthAu:.9938,note:"Visible to the naked eye for about eighteen months, longer than any comet on record."},{id:"mcnaught-2007",designation:"C/2006 P1",name:"Comet McNaught",orbit:{eccentricity:1.00001811603225,perihelionAu:.1707325614080681,inclinationDeg:77.83726446452654,ascendingNodeDeg:267.4149080498975,argumentOfPerihelionDeg:155.9756130642756,perihelionJd:2454113298753579e-9},peakMagnitude:-5.5,peakOn:"2007-01-13",absoluteMagnitude:2.53,activityExponent:4,tailLengthDeg:35,tailLengthAu:.5009,note:"The brightest comet since Ikeya-Seki, seen in daylight beside the Sun in January 2007."},{id:"lovejoy-2011",designation:"C/2011 W3",name:"Comet Lovejoy",orbit:{eccentricity:.999915056276912,perihelionAu:.005553783989325053,inclinationDeg:134.3558712062691,ascendingNodeDeg:326.3693517957772,argumentOfPerihelionDeg:53.50991655176601,perihelionJd:2455911511809431e-9},peakMagnitude:-3,peakOn:"2011-12-16",alsoRecordedMagnitude:1.5,alsoRecordedOn:"2011-12-22",absoluteMagnitude:3.51,activityExponent:1.194,note:"A sungrazer that was expected to be destroyed at perihelion and came out the other side, to stand in the southern dawn sky for the rest of December — which is the second magnitude recorded here."},{id:"panstarrs-2013",designation:"C/2011 L4",name:"Comet PANSTARRS",orbit:{eccentricity:1.000032542889696,perihelionAu:.301544229714915,inclinationDeg:84.2081978367921,ascendingNodeDeg:65.66588626213694,argumentOfPerihelionDeg:333.6516444379993,perihelionJd:2456361669960698e-9},peakMagnitude:1,peakOn:"2013-03-10",absoluteMagnitude:5.98,activityExponent:4},{id:"neowise-2020",designation:"C/2020 F3",name:"Comet NEOWISE",orbit:{eccentricity:.9991782081129224,perihelionAu:.2946512466331692,inclinationDeg:128.9375043020912,ascendingNodeDeg:61.01042991771634,argumentOfPerihelionDeg:37.2786526292898,perihelionJd:2.4590341788972816e6},peakMagnitude:.9,peakOn:"2020-07-08",absoluteMagnitude:5.79,activityExponent:4,tailLengthDeg:10,tailLengthAu:.1808,note:"The first comet since Hale-Bopp that ordinary observers in the northern hemisphere saw without being told where to look."},{id:"tsuchinshan-atlas-2024",designation:"C/2023 A3",name:"Comet Tsuchinshan-ATLAS",orbit:{eccentricity:1.000020192843226,perihelionAu:.3914228969475176,inclinationDeg:139.1105462619479,ascendingNodeDeg:21.55945689078845,argumentOfPerihelionDeg:308.4913086299446,perihelionJd:2460581242087108e-9},peakMagnitude:0,peakOn:"2024-10-14",absoluteMagnitude:3.97,activityExponent:4,tailLengthDeg:20,tailLengthAu:.1902,note:"Briefly reported far brighter around 9 October 2024, when it stood almost between the observer and the Sun and forward-scattered the light through its own dust — a geometry this catalog's brightness model does not attempt, so what is stored is the ordinary evening-sky peak a few days later."}];class sA{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(t){const e=this.julianDayOf(t);return rv.filter(i=>Math.abs(e-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(t,e){return this.aroundDate(t).map(i=>this.appearanceOf(i,t,e)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(t,e,i){const n=Qe(e),s=this.earthPositionAt(n),a=this.apparentPositionOf(t,2451545+n.tt,s),o=this.subtract(a,s),c=this.length(a),l=this.length(o),h=this.tailEndAt(t,a,s,c,n,e,i),u=this.horizontalOf(o,n,e,i);return{apparition:t,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(t,c,l)}}static magnitudeAt(t,e,i){const n=t.absoluteMagnitude+5*Math.log10(i)+2.5*t.activityExponent*Math.log10(e);return Math.max(n,t.peakMagnitude)}static tailEndAt(t,e,i,n,s,a,o){if(t.tailLengthAu===void 0)return{};const c=1+t.tailLengthAu/n,l=this.subtract({x:e.x*c,y:e.y*c,z:e.z*c},i),h=this.subtract(e,i);return{tailEnd:this.horizontalOf(l,s,a,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(t,e,i){const n=this.orbitOf(t);let s=n.positionAt(e);for(let a=0;a<2;a++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(e-o)}return s}static horizontalOf(t,e,i,n){const s=Wr(Kw(),new ke(t.x,t.y,t.z,e)),a=Wr(Y1(e),s),o=Rw(e,new Z0(n.lat,n.lng,n.elevationM)),c=new ke(a.x-o.x,a.y-o.y,a.z-o.z,e),l=j0(c);return Q0(l.ra,l.dec,i,n)}static earthPositionAt(t){return Wr($w(),la(Et.Earth,t))}static julianDayOf(t){return 2451545+Qe(t).tt}static orbitOf(t){const e=this.orbits.get(t.id);if(e)return e;const i=new Ts(t.orbit);return this.orbits.set(t.id,i),i}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}static length(t){return Math.hypot(t.x,t.y,t.z)}static angleBetween(t,e){const i=(t.x*e.x+t.y*e.y+t.z*e.z)/(this.length(t)*this.length(e)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const Ou=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class dg{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(t){const e=this.julianDayOf(t);return Ou.filter(i=>this.magnitudeAt(i,e)!==void 0)}static appearancesAt(t,e){const i=this.julianDayOf(t),n=[];for(const s of Ou){const a=this.magnitudeAt(s,i);a!==void 0&&n.push({outburst:s,position:Hn.ofJ2000(s.raHours,s.decDeg,t,e),magnitude:a})}return n.sort((s,a)=>s.magnitude-a.magnitude)}static brightestAt(t,e){return this.appearancesAt(t,e)[0]}static byId(t){return Ou.find(e=>e.id===t)}static magnitudeAt(t,e){const i=t.lightCurve,n=e-t.startJd;if(i.length===0||n<i[0][0]||n>i[i.length-1][0])return;let s=1;for(;s<i.length-1&&i[s][0]<n;)s++;const[a,o]=i[s-1]??i[0],[c,l]=i[s]??i[0];if(c===a)return o;const h=Math.min(1,Math.max(0,(n-a)/(c-a)));return o+h*(l-o)}static julianDayOf(t){return t.getTime()/864e5+this.UNIX_EPOCH_JD}}const aA=[{id:"quadrantids",code:"QUA",name:"Quadrantids",radiantRaHours:15.33,radiantDecDeg:49.7,start:{month:12,day:28},peak:{month:1,day:3},end:{month:1,day:12},peakZhr:110,velocityKmS:41,populationIndex:2.1},{id:"lyrids",code:"LYR",name:"April Lyrids",radiantRaHours:18.13,radiantDecDeg:33.3,start:{month:4,day:16},peak:{month:4,day:22},end:{month:4,day:25},peakZhr:18,velocityKmS:49,populationIndex:2.1},{id:"eta-aquariids",code:"ETA",name:"eta Aquariids",radiantRaHours:22.53,radiantDecDeg:-1,start:{month:4,day:19},peak:{month:5,day:6},end:{month:5,day:28},peakZhr:50,velocityKmS:66,populationIndex:2.4},{id:"alpha-capricornids",code:"CAP",name:"alpha Capricornids",radiantRaHours:20.47,radiantDecDeg:-9.2,start:{month:7,day:3},peak:{month:7,day:30},end:{month:8,day:15},peakZhr:5,velocityKmS:23,populationIndex:2.5},{id:"southern-delta-aquariids",code:"SDA",name:"Southern delta Aquariids",radiantRaHours:22.67,radiantDecDeg:-16.4,start:{month:7,day:12},peak:{month:7,day:30},end:{month:8,day:23},peakZhr:25,velocityKmS:41,populationIndex:3.2},{id:"perseids",code:"PER",name:"Perseids",radiantRaHours:3.22,radiantDecDeg:58,start:{month:7,day:17},peak:{month:8,day:12},end:{month:8,day:24},peakZhr:100,velocityKmS:59,populationIndex:2.2},{id:"southern-taurids",code:"STA",name:"Southern Taurids",radiantRaHours:3.47,radiantDecDeg:13,start:{month:9,day:10},peak:{month:10,day:10},end:{month:11,day:20},peakZhr:5,velocityKmS:27,populationIndex:2.3},{id:"draconids",code:"DRA",name:"October Draconids",radiantRaHours:17.47,radiantDecDeg:54,start:{month:10,day:6},peak:{month:10,day:8},end:{month:10,day:10},peakZhr:10,velocityKmS:20,populationIndex:2.6},{id:"orionids",code:"ORI",name:"Orionids",radiantRaHours:6.35,radiantDecDeg:15.6,start:{month:10,day:2},peak:{month:10,day:21},end:{month:11,day:7},peakZhr:20,velocityKmS:66,populationIndex:2.5},{id:"northern-taurids",code:"NTA",name:"Northern Taurids",radiantRaHours:3.87,radiantDecDeg:22,start:{month:10,day:20},peak:{month:11,day:12},end:{month:12,day:10},peakZhr:5,velocityKmS:29,populationIndex:2.3},{id:"leonids",code:"LEO",name:"Leonids",radiantRaHours:10.13,radiantDecDeg:21.6,start:{month:11,day:6},peak:{month:11,day:17},end:{month:11,day:30},peakZhr:15,velocityKmS:71,populationIndex:2.5},{id:"geminids",code:"GEM",name:"Geminids",radiantRaHours:7.47,radiantDecDeg:32.3,start:{month:12,day:4},peak:{month:12,day:14},end:{month:12,day:17},peakZhr:150,velocityKmS:35,populationIndex:2.6},{id:"ursids",code:"URS",name:"Ursids",radiantRaHours:14.47,radiantDecDeg:75.3,start:{month:12,day:17},peak:{month:12,day:22},end:{month:12,day:26},peakZhr:10,velocityKmS:33,populationIndex:3}],Zl=6.5;class Nu{static activeAt(t){return aA.flatMap(e=>{const i=this.nearness(e,t);return i<=0?[]:[{shower:e,zhr:e.peakZhr*i,nearness:i}]})}static nearness(t,e){const i=this.dayOfYear(e),n=this.dayOfYear(this.asDate(t.start)),s=this.dayOfYear(this.asDate(t.peak)),a=this.dayOfYear(this.asDate(t.end)),o=this.wrappedDelta(i,s),c=this.wrappedDelta(s,n),l=this.wrappedDelta(a,s);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(t,e,i,n=Zl){if(e<=0)return 0;const s=Zl-n;return t*Math.sin(e*Math.PI/180)/Math.pow(i,s)}static radiantPosition(t,e,i){return Hn.ofJ2000(t.radiantRaHours,t.radiantDecDeg,e,i)}static dayOfYear(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Math.floor((Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())-e)/864e5)+1}static asDate(t){return new Date(Date.UTC(2001,t.month-1,t.day))}static wrappedDelta(t,e){const i=t-e;return i>182?i-365:i<-182?i+365:i}}class ai{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(t,e){const i=Qe(t),n=new lh(0,Aw(t).elon-90,1),s=Wr(Jw(i),J0(n,i)),a=j0(s);return Q0(a.ra,a.dec,t,e)}static observedRatePerHour(t,e=Zl){const i=ai.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(t*Math.PI/180)),n=Zl-e;return(ai.QUIET_RATE_PER_HOUR+i)/Math.pow(ai.POPULATION_INDEX,n)}static schedule(t){const e=new dh(t.seed^1542469173);return za.schedule(t).map(i=>{const n=ai.toCartesian({altitudeDeg:Math.asin(e.next())*180/Math.PI,azimuthDeg:e.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,a=ai.turnAround(n,e.between(0,360)),o={x:n.x*Math.cos(s)+a.x*Math.sin(s),y:n.y*Math.cos(s)+a.y*Math.sin(s),z:n.z*Math.cos(s)+a.z*Math.sin(s)};return{...i,radiant:ai.toHorizontal(o),bearingDeg:ai.bearingFrom(o,n)}})}static turnAround(t,e){const[i,n]=ai.basisAround(t),s=e*Math.PI/180;return{x:i.x*Math.cos(s)+n.x*Math.sin(s),y:i.y*Math.cos(s)+n.y*Math.sin(s),z:i.z*Math.cos(s)+n.z*Math.sin(s)}}static bearingFrom(t,e){const[i,n]=ai.basisAround(t),s=t.x*e.x+t.y*e.y+t.z*e.z,a=ai.normalise({x:e.x-t.x*s,y:e.y-t.y*s,z:e.z-t.z*s});return(Math.atan2(a.x*n.x+a.y*n.y+a.z*n.z,a.x*i.x+a.y*i.y+a.z*i.z)*180/Math.PI%360+360)%360}static basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=ai.normalise(ai.cross(t,e));return[i,ai.normalise(ai.cross(t,i))]}static toHorizontal(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,t.y/e)))*180/Math.PI,azimuthDeg:(Math.atan2(t.x,-t.z)*180/Math.PI%360+360)%360}}static appearanceOf(t){const e=ai.toCartesian(t.radiant??{altitudeDeg:90,azimuthDeg:0}),i=ai.turnAround(e,t.bearingDeg),n=t.fromRadiantDeg*Math.PI/180;return ai.toHorizontal({x:e.x*Math.cos(n)+i.x*Math.sin(n),y:e.y*Math.cos(n)+i.y*Math.sin(n),z:e.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180,n=Math.cos(e);return{x:n*Math.sin(i),y:Math.sin(e),z:-n*Math.cos(i)}}static cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}static normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}static TYPICAL_VELOCITY_KM_S=40}const fg="https://ufoathome.org/tle/index.json";class Li{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Li.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/tle/index.json",location.href).href),t.includes(fg)||t.push(fg),t}static FIRST_SNAPSHOT="2021-02-22";async covers(t){const e=Date.parse(`${Li.FIRST_SNAPSHOT}T00:00:00Z`)-Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS;if(t.getTime()<e)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>t.getTime()>=Date.parse(n.from)-Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS&&t.getTime()<=Date.parse(n.to)+Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS):!1}async at(t){const e=await this.loadIndex();if(!e)return;const{index:i,base:n}=e,s=[],a=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,t,i,n);s.push(...c),a.push(this.coverageOf(o,t,i,c.length>0))}return{objects:s,coverage:a,credit:i.credit,creditUrl:i.source}}async kindAt(t,e,i,n){const s=e.getTime(),a=i.binDays*Li.DAY_MS,o=Math.floor(s/a),c=s-o*a<a/2?o-1:o+1,l=new Set(i.kinds[t].bins),h=[o,c].map(v=>new Date(v*a).toISOString().slice(0,10)).filter(v=>l.has(v));if(h.length===0)return[];const[u,...d]=await Promise.all([this.json(new URL(`objects-${t}.json`,n).href),...h.map(v=>this.binary(new URL(`${t}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of Li.decode(v,i.recordBytes)){const g=f.get(m.norad);(!g||Math.abs(m.epochMs-s)<Math.abs(g.epochMs-s))&&f.set(m.norad,m)}const p=[];for(const v of f.values()){const m=Math.abs(v.epochMs-s)/Li.DAY_MS;if(m>Li.MAX_ELEMENT_AGE_DAYS)continue;const g=u[v.norad]??{name:String(v.norad)};g.launch&&Date.parse(`${g.launch}T00:00:00Z`)>s||p.push({norad:v.norad,name:g.name,kind:t,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(t,e,i,n){const{from:s,to:a}=i.kinds[t],o=e.getTime(),c=Li.MAX_ELEMENT_AGE_DAYS*Li.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(a)+c?"after":"gap";return{kind:t,status:l,from:s,to:a}}static decode(t,e){const i=new DataView(t),n=[];for(let s=0;s+e<=t.byteLength;s+=e)n.push({norad:i.getUint32(s,!0),epochMs:i.getFloat64(s+4,!0),bstar:i.getFloat32(s+12,!0),inclinationDeg:i.getFloat32(s+16,!0),raanDeg:i.getFloat32(s+20,!0),eccentricity:i.getFloat32(s+24,!0),argOfPerigeeDeg:i.getFloat32(s+28,!0),meanAnomalyDeg:i.getFloat32(s+32,!0),meanMotion:i.getFloat64(s+36,!0)});return n}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;return{index:await e.json(),base:t}}catch{}})(),this.index}json(t){return this.cached(t,async e=>e.json())}binary(t){return this.cached(t,async e=>e.arrayBuffer())}cached(t,e){let i=this.files.get(t);return i||(i=this.fetchImpl(t).then(n=>{if(!n.ok)throw new Error(`${t}: ${n.status}`);return e(n)}),i.catch(()=>this.files.delete(t)),this.files.set(t,i)),i}}class rA{lowerM;upperM;add(t,e){if(!(t<=0)){if(e.behindM!==void 0){const i=De.sizeMAt(e.behindM,t);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(e.inFrontM!==void 0){const i=De.sizeMAt(e.inFrontM,t);this.upperM=this.upperM===void 0?i:Math.min(this.upperM,i)}}}get sizeRange(){return{minM:this.lowerM,maxM:this.upperM}}get empty(){return this.lowerM===void 0&&this.upperM===void 0}get contradictory(){return this.lowerM!==void 0&&this.upperM!==void 0&&this.lowerM>this.upperM}distanceRangeAt(t){return t<=0?{}:{minM:this.lowerM===void 0?void 0:De.distanceMAt(this.lowerM,t),maxM:this.upperM===void 0?void 0:De.distanceMAt(this.upperM,t)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ha{static DEG_PER_SECOND=360/86164.0905;static degOver(t){return Math.max(0,t)*Ha.DEG_PER_SECOND}static instants(t,e){if(!(e>0))return 1;const i=Ha.degOver(t)/e;return i<1?1:Math.min(Ha.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class Hi{static EYE={apertureMm:7,exposureSeconds:.1,resolutionArcsec:60};static WAVELENGTH_M=55e-8;static ARCSEC_PER_RADIAN=180*3600/Math.PI;static UNKNOWN_CAMERA_FOCAL_MM=50;static UNKNOWN_CAMERA_DETAIL_UM=20;static get skyDriftArcsecPerSecond(){return Ha.DEG_PER_SECOND*3600}static graspOf(t,e={}){const i=e.exposureSeconds??t.exposureSeconds,n=e.fNumber??t.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return Hi.EYE;const s=e.focalLengthMm??t.frame?.focalLengthMm??Hi.UNKNOWN_CAMERA_FOCAL_MM,a=s/n,o=Hi.resolutionArcsec(t,s,a);return{apertureMm:a,exposureSeconds:Math.min(i,Hi.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(t,e,i){const s=(t.detailUm??Hi.UNKNOWN_CAMERA_DETAIL_UM)/1e3/e*Hi.ARCSEC_PER_RADIAN,a=1.22*Hi.WAVELENGTH_M/(i/1e3)*Hi.ARCSEC_PER_RADIAN;return Math.max(s,a)}static trailLimitedSeconds(t){return t/Hi.skyDriftArcsecPerSecond}static gainOverEye(t,e={}){const i=Hi.graspOf(t,e),n=Hi.EYE,s=(i.apertureMm/n.apertureMm)**2,a=i.exposureSeconds/n.exposureSeconds,o=(n.resolutionArcsec/i.resolutionArcsec)**2;return 1.25*Math.log10(s*a*o)}static gainFor(t,e){const i=e.fieldOfViewDeg===void 0?void 0:mi.focalLengthMmFor(t,e.fieldOfViewDeg);return Hi.gainOverEye(t,{fNumber:e.fNumber,focalLengthMm:i,exposureSeconds:e.exposureSeconds})}}const pg=111320,To=Math.PI/180,oA=1.02,cA=1;class Ho{static of(t,e){const i=Ho.sightings(t,e);if(i.length<2)return;const n=Ho.baseline(i);if(!n)return;const{near:s,far:a,closedM:o}=n,c=Math.tan(a.widthDeg/2*To)===0?0:Math.tan(s.widthDeg/2*To)/Math.tan(a.widthDeg/2*To);if(c<oA)return;const l=o/(c-1),h=De.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:De.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:a.t,toT:s.t,closedM:o}}static sightings(t,e){return t.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===e)?.shape,s=n?.angular?.widthDeg,a=Ze(t,i.t);return s===void 0||s<=0||a?.lat===void 0||a.lng===void 0?[]:[{t:i.t,widthDeg:s,lat:a.lat,lng:a.lng,sightAzimuthDeg:n?.aim?.azimuthDeg??a.headingDeg}]}).sort((i,n)=>i.t-n.t)}static baseline(t){let e;for(const i of t)for(const n of t){if(i.t>=n.t)continue;const s=Ho.closedAlongSight(i,n),[a,o,c]=s>=0?[n,i,s]:[i,n,-s];c<cA||a.widthDeg<=o.widthDeg||(!e||c>e.closedM)&&(e={near:a,far:o,closedM:c})}return e}static closedAlongSight(t,e){const i=(e.lat-t.lat)*pg,n=(e.lng-t.lng)*pg*Math.cos(t.lat*To),s=(t.sightAzimuthDeg??0)*To;return i*Math.cos(s)+n*Math.sin(s)}}class Bi{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(t){if(t.statedM!==void 0&&t.statedM>0)return{distanceM:Bi.atLeastNearest(t.statedM),basis:"stated"};if(t.hypothesisM!==void 0&&t.hypothesisM>0)return{distanceM:Bi.atLeastNearest(t.hypothesisM),basis:"hypothesis"};if(t.derivedM!==void 0&&t.derivedM>0)return{distanceM:Bi.atLeastNearest(t.derivedM),basis:"derived"};const e=Bi.largest(t.range?.minM,t.crossing?.behindM),i=Bi.smallest(t.range?.maxM,t.crossing?.inFrontM),n=e===void 0?void 0:e*Bi.MARGIN,s=i===void 0?void 0:i/Bi.MARGIN;return n!==void 0&&s!==void 0?{distanceM:Bi.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:Bi.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<Bi.CONVENTIONAL_M?{distanceM:Bi.atLeastNearest(s),basis:"bounded"}:{distanceM:Bi.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(t){return Math.max(Bi.NEAREST_M,t)}static largest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.max(...e)}static smallest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.min(...e)}}const Fu=Math.PI/180;class ie{constructor(t,e,i){this.body=t,this.ground=e;const n=[...t.track].sort((s,a)=>s.t-a.t);this.keys=this.place(n,i);for(const s of n)ie.collect(this.motionKeys,s.t,s.motions),ie.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(t,e,i){for(const[n,s]of Object.entries(i??{})){const a=t.get(n)??[];a.push({t:e,value:s}),t.set(n,a)}}motionsAt(t){return ie.channelsAt(this.motionKeys,t,0)}lightsAt(t){return this.lightKeys.size>0?ie.channelsAt(this.lightKeys,t,void 0):void 0}static channelsAt(t,e,i){const n={};for(const[s,a]of t){let o=a.length-1;for(;o>=0&&a[o].t>e;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const c=a[o],l=a[Math.min(o+1,a.length-1)],h=l===c||l.t===c.t?0:Math.min(1,(e-c.t)/(l.t-c.t));n[s]=ie.lerp(c.value,l.value,h)}return n}static eyeOf(t,e,i){const n=Ze(t,0),s=Ze(t,e),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?Je(s.lat,s.lng,n.lat,n.lng):void 0,c=o?o.x:0,l=o?-o.z:0;return{eastM:c,northM:l,upM:i.heightAt(c,l)+ie.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(t,e,i,n){const s=ie.directionOf(e,i),a=l=>t.upM+s.upM*l-n.heightAt(t.eastM+s.eastM*l,t.northM+s.northM*l);let o=0,c=0;for(;c<ie.MAX_RANGE_M;){if(c=o+Math.max(.5,o*.01),a(c)<=0){for(let l=0;l<30;l++){const h=(o+c)/2;a(h)<=0?c=h:o=h}return c}o=c}}static directionOf(t,e){const i=t*Fu,n=e*Fu;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(t){const e=this.keys;if(e.length===0||t<e[0].t)return;let i=e.length-1;for(;i>0&&e[i].t>t;)i--;const n=e[i];if(!n.present)return;const s=e[Math.min(i+1,e.length-1)],a=s===n||s.t===n.t?0:Math.min(1,(t-n.t)/(s.t-n.t)),o=ie.lerp(n.eastM,s.eastM,a),c=ie.lerp(n.northM,s.northM,a),l={widthM:ie.lerp(n.sizeM.widthM,s.sizeM.widthM,a),lengthM:ie.lerp(n.sizeM.lengthM,s.sizeM.lengthM,a),heightM:ie.lerp(n.sizeM.heightM,s.sizeM.heightM,a)},h={headingDeg:ie.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,a),pitchDeg:ie.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,a),rollDeg:ie.lerp(n.attitude.rollDeg,s.attitude.rollDeg,a)};let u;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const d=ie.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,a);u=this.groundUnderFootprint(o,c,l,h.headingDeg)+d+l.heightM/2}else u=ie.lerp(this.centreUpOf(n),this.centreUpOf(s),a);return{id:this.body.id,model:this.body.model,explains:this.body.explains??[],outlineNode:this.body.outlineNode,eastM:o,northM:c,upM:u,sizeM:l,attitude:h,appearance:{color:(a<1?n:s).appearance.color,albedo:ie.lerp(n.appearance.albedo,s.appearance.albedo,a),luminanceCdM2:ie.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,a)},flame:ie.flameBetween(n.flame,s.flame,a),motions:this.motionsAt(t),lights:this.lightsAt(t),throwsFlame:this.body.track.some(d=>d.flame!==void 0&&d.flame.luminanceCdM2>0)}}static flameBetween(t,e,i){if(!t||t.luminanceCdM2<=0)return i>=1&&e&&e.luminanceCdM2>0?e:void 0;const n=t,s=e??t,a={...i<1?n:s,lengthM:ie.lerp(n.lengthM,s.lengthM,i),widthM:ie.lerp(n.widthM,s.widthM,i),luminanceCdM2:ie.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return a.luminanceCdM2>0?a:void 0}centreUpOf(t){return"upM"in t.vertical?t.vertical.upM:this.groundUnderFootprint(t.eastM,t.northM,t.sizeM,t.attitude.headingDeg)+t.vertical.aboveGroundM+t.sizeM.heightM/2}groundUnderFootprint(t,e,i,n){const s=n*Fu,a={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(t,e);for(const[l,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const u=l*i.widthM/2,d=h*i.lengthM/2;c=Math.max(c,this.ground.heightAt(t+a.eastM*u+o.eastM*d,e+a.northM*u+o.northM*d))}return c}place(t,e){const i=[];let n;for(const s of t){const a=s.sizeM??n?.sizeM??ie.DEFAULT_SIZE,o={headingDeg:s.attitude?.headingDeg??n?.attitude.headingDeg??0,pitchDeg:s.attitude?.pitchDeg??n?.attitude.pitchDeg??0,rollDeg:s.attitude?.rollDeg??n?.attitude.rollDeg??0},c={color:s.appearance?.color??n?.appearance.color??ie.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??ie.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??ie.DEFAULT_APPEARANCE.luminanceCdM2},l=this.positionOf(s,e)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s)??n.vertical});if(!l)continue;const h=s.flame??n?.flame,u=s.present??n?.present??!0;n={t:s.t,...l,sizeM:a,attitude:o,appearance:c,flame:h,present:u},i.push(n)}return i}verticalOf(t){if(t.onGround)return{aboveGroundM:0};if(t.altitudeAboveGroundM!==void 0)return{aboveGroundM:t.altitudeAboveGroundM}}positionOf(t,e){if(t.eastM!==void 0&&t.northM!==void 0)return{eastM:t.eastM,northM:t.northM,vertical:this.verticalOf(t)??{aboveGroundM:0}};if(t.azimuthDeg===void 0||t.altitudeDeg===void 0)return;const i=e(t.t);if(!i)return;const n=t.distanceM??(t.onGround?ie.lineOfSightMeetsGround(i,t.azimuthDeg,t.altitudeDeg,this.ground):void 0);if(n===void 0)return;const s=ie.directionOf(t.azimuthDeg,t.altitudeDeg),a=i.eastM+s.eastM*n,o=i.northM+s.northM*n;return{eastM:a,northM:o,vertical:this.verticalOf(t)??{upM:i.upM+s.upM*n}}}static lerp(t,e,i){return t+(e-t)*i}static lerpAngle(t,e,i){const n=((e-t)%360+540)%360-180;return((t+n*i)%360+360)%360}}class me{static A=6378137;static E2=.00669437999014;static DEG=Math.PI/180;static STANDARD_DISTANCE_KM=100;static DEFAULT_COLOR="#ffb347";static DEFAULT_TRAIN_S=1.5;static FADE_MS=600;static TRAIN_POINTS=8;static leadAt(t,e){const i=t.track;if(i.length<2||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-2&&i[n+1].t<e;)n++;const s=i[n],a=i[n+1],o=a.t-s.t,c=o>0?(e-s.t)/o:0,[l,h]=me.alongGreatCircle(s,a,c);return{lat:l,lng:h,heightM:(s.altitudeKm+(a.altitudeKm-s.altitudeKm)*c)*1e3}}static viewsAt(t,e,i){const n=[];for(const s of t){const a=s.track[0]?.t??0,o=s.track[s.track.length-1]?.t??0;s.fragments.forEach((c,l)=>{const h=c.fromT??a,u=c.untilT??o;if(e<h||e>u)return;const d=(c.lagS??0)*1e3,f=me.leadAt(s,e-d);if(!f)return;const p=me.seenFrom(i,f);if(p.altitudeDeg<0)return;const v=Math.min(me.FADE_MS,(u-h)/4),m=v>0?Math.min(1,(e-h)/v,(u-e)/v):1,g=-2.5*Math.log10(Math.max(m,.001)),_=c.absoluteMagnitude+5*Math.log10(p.distanceKm/me.STANDARD_DISTANCE_KM)+g,y=[p],M=(c.trainS??me.DEFAULT_TRAIN_S)*1e3;for(let b=1;b<=me.TRAIN_POINTS;b++){const w=Math.min(M*b/me.TRAIN_POINTS,e-h),T=me.leadAt(s,e-d-w);if(!T||(y.push(me.seenFrom(i,T)),w>=e-h))break}n.push({reentryId:s.id,fragmentId:c.id??String(l),head:p,magnitude:_,color:c.color??me.DEFAULT_COLOR,train:y})})}return n}static seenFrom(t,e){const i=me.ecef(t),n=me.ecef(e),s=n[0]-i[0],a=n[1]-i[1],o=n[2]-i[2],c=t.lat*me.DEG,l=t.lng*me.DEG,h=-Math.sin(l)*s+Math.cos(l)*a,u=-Math.sin(c)*Math.cos(l)*s-Math.sin(c)*Math.sin(l)*a+Math.cos(c)*o,d=Math.cos(c)*Math.cos(l)*s+Math.cos(c)*Math.sin(l)*a+Math.sin(c)*o,f=Math.hypot(h,u,d);return{altitudeDeg:Math.asin(d/f)/me.DEG,azimuthDeg:(Math.atan2(h,u)/me.DEG+360)%360,distanceKm:f/1e3}}static ecef(t){const e=t.lat*me.DEG,i=t.lng*me.DEG,n=Math.sin(e),s=me.A/Math.sqrt(1-me.E2*n*n);return[(s+t.heightM)*Math.cos(e)*Math.cos(i),(s+t.heightM)*Math.cos(e)*Math.sin(i),(s*(1-me.E2)+t.heightM)*n]}static alongGreatCircle(t,e,i){const n=h=>{const u=h.lat*me.DEG,d=h.lng*me.DEG;return[Math.cos(u)*Math.cos(d),Math.cos(u)*Math.sin(d),Math.sin(u)]},s=n(t),a=n(e),o=Math.max(-1,Math.min(1,s[0]*a[0]+s[1]*a[1]+s[2]*a[2])),c=Math.acos(o);let l;if(c<1e-12)l=s;else{const h=Math.sin((1-i)*c)/Math.sin(c),u=Math.sin(i*c)/Math.sin(c);l=[s[0]*h+a[0]*u,s[1]*h+a[1]*u,s[2]*h+a[2]*u]}return[Math.atan2(l[2],Math.hypot(l[0],l[1]))/me.DEG,Math.atan2(l[1],l[0])/me.DEG]}}class nf{static FIRST_DAY="2022-01-01";static mayCover(t){return new Date(t).toISOString().slice(0,10)>=nf.FIRST_DAY}}class lA{constructor(t,e,i){this.citation=t,this.covers=e,this.load=i}loading;mayCover(t){return this.covers(t)}async between(t,e,i,n){try{return await(await this.provider()).between(t,e,i,n)}catch{return{status:"failed"}}}async describe(t,e){try{return await(await this.provider()).describe?.(t,e)}catch{return}}provider(){if(!this.loading){const t=this.load();this.loading=t,t.catch(()=>{this.loading===t&&(this.loading=void 0)})}return this.loading}}const hA="Aircraft positions: adsb.lol feeders and contributors, Open Database License 1.0 (https://www.adsb.lol/docs/open-data/historical/)",uA=[{id:"adsb-lol",name:"adsb.lol",credit:"adsb.lol feeders and contributors, ODbL 1.0",creditUrl:"https://www.adsb.lol/docs/open-data/historical/",create:()=>new lA(hA,r=>nf.mayCover(r),async()=>new(await an(async()=>{const{AdsbLolArchiveProvider:r}=await import("./AdsbLolArchiveProvider-2vNkvjL5.js");return{AdsbLolArchiveProvider:r}},[],import.meta.url)).AdsbLolArchiveProvider)}];class Gi{static MAX_GAP_S=60;static FT_TO_M=.3048;static EARTH_RADIUS_KM=6371;static seenFrom(t,e,i){const n=Gi.positionAt(t,i);if(!n)return;const s=me.seenFrom(e,n.geo);if(!(s.altitudeDeg<0))return{track:t,sky:s,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg,angularRateDegPerS:Gi.angularRate(t,e,i)}}static viewsAt(t,e,i){return t.flatMap(n=>Gi.seenFrom(n,e,i)??[])}static groundDistanceKm(t,e){const i=Math.PI/180,n=Math.sin((e.lat-t.lat)*i/2)**2+Math.cos(t.lat*i)*Math.cos(e.lat*i)*Math.sin((e.lng-t.lng)*i/2)**2;return 2*Gi.EARTH_RADIUS_KM*Math.asin(Math.min(1,Math.sqrt(n)))}static wrapLongitude(t){return((t+180)%360+360)%360-180}static positionAt(t,e){const i=t.points;if(i.length===0||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-1&&i[n+1].t<=e;)n++;const s=i[n],a=i[n+1]??s,o=a.t-s.t;if(o>Gi.MAX_GAP_S*1e3)return;const c=o>0?(e-s.t)/o:0,l=s.altitudeFt+(a.altitudeFt-s.altitudeFt)*c,h=(a.lng-s.lng+540)%360-180;return{geo:{lat:s.lat+(a.lat-s.lat)*c,lng:Gi.wrapLongitude(s.lng+h*c),heightM:l*Gi.FT_TO_M},altitudeFt:l,groundSpeedKt:s.groundSpeedKt,trackDeg:s.trackDeg}}static angularRate(t,e,i){const n=Gi.positionAt(t,i-500),s=Gi.positionAt(t,i+500);if(!n||!s)return;const a=Gi.unit(me.seenFrom(e,n.geo)),o=Gi.unit(me.seenFrom(e,s.geo)),c=Math.min(1,Math.max(-1,a[0]*o[0]+a[1]*o[1]+a[2]*o[2]));return Math.acos(c)*180/Math.PI}static unit(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180;return[Math.cos(e)*Math.sin(i),Math.cos(e)*Math.cos(i),Math.sin(e)]}}const mg="https://ufoathome.org/fireballs/index.json";class hs{static FIRST_MONTH="2018-12";static STRIKING_MAGNITUDE=-1;static COLOR="#eef2ff";static TRAIN_S=.3;fetchImpl;indexUrls;index;months=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??hs.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/fireballs/index.json",location.href).href),t.includes(mg)||t.push(mg),t}static mayCover(t){return new Date(t).toISOString().slice(0,7)>=hs.FIRST_MONTH}async credit(){return(await this.loadIndex())?.index.credit}async between(t,e){if(!hs.mayCover(e))return;const i=await this.loadIndex();if(!i)return;const n=new Set([new Date(t).toISOString().slice(0,7),new Date(e).toISOString().slice(0,7)]);return[...n].some(a=>a>=i.index.from&&a<=i.index.to)?(await Promise.all([...n].filter(a=>i.index.months.includes(a)).map(a=>this.monthOf(a,i.base)))).flat().filter(a=>a.t>=t&&a.t<=e):void 0}static seenFrom(t,e){const i=hs.peakFraction(t),n={lat:t.from[0]+(t.to[0]-t.from[0])*i,lng:t.from[1]+(t.to[1]-t.from[1])*i,heightM:t.peakHeightKm*1e3},s=me.seenFrom(e,n);if(!(s.altitudeDeg<0))return{record:t,peak:s,magnitude:t.peakMagnitude+5*Math.log10(s.distanceKm/me.STANDARD_DISTANCE_KM)}}static asReentry(t,e){const i=t.t-e,n=i+Math.max(t.durationS,.1)*1e3;return{id:`gmn-${t.id}`,track:[{t:i,lat:t.from[0],lng:t.from[1],altitudeKm:t.from[2]},{t:n,lat:t.to[0],lng:t.to[1],altitudeKm:t.to[2]}],fragments:[{absoluteMagnitude:t.peakMagnitude,color:hs.COLOR,trainS:hs.TRAIN_S}]}}static peakFraction(t){const e=t.from[2]-t.to[2];return Math.abs(e)<1e-6?.5:Math.min(1,Math.max(0,(t.from[2]-t.peakHeightKm)/e))}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}monthOf(t,e){let i=this.months.get(t);return i||(i=this.fetchImpl(new URL(`${t}.json`,e).href).then(n=>n.ok?n.json():[]).catch(()=>[]),this.months.set(t,i)),i}}const _r=Math.PI/180,Ro=180/Math.PI;class si{constructor(t){this.timeline=t}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(t,e,i,n){const s=[];for(const a of e){const o=si.projectionOf(a,i,n?.(a));if(o)for(const c of a.explains){const l=this.timeline.getInterpolatedShapeAt(t,c);!l||l.transparency>=1||s.push({...si.compare(c,a.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(t,e,i,n){const s=[],a=i.aim?si.separationDeg(i.aim,n.aim):void 0;if(a!==void 0){const l=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;a>Math.max(si.DIRECTION_TOLERANCE_DEG,l)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,c=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!si.withinSize(o)&&s.push("width"),c!==void 0&&!si.withinSize(c)&&s.push("height"),{sourceId:t,bodyId:e,stated:i,predicted:n,separationDeg:a,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(t,e,i){const n=i&&i.length>0?i:si.outlineOf(t),s=i&&i.length>0?si.centreOf(i):t,a=si.normalized({eastM:s.eastM-e.eastM,northM:s.northM-e.northM,upM:s.upM-e.upM});if(!a)return;const o=si.normalized({eastM:a.northM,northM:-a.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=si.cross(o,a);let l=1/0,h=-1/0,u=1/0,d=-1/0;for(const f of n){const p={eastM:f.eastM-e.eastM,northM:f.northM-e.northM,upM:f.upM-e.upM},v=si.dot(p,a);if(v<=0)return;const m=Math.atan2(si.dot(p,o),v),g=Math.atan2(si.dot(p,c),v);l=Math.min(l,m),h=Math.max(h,m),u=Math.min(u,g),d=Math.max(d,g)}return{aim:{azimuthDeg:(Math.atan2(a.eastM,a.northM)*Ro+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,a.upM)))*Ro},angular:{widthDeg:(h-l)*Ro,heightDeg:(d-u)*Ro}}}static centreOf(t){const e=i=>(Math.min(...t.map(n=>n[i]))+Math.max(...t.map(n=>n[i])))/2;return{eastM:e("eastM"),northM:e("northM"),upM:e("upM")}}static separationDeg(t,e){const i=t.altitudeDeg*_r,n=e.altitudeDeg*_r,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((t.azimuthDeg-e.azimuthDeg)*_r);return Math.acos(Math.max(-1,Math.min(1,s)))*Ro}static withinSize(t){return t<=si.SIZE_TOLERANCE&&t>=1/si.SIZE_TOLERANCE}static outlineOf(t){const e=t.sizeM.widthM/2,i=t.sizeM.lengthM/2,n=t.sizeM.heightM/2,s=[],a=t.model.url===void 0?t.model.id:void 0;if(a!==void 0&&a!=="box"&&nv.includes(a))for(let u=0;u<=si.RINGS;u++){const d=u/si.RINGS*Math.PI;for(let f=0;f<si.SEGMENTS;f++){const p=f/si.SEGMENTS*2*Math.PI;s.push([e*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-e,e])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=t.attitude.headingDeg*_r,l=t.attitude.pitchDeg*_r,h=t.attitude.rollDeg*_r;return s.map(([u,d,f])=>{const p=u*Math.cos(h)+f*Math.sin(h),v=-u*Math.sin(h)+f*Math.cos(h),m=d*Math.cos(l)-v*Math.sin(l),g=d*Math.sin(l)+v*Math.cos(l);return{eastM:t.eastM+p*Math.cos(c)+m*Math.sin(c),northM:t.northM-p*Math.sin(c)+m*Math.cos(c),upM:t.upM+g}})}static dot(t,e){return t.eastM*e.eastM+t.northM*e.northM+t.upM*e.upM}static cross(t,e){return{eastM:t.northM*e.upM-t.upM*e.northM,northM:t.upM*e.eastM-t.eastM*e.upM,upM:t.eastM*e.northM-t.northM*e.eastM}}static normalized(t){const e=Math.hypot(t.eastM,t.northM,t.upM);return e>1e-9?{eastM:t.eastM/e,northM:t.northM/e,upM:t.upM/e}:void 0}}Ng();const dA={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},fA="{name} — mag {mag}, {alt}° above the horizon",pA="{name} — satellite, mag {mag}, {height} km up",mA="satellites-change",gA="fireballs-change",vA="aircraft-change",MA="rr0-confrontation",xA="{name} — mag {mag}, {alt}° below the horizontal",Uu="Credits",gg="comet:",vg="nova:",yA={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",crop:"Crop row",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},_A=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,SA=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,bA=-18,wA={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},ku={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class Ve extends HTMLElement{creditsButton;set ownCredits(t){this.creditsButton.hidden=!t}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",Lr,Or]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new Li;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;static fireballArchive=new hs;fireballs;static aircraftProviders=new Map;static SOUND_LOOKBACK_MS=3e5;static NO_CONTRAILS=[];static upperAirProviders=new Map;static NO_PRESENCE=new Map;aircraftSource=uA[0];static trafficRuntimeLoading;static trafficRuntime;static loadTrafficRuntime(){return Ve.trafficRuntimeLoading??=an(()=>import("./trafficRuntime-B1Tm75lS.js"),__vite__mapDeps([2,1]),import.meta.url).then(t=>Ve.trafficRuntime=t),Ve.trafficRuntimeLoading.catch(()=>{Ve.trafficRuntimeLoading=void 0}),Ve.trafficRuntimeLoading}traffic;lastSun;decorMemo;starCatalogDepth=0;weatherAudio=new nA;vehicleAudio=new Mv;aircraftAudio;vehicleHearing=new Al;animateWhilePausedValue=!1;set animateWhilePaused(t){t!==this.animateWhilePausedValue&&(this.animateWhilePausedValue=t,this.syncAnimationsToPlayback())}get animateWhilePaused(){return this.animateWhilePausedValue}thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=t=>{this.sceneRenderer.setCompassHovered(!0);const e=this.ufoElement.canvasElement,i=e.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(t.clientX-i.left)/i.width*e.width,s=(t.clientY-i.top)/i.height*e.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const a=(t.clientX-i.left)/i.width*2-1,o=-((t.clientY-i.top)/i.height*2-1),c=this.naming,l=c.names,h=this.sceneRenderer.pickBodyAt(a,o);if(h){this.showHoverTooltip(t,this.bodyName(h));return}const u=this.sceneRenderer.pickDecorAt(a,o),d=u?this.ufoElement.sighting.decor.find(m=>m.id===u):void 0;if(d){this.showHoverTooltip(t,this.said.read(d.title)||c.decorKind(d.kind,yA[d.kind]));return}const f=this.trafficTooltipAt(a,o);if(f){this.showHoverTooltip(t,f);return}const p=this.sceneRenderer.pickSatelliteAt(a,o);if(p){this.showHoverTooltip(t,(l?.satelliteTooltip??pA).replace("{name}",p.name).replace("{mag}",p.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(p.heightKm).toLocaleString()));return}const v=this.sceneRenderer.pickStarAt(a,o);if(v){const m=v.star.mag,g=v.altitudeDeg,_=g<0?l?.starTooltipBelow??xA:l?.starTooltip??fA;this.showHoverTooltip(t,_.replace("{name}",c.star(v.star)).replace("{mag}",m.toLocaleString(void 0,{maximumFractionDigits:Math.abs(m)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(g)))));return}this.hoverTooltip.hidden=!0};bodyName(t){const e=t.startsWith(gg)?t.slice(gg.length):void 0,i=e?rv.find(a=>a.id===e):void 0;if(i)return this.naming.comet(i);const n=t.startsWith(vg)?dg.byId(t.slice(vg.length)):void 0;if(n)return this.naming.nova(n);const s=dA[t];return s===void 0?t:this.naming.body(t,s)}get naming(){return this.sceneNaming}sceneNaming=new ug;namesLanguage="en";async loadSceneNames(){const t=bg(Pr.preferencesFor(this),wg);if(t===this.namesLanguage)return;this.namesLanguage=t;const e=await r2(t);t===this.namesLanguage&&this.applySceneNaming(new ug(e))}renderLoaderText(t,e){let i=0;const n=(s,a)=>{s.setAttribute("aria-label",a),s.replaceChildren(),a.split(" ").forEach((o,c)=>{c>0&&s.append(" ");const l=document.createElement("span");l.className="scene-loader-word",l.setAttribute("aria-hidden","true");for(const h of o){const u=document.createElement("span");u.className="scene-loader-letter",u.style.setProperty("--i",String(i++)),u.textContent=h,l.append(u)}s.append(l),i++})};n(this.loaderNotVideo,t),i+=6,n(this.loaderNote,e)}applySceneNaming(t){this.sceneNaming=t;const e=t.names?.credits??Uu;this.creditsButton.title=e,this.creditsButton.setAttribute("aria-label",e),t.names&&this.renderLoaderText(t.names.notAVideo,t.names.isASimulation),this.sceneRenderer.setCompassPoints(t.names?.compassPoints)}showHoverTooltip(t,e){this.hoverTooltip.textContent=e,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${t.clientX-i.left+12}px`,this.hoverTooltip.style.top=`${t.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(t){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),gi.thunderDelayMs(t))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(uc(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;applyLevel(){const t=this.ufoElement.level;this.weatherAudio.setLevel(t),this.vehicleAudio.setLevel(t),this.aircraftAudio?.setLevel(t)}handlePageGesture=()=>{this.ufoElement.playbackState==="playing"&&this.handleFirstInteraction()};unlockIfAlreadyActivated(){this.interacted||navigator.userActivation?.hasBeenActive&&this.handleFirstInteraction()}static GESTURES=["pointerdown","pointerup","touchend","click","keydown"];handleTimeUpdate=t=>{this.lastTimeMs=t.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now())};syncAnimationsToPlayback(){const t=this.ufoElement.playbackState==="playing",e=t||this.animateWhilePaused;this.sceneRenderer.setAnimationsRunning(e,t),this.weatherAudio.setPaused(!t),this.vehicleAudio.setPaused(!t),this.aircraftAudio?.setPaused(!t),t&&this.unlockIfAlreadyActivated(),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${bv}</style>${Sv}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.frameElement=this.shadow.getElementById("frame"),this.sceneCanvas=this.shadow.getElementById("scene-canvas"),this.sceneRenderer=new Se(this.sceneCanvas);const e=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.renderLoaderText("This is not a video","It is a real-time simulation."),this.sceneRenderer.onFirstFrameHold=s=>{e.hidden=!s,this.ufoElement.captionHeld=s},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(Hu),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.detail)),this.ufoElement.style.setProperty("--ufo-canvas-background","transparent"),this.ufoElement.style.setProperty("--ufo-canvas-border","none"),this.ufoElement.fullscreenTarget=this.stageElement,this.shadow.getElementById("ufo-slot").replaceWith(this.ufoElement),this.ufoElement.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&tn.fill(n,this)}),this.creditsButton.title=Uu,this.creditsButton.setAttribute("aria-label",Uu),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,a)=>this.seekPreviewOf(a).paint(s,a),this.ufoElement.addEventListener("mutedchange",()=>this.applyLevel()),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.addEventListener("traceview",s=>this.sceneRenderer.setTracesShown(s.detail.shown)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of Ve.GESTURES)this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Rs(Pr.preferencesFor(this))}saidTexts;traceLabelsFor;traceLabels(t){const e=Pr.preferencesFor(this).join();if(this.traceLabelsFor?.traces!==t||this.traceLabelsFor.language!==e){const i=new Map;for(const n of t){const s=this.said.read(n.title);s&&i.set(n.id,s)}this.traceLabelsFor={traces:t,language:e,labels:i}}return this.traceLabelsFor.labels}connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),document.addEventListener("fullscreenchange",this.handleFullscreenChange);for(const e of Ve.GESTURES)document.addEventListener(e,this.handlePageGesture,!0);const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange);for(const t of Ve.GESTURES)document.removeEventListener(t,this.handlePageGesture,!0);this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),this.vehicleAudio.dispose(),this.aircraftAudio?.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),(t==="star-catalog-src"||t==="deep-star-catalog-src")&&i!==e&&this.isConnected&&this.loadStars(),t==="show-compass"&&i!==e&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),t==="max-pixel-ratio"&&i!==e){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(t===Lr||t===Or)&&i!==e&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const t of[Lr,Or]){const e=this.getAttribute(t);e===null?this.ufoElement.removeAttribute(t):this.ufoElement.setAttribute(t,e)}}setCompassForced(t){this.sceneRenderer.setCompassForced(t)}lookToward(t){const e=Ze(this.ufoElement.sighting,this.lastTimeMs);if(t.kind==="observer"||e?.lat===void 0||e.lng===void 0||e.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=Je(t.lat,t.lng,e.lat,e.lng);if(Math.hypot(i,n)<1)return this.setLookOffset(0,0);const s=(Math.atan2(i,-n)*180/Math.PI+360)%360;this.setLookOffset(((s-e.headingDeg)%360+540)%360-180,-e.pitchDeg)}setLookOffset(t,e){this.sceneRenderer.setLookOffset(t,e),this.ufoElement.setLookOffset(t,e),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(t,e){this.sceneRenderer.setIndoorLook(t,e)}setCloudRendering(t){this.sceneRenderer.setCloudRendering(t)}setWeather(t){this.sceneRenderer.setWeather(t),this.weatherAudio.setAmbient(t.precipitationType,t.precipitationIntensity*(t.precipitationAmount??1),t.windSpeed)}pickCloudAt(t,e){return this.sceneRenderer.pickCloudAt(t,e)}cloudDirectionAt(t,e){return this.sceneRenderer.cloudDirectionAt(t,e)}pickDecorAt(t,e){return this.sceneRenderer.pickDecorAt(t,e)}bodyScreenBox(t){return this.sceneRenderer.bodyScreenBox(t)}pickPlacedBodyAt(t,e){return this.sceneRenderer.pickPlacedBodyAt(t,e)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume()}async loadFromSrc(t){const e=_g.json(t);this.holdForNewScene(e);const i=await e;this.documentUrl=new URL(t,location.href).href,this.sightingData=i}holdForNewScene(t){this.sceneRenderer.holdForNewScene(t)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(t){this.sceneRenderer.documentUrl=t}get sightingData(){return this.ufoElement.sightingData}set sightingData(t){this.ufoElement.sightingData=t,this.seekPreview?.recordingChanged(t),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(t){const e=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(t.width/e);return t.height!==i&&(t.height=i),this.seekPreview??=new Kl(this,()=>document.createElement(h0))}showAt(t){this.ufoElement.currentTime=t,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(t){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const e=t.getContext("2d");return e?(e.drawImage(this.sceneCanvas,0,0,t.width,t.height),!0):!1}referenceAspect(t){return this.sceneRenderer.referenceAspect(t)}screenPointOf(t){return this.sceneRenderer.screenPointOf(t)}directionAt(t,e){return this.sceneRenderer.directionAt(t,e)}referenceFailedToLoad(t){return this.sceneRenderer.referenceFailedToLoad(t)}applyReferenceView(t){this.sceneRenderer.setReferencesShown(t.shown);for(const e of this.ufoElement.sighting.references)this.sceneRenderer.setReferenceView(e.id,{opacity:t.opacity})}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}setTerrainProviders(t){this.sceneRenderer.setTerrainProviders(t)}setDecorModelProvider(t){this.sceneRenderer.setDecorModelProvider(t)}get decorModelCredits(){return this.sceneRenderer.currentDecorModelCredits}applyFrameFormat(){const t=this.ufoElement.sighting.instrument,e=De.CANVAS_HEIGHT_PX,i=mi.frameWidthPx(t,e);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${e}`)}resizeToStage(){const t=this.frameElement.getBoundingClientRect(),e=Math.max(1,Math.round(t.width)),i=Math.max(1,Math.round(t.height));this.sceneCanvas.width=e,this.sceneCanvas.height=i,this.sceneRenderer.resize(e,i)}async loadStars(){const t=[{magnitudeLimit:Pu,url:this.getAttribute("star-catalog-src")??_A},{magnitudeLimit:Lu,url:this.getAttribute("deep-star-catalog-src")??SA}],e=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=e>Pu?Lu:Pu;const n=await is.upTo(t,e);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Lu||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const t=this.ufoElement.sighting,e=Hi.gainFor(t.instrument,{fNumber:Ze(t,0)?.fNumber,fieldOfViewDeg:sn.fovOf(t,0),exposureSeconds:t.exposure});return bl(bA,e)}updateAstronomy(t){this.ensureStarsDeepEnough(),this.applySceneAt(t);const e=zn.windowEndingAt(t,this.exposureSeconds()),i=e.seconds,n=this.degreesPerPixelAt(t),s=Ha.instants(i,n),a=Math.max(s,this.ufoElement.exposureTimes(t).length,zn.instants(this.decorWithTraffic(this.ufoElement.sighting),Ze(this.ufoElement.sighting,t)?.elevationM??0,e.fromMs,i,n));if(a<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(a,o=>this.applySceneAt(e.fromMs+e.ms*o/(a-1),{sky:Math.floor(o*s/a)!==Math.floor((o-1)*s/a),stepMs:e.ms/a}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(t){const e=this.sceneCanvas.height;return e<=0?0:sn.fovOf(this.ufoElement.sighting,t)/e}applySceneAt(t,e){const i=this.ufoElement.sighting;this.setWeather(uc(i,t)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),e||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,t)),e||this.pushAircraftSound(i,t),this.updateMeteorShower(i,t),this.updateLightning(i,t,e!==void 0),this.sceneRenderer.setDecor(this.decorWithTraffic(i)),this.sceneRenderer.setDecorPresence(this.traffic?.set?.presence??Ve.NO_PRESENCE),this.sceneRenderer.setDecorSunlight(this.trafficSunlight(t)),this.sceneRenderer.setContrails(this.traffic?.contrails??Ve.NO_CONTRAILS),this.sceneRenderer.setContrailSunlight(this.contrailSunlight(t));const n=Ze(i,t);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=Ze(i,0),a=eo(i,0),o=Object.fromEntries(Tl(eo(i,t)).map(M=>[M.id,Mf(t,i.weatherTrack,a,s,n,M.id)]));this.sceneRenderer.setCloudOffset(Mf(t,i.weatherTrack,a,s,n),o),this.sceneRenderer.setObserverPose(n??ku),this.sceneRenderer.setLensOptics(this.lensOpticsAt(t)),this.sceneRenderer.setInstrumentGain(Hi.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:sn.fovOf(i,t),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(be.bodyAt(i,t,this.ufoElement.steadyObserver)),this.sceneRenderer.updateDecorAnchoring(Ze(i,0),n,t),this.placeBodiesAt(t,e===void 0),this.sceneRenderer.updateDecorLitState(t,e?.stepMs??0),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng,()=>{this.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.sceneRenderer.setTraces(i.traces,this.traceLabels(i.traces)),this.pushPhenomenaAt(t);const c=n?.lat??ku.lat,l=n?.lng??ku.lng,h=yo(i.event.time??{},l,i.event.utcOffsetHours),u={lat:c,lng:l,elevationM:n?.elevationM??0};this.pushSatellitesAt(h,t,u),this.ensureFireballs(h);const d=[...this.interpretationShown?.reentries??[],...this.fireballs?.reentries??[]];if(this.sceneRenderer.setReentries(d.length===0?[]:me.viewsAt(d,t,{lat:c,lng:l,heightM:u.elevationM})),e&&!e.sky)return;if(!h){this.sceneRenderer.setAstronomy(wA);return}const f=new Date(h.getTime()+t),p=Math.max(1,Math.round(.25*this.degreesPerPixelAt(t)/Ha.DEG_PER_SECOND*1e3)),v=Math.max(1e-8,this.degreesPerPixelAt(t)*.1),m=`${Math.floor(f.getTime()/p)}|${Math.round(c/v)}|${Math.round(l/v)}|${Math.round(u.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(m===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=m;const g={...tl("Sun",f,u),magnitude:cu("Sun",f)};this.lastSun={altitudeDeg:g.altitudeDeg,azimuthDeg:g.azimuthDeg};const _={...tl("Moon",f,u),phase:Qw(f),magnitude:cu("Moon",f)},y=jw.map(M=>({body:M,position:tl(M,f,u),magnitude:cu(M,f)}));this.sceneRenderer.setAstronomy({sun:g,moon:_,planets:y,comet:this.cometAt(f,u),novae:dg.appearancesAt(f,u).map(({outburst:M,position:b,magnitude:w})=>({id:M.id,position:b,magnitude:w})),stars:this.starCatalog?{catalog:this.starCatalog,date:f,observer:u}:void 0,frame:{date:f,observer:u}}),this.ufoElement.setSunAltitude(g.altitudeDeg)}pushSatellitesAt(t,e,i){if(this.ensureSatellites(t),!t||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(t.getTime()+e),s=[];for(const a of this.satellites.passes.positionsAt(n,i,-1))a.magnitude!==void 0&&s.push({norad:a.object.norad,name:a.object.name,position:{altitudeDeg:a.altitudeDeg,azimuthDeg:a.azimuthDeg},magnitude:a.magnitude,heightKm:a.heightKm});this.sceneRenderer.setSatellites(s)}ensureFireballs(t){const e=this.ufoElement.sighting,i=Math.max((e.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),n=t?.getTime(),s=n===void 0?"":`${n}+${i}`;if(this.fireballs?.key===s)return;if(n===void 0||!hs.mayCover(n+i)){this.fireballs={key:s,status:"outside",reentries:[]};return}const a={key:s,status:"loading",reentries:[]};this.fireballs=a,Ve.fireballArchive.between(n,n+i).then(o=>{a.status=o?"ready":"unavailable",a.records=o??[],a.reentries=a.records.map(c=>hs.asReentry(c,n)),!(this.fireballs!==a||!this.isConnected)&&(this.dispatchEvent(new CustomEvent(gA)),a.reentries.length>0&&this.updateAstronomy(this.lastTimeMs))})}decorWithTraffic(t){const e=this.ensureTraffic(t);if(!e||e.objects.length===0)return t.decor;const i=this.decorMemo;if(i&&i.base===t.decor&&i.traffic===e.objects)return i.merged;const n=[...t.decor,...e.objects];return this.decorMemo={base:t.decor,traffic:e.objects,merged:n},n}ensureTraffic(t){const e=Ze(t,0),i=e?.lng===void 0?void 0:yo(t.event.time??{},e.lng,t.event.utcOffsetHours),n=Math.max((t.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),s=i?.getTime(),a=s===void 0||e?.lat===void 0||e.lng===void 0?"":`${this.aircraftSource.id}|${s}+${n}|${e.lat.toFixed(3)},${e.lng.toFixed(3)}|${Math.round(e.elevationM??0)}`;if(this.traffic?.key===a)return this.traffic.set;if(a===""||s===void 0||e?.lat===void 0||e.lng===void 0){this.traffic={key:a,status:"outside"};return}let o=Ve.aircraftProviders.get(this.aircraftSource.id);if(o||Ve.aircraftProviders.set(this.aircraftSource.id,o=this.aircraftSource.create()),o.mayCover&&!o.mayCover(s+n)){this.traffic={key:a,status:"outside"};return}const c={key:a,status:"loading",startMs:s,observer:{lat:e.lat,lng:e.lng}};this.traffic=c;const l={lat:e.lat,lng:e.lng,heightM:e.elevationM??0},h=Gi.MAX_GAP_S*1e3,u=Ve.SOUND_LOOKBACK_MS,d={lat:e.lat,lng:e.lng,elevationM:e.elevationM??0},f=(p,v)=>p.TrafficDecor.from(c.tracks??[],l,s,p.TrafficDecor.MAX_OBJECTS,{models:v,sunElevationAt:m=>this.sunElevationAt(m,d)});o.between(l,s-u,s+n+h).then(async p=>{if(this.traffic!==c)return;if(p.status!=="found"){c.status=p.status==="outside"?"outside":"unavailable",this.announceTraffic();return}let v;try{v=await Ve.loadTrafficRuntime()}catch{this.traffic===c&&(c.status="unavailable",this.announceTraffic());return}this.traffic===c&&(c.status="ready",c.tracks=p.tracks,c.set=f(v),this.startAircraftSound(c,v),this.announceTraffic(),this.describeTraffic(o,c,v,f),c.set.shown>0&&this.readUpperAir(c,v,s-u,s+n+h))})}trafficSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||i.startMs===void 0||!i.observer)return e;for(const[a,o]of n.presence){if(t<o.fromMs||t>o.untilMs)continue;const c=n.flights.get(a),l=c?Gi.positionAt(c,i.startMs+t):void 0;l&&e.set(a,{heightM:l.geo.heightM,sunElevationDeg:gn.sunElevationDeg(s,i.observer,l.geo)})}return e}trafficTooltipAt(t,e){const i=this.sceneRenderer.pickTrafficAt(t,e),n=i?this.trafficInfoAt(i):void 0;if(!n)return;const s=this.naming,a=Ve.trafficRuntime;return a?.TrafficTooltip.text(n,s.names?.trafficTooltip??a.TrafficTooltip.ENGLISH,o=>s.towards(o))}trafficInfoAt(t){const e=this.traffic,i=e?.set?.flights.get(t);if(!e||!i||e.startMs===void 0||!e.observer)return;const n=Ve.trafficRuntime;if(!n)return;const s=e.descriptions?.get(Bn.keyOf(i)),a=Ze(this.ufoElement.sighting,this.lastTimeMs),o={lat:e.observer.lat,lng:e.observer.lng,heightM:a?.elevationM??0},c=n.AmbientNoise.dbA(uc(this.ufoElement.sighting,this.lastTimeMs)),l=n.TrafficInfos.at(i,s,o,e.startMs+this.lastTimeMs,{ambientDbA:c}),h=l&&this.contrailAt(t,this.lastTimeMs);return l&&h?{...l,contrail:h}:l}contrailAt(t,e){const i=this.traffic?.contrails?.find(s=>s.id===t);if(!i)return;let n;for(const s of i.points){if(s.tMs>e)break;n=s}return n?.forms?{persistent:n.persistent,iceRelativeHumidity:n.iceRelativeHumidity}:void 0}startAircraftSound(t,e){this.aircraftAudio||(this.aircraftAudio=new e.AircraftAudio,this.aircraftAudio.setLevel(this.ufoElement.level),this.interacted&&this.aircraftAudio.resume(),this.aircraftAudio.setPaused(this.ufoElement.playbackState!=="playing")),this.sortOutAudible(t,e)}sortOutAudible(t,e){!t.set||!t.observer||(t.audible=e.TrafficSound.candidates(t.set.flights,t.descriptions??new Map,Bn.keyOf,{...t.observer,heightM:0},{ambientDbA:e.AmbientNoise.BASE_DB_A}))}pushAircraftSound(t,e){const i=this.aircraftAudio;if(!i)return;const n=Ve.trafficRuntime,s=this.traffic,a=s?.set;if(!n||!s||!a||!s.audible||s.startMs===void 0||!s.observer){i.setVoices([]);return}const o=Ze(t,e),c={lat:s.observer.lat,lng:s.observer.lng,heightM:o?.elevationM??0},l=uc(t,e),h=n.TrafficSound.voices(s.audible,a.flights,s.descriptions??new Map,Bn.keyOf,c,s.startMs+e,{ambientDbA:n.AmbientNoise.dbA(l),referenceAmplitude:n.AmbientNoise.referenceAmplitude(l)});i.setVoices(h,o?.headingDeg??0)}announceTraffic(){this.isConnected&&(this.dispatchEvent(new CustomEvent(vA)),this.updateAstronomy(this.lastTimeMs))}async describeTraffic(t,e,i,n){if(!t.describe||!e.set||!e.tracks)return;const s=new Set([...e.set.flights.values()].map(l=>Bn.keyOf(l))),a=e.tracks.filter(l=>s.has(Bn.keyOf(l))&&l.points.length>0),o=new Map,c=new Map;await Promise.all(a.map(async l=>{const h=new Date(l.points[0].t).toISOString().slice(0,10),u=await t.describe(l,h).catch(()=>{});u&&(c.set(Bn.keyOf(l),u),o.set(Bn.keyOf(l),i.AircraftModels.of(u)))})),!(this.traffic!==e||o.size===0)&&(e.descriptions=c,e.models=o,e.set=n(i,o),this.planContrails(e,i),this.sortOutAudible(e,i),this.announceTraffic())}async readUpperAir(t,e,i,n){if(!t.observer)return;const s=this.upperAirSource??e.UPPER_AIR_SOURCES[0];let a=Ve.upperAirProviders.get(s.id);a||Ve.upperAirProviders.set(s.id,a=s.create());const o=await a.between(t.observer,i,n);this.traffic!==t||o.status!=="found"||(t.air=o.samples,t.airSource=o.source,this.planContrails(t,e),this.announceTraffic())}planContrails(t,e){!t.set||!t.air||t.startMs===void 0||(t.contrails=e.AircraftContrails.plan(t.set,t.models,t.air,t.startMs))}contrailSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||!i.contrails?.length||i.startMs===void 0||!i.observer)return e;for(const a of i.contrails){const o=n.presence.get(a.id),c=n.flights.get(a.id);if(!o||!c)continue;const l=Gi.positionAt(c,i.startMs+Math.min(o.untilMs,Math.max(o.fromMs,t)));l&&e.set(a.id,{heightM:l.geo.heightM,sunElevationDeg:gn.sunElevationDeg(s,i.observer,l.geo)})}return e}sunElevationAt(t,e){const i=tl("Sun",new Date(t.t),e);return gn.sunElevationDeg(i,e,t)}upperAirSource;setUpperAirSource(t){t.id!==this.upperAirSource?.id&&(this.upperAirSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}setAircraftSource(t){t.id!==this.aircraftSource.id&&(this.aircraftSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}get aircraftState(){const t=this.traffic?.contrails?.length?this.upperAirSource??Ve.trafficRuntime?.UPPER_AIR_SOURCES[0]:void 0;return{trailCredit:t&&{credit:t.credit,creditUrl:t.creditUrl},status:this.traffic?.status??"none",total:this.traffic?.set?.total??0,shown:this.traffic?.set?.shown??0,credit:this.aircraftSource.credit,creditUrl:this.aircraftSource.creditUrl}}get fireballState(){return{status:this.fireballs?.status??"none",records:this.fireballs?.records??[]}}ensureSatellites(t){const e=t?String(t.getTime()):"";if(e===this.satellitesFor)return;this.satellitesFor=e,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!t){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=a=>{i===this.satelliteRequest&&(this.satelliteStatus=a,this.isConnected&&this.dispatchEvent(new CustomEvent(mA)))},s=Ve.tleArchive;(async()=>{if(!await s.covers(t))return n("outside");const[a,o]=await Promise.all([s.at(t),an(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!a)return n("unavailable");this.satellites={snapshot:a,passes:new o.SatellitePasses(a.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const t=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:t?.coverage,credit:t?.credit,creditUrl:t?.creditUrl}}satellitePassesDuring(t){const e=this.satellites,i=this.ufoElement.sighting,n=Ze(i,0),s=i.event.place?.[0],a=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!e||a===void 0||o===void 0)return[];const c=yo(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(t,0),4*36e5),h={lat:a,lng:o,elevationM:n?.elevationM??0},u=JSON.stringify([this.satellitesFor,c.getTime(),a,o,h.elevationM,l]);if(this.satellitePassesMemo?.key===u)return this.satellitePassesMemo.passes;const d=Math.max(10,Math.ceil(l/1e3/600)),f=e.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(t,e){const i=sA.brightestAt(t,e);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(t){const e=this.ufoElement.sighting;e!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=e);const i=e.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,a=this.projectionAt(t),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(t,p);if(!v)continue;const m={...v,bounds:{...v.bounds,x:v.bounds.x+s.x,y:v.bounds.y+s.y}};o.set(p,m);const g=v.aim?this.sceneRenderer.screenPointOf(kn.directionOf(v.aim,this.directionScratch)):{ndcX:(m.bounds.x+m.bounds.width/2)/n.width*2-1,ndcY:-((m.bounds.y+m.bounds.height/2)/n.height*2-1)},_=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,y=_?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(_||v.aim)&&l.delete(p);const M=v.angular?.widthDeg??a.pxToDeg(v.bounds.width),b=this.sizeEstimateOf(p);b.add(M,y);const w=Ho.of(e,p);c.set(p,Bi.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:w&&M>0?De.distanceMAt(w.widthM,M):void 0,range:b.distanceRangeAt(M),crossing:y}))}for(const[p,v]of o)for(const[m,g]of o){if(m===p||g.transparency>=1||g.bounds.width*g.bounds.height<=v.bounds.width*v.bounds.height||!(v.bounds.x>=g.bounds.x&&v.bounds.y>=g.bounds.y&&v.bounds.x+v.bounds.width<=g.bounds.x+g.bounds.width&&v.bounds.y+v.bounds.height<=g.bounds.y+g.bounds.height))continue;const y=c.get(m);y&&c.set(p,{distanceM:y.distanceM*.999,basis:y.basis});break}this.depths=c;const h=i.sourceIds,u=[];for(const[p,v]of o)u.push({sourceId:p,shape:v,distanceM:c.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:l.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(Ze(e,t)?.rollDeg??0)+be.bodyAt(e,t,this.ufoElement.steadyObserver).rollDeg;this.sceneRenderer.setPhenomena(u,{projection:a,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:mi.starPointsOf(e.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(t){this.interpretationShown=t,this.updateAstronomy(this.lastTimeMs)}get accountInTheRound(){return this.inTheRound}set accountInTheRound(t){this.inTheRound=t}get compareAccount(){return this.comparing}set compareAccount(t){this.comparing=t,this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(t,e,i){const n=this.sceneRenderer.bodyGround,s=ie.eyeOf(this.ufoElement.sighting,i,n);return s?ie.lineOfSightMeetsGround(s,t,e,n):void 0}bodyReading(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=d=>ie.eyeOf(n,d,i),a=new ie(t,i,s).at(e),o=s(e);if(!a||!o)return;const c=a.eastM-o.eastM,l=a.northM-o.northM,h=a.upM-o.upM,u=Math.hypot(c,l);return{azimuthDeg:(Math.atan2(c,l)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,u)*180/Math.PI,distanceM:Math.hypot(u,h),eastM:a.eastM,northM:a.northM,aboveGroundM:a.upM-a.sizeM.heightM/2-i.heightAt(a.eastM,a.northM),sizeM:a.sizeM,attitude:a.attitude,appearance:a.appearance}}directionToBody(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>ie.eyeOf(n,p,i),a=new ie(t,i,s),o=a.at(e)?e:t.track[0]?.t,c=o===void 0?void 0:a.at(o),l=o===void 0?void 0:s(o);if(!c||!l)return;const h=c.eastM-l.eastM,u=c.northM-l.northM,d=c.upM-l.upM,f=Math.hypot(h,u);if(!(f===0&&d===0))return{azimuthDeg:(Math.atan2(h,u)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(d,f)*180/Math.PI}}placeBodiesAt(t,e){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],a=[];const o=this.sceneRenderer.bodyGround,c=p=>ie.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new ie(p,o,c).at(t)).filter(p=>p!==void 0));const l=eo(n,t),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,t/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(t):void 0;if(d&&(a=new si(n.timeline).at(t,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=a,!e)return;const f=JSON.stringify(a);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(MA,{detail:a})))}setDistanceHypothesis(t,e){e===void 0||!(e>0)?this.distanceHypotheses.delete(t):this.distanceHypotheses.set(t,e),this.updateAstronomy(this.lastTimeMs)}depthOf(t){return this.depths.get(t)}sizeRangeOf(t){return this.sizeEstimateOf(t).sizeRange}distanceRangeAt(t,e){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(e,t);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(e).pxToDeg(i.bounds.width);return this.sizeEstimateOf(t).distanceRangeAt(n)}sizeContradictory(t){return this.sizeEstimateOf(t).contradictory}updateMeteorShower(t,e){this.ensureMeteorSchedule(t),this.sceneRenderer.updateMeteors(e)}updateLightning(t,e,i){if(this.ensureLightningSchedule(t),this.sceneRenderer.updateLightning(e),i)return;const n=this.lastLightningT;if(this.lastLightningT=e,n===void 0||e<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(a=>a.t>n&&a.t<=e).pop();s&&eo(t,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(t){const e=eo(t,0).precipitationIntensity,i=`${this.meteorInputsOf(t)}|${e}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=t.event.time,s=t.event.place?.[0],a=n?.year!==void 0?yo(n,s?.lng??0,t.event.utcOffsetHours):void 0,o=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,c=Math.round((a?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=gi.schedule({durationMs:o,seed:c,intensity:e}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(t){const e=this.meteorInputsOf(t);e!==this.meteorScheduleFor&&(this.meteorScheduleFor=e,this.scheduleMeteors(t))}meteorInputsOf(t){const e=t.event.place?.[0],i=t.event.time;return JSON.stringify([e?.lat,e?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,t.event.utcOffsetHours,t.event.durationSeconds,t.timeline.duration])}scheduleMeteors(t){const e=t.event.place?.[0],i=t.event.time,n=e?.lat!==void 0&&e.lng!==void 0&&i?.year!==void 0?yo(i,e.lng,t.event.utcOffsetHours):void 0;if(!n||e?.lat===void 0||e.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:e.lat,lng:e.lng,elevationM:0},a=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(e.lat*1e3),c=ai.schedule({ratePerHour:ai.observedRatePerHour(ai.apexPosition(n,s).altitudeDeg),durationMs:a,velocityKmS:ai.TYPICAL_VELOCITY_KM_S,seed:o}),l=Nu.activeAt(n).map(u=>{const d=Nu.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:Nu.observedRatePerHour(u.zhr,d.altitudeDeg,u.shower.populationIndex)}}).sort((u,d)=>d.rate-u.rate)[0];if(!l||l.rate<=0){this.sceneRenderer.setMeteorShower(c,0,0);return}const h=za.schedule({ratePerHour:l.rate,durationMs:a,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(t){this.ensureMeteorSchedule(this.ufoElement.sighting);const e=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,a)=>a.brightness-s.brightness);if(e.length===0)return;const i=e[t%e.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(t){const e=this.ufoElement.sighting,i=e.instrument,n=i.frame,s=Ze(e,t),a=s?.fNumber??i.fNumber;if(!n||a===void 0)return;const o=mi.focalLengthMmFor(i,sn.fovOf(e,t));if(o!==void 0)return{focalLengthMm:o,fNumber:a,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(t){const e=this.ufoElement.sighting;return Is.of(e.instrument,De.CANVAS_HEIGHT_PX,sn.fovOf(e,t))}sizeEstimateOf(t){let e=this.sizeEstimates.get(t);return e||(e=new rA,this.sizeEstimates.set(t,e)),e}}const h0="rr0-scene";function EA(){Ng(),customElements.get(h0)||customElements.define(h0,Ve)}EA();export{FA as $,Fa as A,qi as B,st as C,m2 as D,NA as E,he as F,Ce as G,rx as H,zA as I,Ll as J,Xi as K,GA as L,Tt as M,UA as N,m1 as O,r1 as P,Ip as Q,me as R,Fs as S,Bn as T,nx as U,R as V,OA as W,CA as X,rn as Y,dp as Z,He as _,Gi as a,BA as a0,i1 as a1,Ca as a2,vc as a3,yh as a4,$2 as a5,ce as a6,Ie as a7,Zo as a8,Zu as a9,Ti as aa,Us as ab,tx as ac,Ta as ad,Ae as ae,IA as af,PA as ag,a1 as ah,LA as ai,nn as aj,Yn as ak,s1 as al,wp as am,$M as an,Il as ao,Td as ap,Ei as aq,f1 as ar,O0 as as,N0 as at,oe as au,ha as av,ac as aw,HA as b,Ul as c,ue as d,as as e,Mt as f,pt as g,ae as h,Qt as i,DA as j,ne as k,ss as l,yl as m,ks as n,ho as o,Je as p,Zt as q,yn as r,Yi as s,hA as t,nf as u,AA as v,RA as w,TA as x,rc as y,kA as z};