@rr0/ufoathome 0.64.0 → 0.64.1
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.
|
@@ -6155,7 +6155,7 @@ void main()
|
|
|
6155
6155
|
if (ice <= 0.0) discard;
|
|
6156
6156
|
gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
|
|
6157
6157
|
}
|
|
6158
|
-
`,transparent:!0,blending:Ii,depthWrite:!1,side:Ne,fog:!1}),this.object=new Ot(new je(Ei.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)<Ei.ALTITUDE_STEP_DEG)||!(Math.abs(e-this.mappedAlignment)<Ei.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)<Ei.LEAP_ALTITUDE_DEG)||!(Math.abs(e-this.pendingAlignment)<Ei.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)<Ei.ALTITUDE_STEP_DEG&&Math.abs(e-this.pendingAlignment)<Ei.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?Ei.URGENT_BUDGET_MS:Ei.BUDGET_MS;do this.sky.trace(Ei.RAYS_PER_BATCH);while(this.sky.tracedRays<Ei.RAYS&&performance.now()-e<i);if(this.sky.tracedRays>=Ei.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]=is.toHalfFloat(e[n]),this.texels[i+1]=is.toHalfFloat(e[n+1]),this.texels[i+2]=is.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 ri{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=ri.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(ri.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=ri.MAX_CONCURRENT*ri.SEGMENTS*ri.VERTICES_PER_SEGMENT;this.positions=new Float32Array(t*3),this.colors=new Float32Array(t*3);const e=new me;e.setAttribute("position",new se(this.positions,3)),e.setAttribute("color",new se(this.colors,3)),e.setDrawRange(0,0),this.object=new Ot(e,new sn({vertexColors:!0,transparent:!0,blending:Ii,depthWrite:!1,fog:!1,side:en})),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=tr.aliveAt(this.meteors,t).slice(0,ri.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=li(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=S=>v*S**1.6,g=S=>this.onSphere(c,p,d+(u-d)*S),y=S=>ri.RADIUS*((ri.MIN_HALF_WIDTH_DEG+ri.BRIGHT_HALF_WIDTH_DEG*s.brightness*S)*Math.PI/180);for(let S=1;S<ri.POINTS;S++){const _=(S-1)/ri.SEGMENTS,w=S/ri.SEGMENTS;n=this.pushRibbon(n,g(_),g(w),y(_),y(w),m(_),m(w))}}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=li(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<ri.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,y)=>g===0?y: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=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)*ri.RADIUS,y:(t.y*s+e.y*a)*ri.RADIUS,z:(t.z*s+e.z*a)*ri.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()}}const oh=Math.PI/180;function Ge(r,t,e,i,n=!1){const s=n?new sn({color:new st(...e)}):new oo({color:new st(...e)}),a=new Ot(t,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const lp=.25,cb=.002,lb=20;function hb(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 Ng=[.32,.32,.3],Og=[1,.85,.5],Ug=[.25,.25,.25],Fg=[1,.97,.85],ub=[.55,.68,.72],Rn=.03,Dn=.05,kg={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 Ri(r,t){return r?.[t]}function Cn(r,t,e,i,n,s,a,o){if(o===void 0)return;const c=new oo({color:new st(...ub),transparent:!0,opacity:o/100}),l=new Ot(new Yi(t,e,i),c);l.position.set(n,s,a),r.add(l)}const Ji=.05,ch=[.6,.58,.53],hp=[.5,.5,.48];function Vr(r,t,e,i,n,s,a,o){const c=new oo({color:new st(...o),side:Ne}),l=new Ot(new Yi(t,e,i),c);l.position.set(n,s,a),r.add(l)}function db(r,t,e,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(t?Vr(r,p,v,Ji,m,o+g,a,c):Vr(r,Ji,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 zg(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?Vr(r,v,u,Ji,0,h,m,ch):Vr(r,Ji,u,v,m,h,0,ch):db(r,p,v,u,f,s,m,h,ch)};d(a,!0,t*2,-e+Ji),d(o,!0,t*2,e-Ji),d(c,!1,e*2,-t+Ji),d(l,!1,e*2,t-Ji),Vr(r,t*2,Ji,e*2,0,i+Ji,0,hp),Vr(r,t*2,Ji,e*2,0,n-Ji,0,hp)}function ju(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:-In};case"front-right":return{x:t-i,z:-In};case"behind-left":return{x:-(t-i),z:In};case"behind-right":return{x:t-i,z:In}}}function Bg(r,t,e,i,n,s,a){const o=ed();o.scale.setScalar(i),o.rotation.y=kg[t];const{x:c,z:l}=ju(t,n,s,a);o.position.set(c,e,l),r.add(o)}const Qu=6,td=6,bs=3,Da=1.4,Ca=bs*.5,Hg=1.2,Gg=.35,fb=.75,pb=1.6;function up(r,t,e,i){const n=new Le,s=Math.max(1,r+1),a=s*bs;Ge(n,new Yi(Qu,a,td),[.55,.54,.5],a/2);const o=Qu/2,c=td/2;for(let l=0;l<s;l++){const h=l*bs+bs/2;Cn(n,Da,Ca,Dn,0,h,-c-Rn,Ri(t,"front")),Cn(n,Da,Ca,Dn,0,h,c+Rn,Ri(t,"behind")),Cn(n,Dn,Ca,Da,-o-Rn,h,0,Ri(t,"left")),Cn(n,Dn,Ca,Da,o+Rn,h,0,Ri(t,"right"))}if(e){const l=Math.min(Math.max(i??0,0),s-1);Bg(n,e,l*bs,.72,o,c,Hg);const h=u=>Ri(t,u)!==void 0?[{main:Da,center:0}]:[];zg(n,o,c,l*bs,(l+1)*bs,Ca,h("front"),h("behind"),h("left"),h("right"))}return n}function dp(){const r=new Le,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 je(n,10,7);a.scale(1,.85,1),a.translate(e,0,i),Ge(r,a,[.26,.28,.17],s)}return r}function fp(){const r=new Le;return Ge(r,new zn(.15,.22,2,8),[.32,.22,.14],1),Ge(r,new la(1.4,3,8),[.16,.32,.14],3.5),r}const pp=.275,mb=.35,gb=.9,vb=34,Mb=8,xb=1.4;function mp(){const r=new Le,t=new je(pp,7,3,0,Math.PI*2,0,Math.PI/2);t.scale(1,mb/pp,1);const e=hi.repeatOnGrid(t,vb,gb,Mb,xb),i=Ge(r,e,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=e.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=t.getAttribute("position").count,t.dispose(),r}function gp(){const r=new Le,t=new je(1,7,3,0,Math.PI*2,0,Math.PI/2);return Ge(r,t,[.38,.36,.32],0),r}function vp(r){const t=new Le;return Ge(t,new zn(.05,.08,5,8),[.28,.28,.3],2.5),Ge(t,new je(.25,12,8),r?Og:Ng,5.1,!0),t}const _b=[.08,.08,.08],ys=.8,kr=1,En=1.7,lh=.6,Hs=.4,ac=1.2,Or=.7,In=.5,yb=En;function Mp(r,t,e){const i=new Le;Ge(i,new Yi(1.8,1.4,4.2),[.45,.14,.14],.7),Ge(i,new Yi(ys*2,lh,kr*2),[.4,.12,.12],En);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Ge(i,new zn(.4,.4,.3,12),_b,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?Fg:Ug;for(const s of[-.7,.7])Ge(i,new je(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(Cn(i,ac,Hs,Dn,0,En,-kr-Rn,Ri(t,"front")),Cn(i,ac,Hs,Dn,0,En,kr+Rn,Ri(t,"behind")),Cn(i,Dn,Hs,Or,-ys-Rn,En,-In,Ri(t,"front-left")),Cn(i,Dn,Hs,Or,-ys-Rn,En,In,Ri(t,"behind-left")),Cn(i,Dn,Hs,Or,ys+Rn,En,-In,Ri(t,"front-right")),Cn(i,Dn,Hs,Or,ys+Rn,En,In,Ri(t,"behind-right")),e){Bg(i,e,fb,.5,ys,kr,Gg);const s=(c,l)=>{const h=[];return Ri(t,c)!==void 0&&h.push({main:Or,center:-In}),Ri(t,l)!==void 0&&h.push({main:Or,center:In}),h},a=Ri(t,"front")!==void 0?[{main:ac,center:0}]:[],o=Ri(t,"behind")!==void 0?[{main:ac,center:0}]:[];zg(i,ys,kr,En-lh/2,En+lh/2,Hs,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const xp=new Map;function _p(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 hh(r,t){return t>1e-6?r/t:1}const Vg=[.95,.9,.82],yp=[.72,.74,.78];function Sp(){const r=new Le;Ge(r,new zn(.25,.3,1.5,10),yp,.75),Ge(r,new je(.26,10,8),yp,1.74);const t=Ge(r,new la(.07,.16,8),Vg,1.74);return t.rotation.x=-Math.PI/2,t.position.z=-.22,r}function ed(){const r=new Le;Ge(r,new zn(.25,.3,1.5,10),[.3,.3,.35],.75),Ge(r,new je(.22,10,8),[.62,.52,.46],1.72);const t=Ge(r,new la(.07,.16,8),Vg,1.72);return t.rotation.x=-Math.PI/2,t.position.z=-.2,r}const Sb=17,bp=18.5,uh=[.16,.16,.18];function wp(){const r=new Le,t=Ge(r,new zn(1.8,1.8,bp*2,10),uh,0);t.rotation.x=Math.PI/2,Ge(r,new Yi(Sb*2,.5,4.5),uh,0);const e=Ge(r,new Yi(.4,5.5,4),uh,3);return e.position.z=-bp+2,r}class hi{static groundUnderFootprint(t,e,i,n,s,a=0){const o=hi.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));let u=-1/0;for(let d=0;d<l;d++){const f=(d/(l-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=e+Math.sin(c)*f+Math.cos(c)*v,g=i-Math.cos(c)*f+Math.sin(c)*v;u=Math.max(u,s(m,g))}}return Number.isFinite(u)?u:s(e,i)}static occupantView(t){const e=t.witnessSide;if(!e)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=t.kind==="vehicle"?ju(e,ys,kr,Gg):ju(e,Qu/2,td/2,Hg),s=t.kind==="vehicle"?yb:(t.occupiedFloor??0)*bs+pb,a=(t.headingDeg??0)-kg[e]/oh,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(hi.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 y=0;y<n;y++)for(let S=0;S<e;S++,m++){const _=v+y*s,w=p+S*i;for(let E=0;E<l;E++){const R=(m*l+E)*3;u[R]=a.getX(E)+_,u[R+1]=a.getY(E),u[R+2]=a.getZ(E)+w,d[R]=o.getX(E),d[R+1]=o.getY(E),d[R+2]=o.getZ(E)}for(let E=0;E<c.count;E++)f[m*c.count+E]=c.getX(E)+m*l}const g=new me;return g.setAttribute("position",new pe(u,3)),g.setAttribute("normal",new pe(d,3)),g.setIndex(new xd(f,1)),g}static fitCropToGround(t,e){t.updateMatrixWorld(!0);const i=new D;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 Yt().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"?up(t.floors??g0,t.windows,t.witnessSide,t.occupiedFloor):t.kind==="tree"?fp():t.kind==="shrub"?dp():t.kind==="crop"?mp():t.kind==="mound"?gp():t.kind==="streetlight"?vp(e):t.kind==="vehicle"?Mp(e,t.windows,t.witnessSide):t.kind==="aircraft"?wp():t.kind==="entity"?Sp():ed();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Le;return i.name=hi.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*oh),this.addLights(s,t.lights),t.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(t){const e=t.sizeM;if(!e)return new D(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new D(e.widthM===void 0?1:hh(e.widthM,i.widthM),e.heightM===void 0?1:hh(e.heightM,i.heightM),e.lengthM===void 0?1:hh(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??g0)+1):0,n=`${t}:${i}`,s=xp.get(n);if(s)return s;const a=t==="building"?up(i-1,void 0,void 0,void 0):t==="tree"?fp():t==="shrub"?dp():t==="crop"?mp():t==="mound"?gp():t==="streetlight"?vp(!1):t==="vehicle"?Mp(!1,void 0,void 0):t==="aircraft"?wp():t==="entity"?Sp():ed(),o=new rn().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),xp.set(n,c),c}static usesModel(t){return t.model!==void 0&&!(t.witnessSide!==void 0&&dm(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),a=new Le;a.name=hi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*oh,i.updateMatrixWorld(!0);const o=new rn().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=_p(e.sizeM,c)??_p(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new D).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 Ot&&(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 exemptFromFog(t){t.traverse(e=>{if(!(e instanceof Ot))return;const i=e.material;i.fog=!1,i.needsUpdate=!0})}static addLights(t,e){for(const i of e??[]){const n=hb(i.color),s=Ge(t,new je(lp,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}}static setLights(t,e,i,n,s=0){if(!e||e.length===0)return;const a=new Map(e.map(c=>[c.id,c])),o=Math.max(1,n*cb/lp);for(const c of t.children){if(!(c instanceof Ot))continue;const l=c.userData.lightId;if(!l)continue;const h=a.get(l);if(!h)continue;const u=s>0?fm(h,i,i+s):B1(h,i)?1:0;c.visible=u>0;const d=c.material,f=c.userData.lightColor;if(f){const p=s>0?u*lb*(h.intensity??1):u;d.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}c.scale.setScalar(o)}}static setLit(t,e,i){const n=e==="streetlight"?i?Og:Ng:i?Fg:Ug;t.traverse(s=>{const a=s.userData;!(s instanceof Ot)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(t){t.traverse(e=>{if(!(e instanceof Ot))return;e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const dh="https://ufoathome.org/models/index.json";class bb{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??wb()}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 wb(){const r=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return r&&r!==dh?[r,dh]:[dh]}const Eb=[{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 bb}];async function Ep(r){const{GLTFLoader:t}=await Ec(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-BumifFuq.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const Wg=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class Qi{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new Qm(16777215,0,0,2);glow;constructor(){const t=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);t.push(new yt(Math.max(o,1e-4),-a))}const i=new il(t,48),n=new ge({uniforms:{uTime:{value:0},uColor:{value:new st(1,1,1)},uTipColor:{value:new st(1,1,1)}},vertexShader:Qi.VERTEX,fragmentShader:Qi.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,side:en,toneMapped:!1});this.mesh=new Ot(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=Qi.RENDER_ORDER,this.mesh.visible=!1,this.glow=new Ot(new an(2,2),new ge({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:Qi.GLOW_VERTEX,fragmentShader:Qi.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=Qi.RENDER_ORDER,this.glow.visible=!1}static glowFor(t,e){const i=Math.max(t.widthM*.6,e*Qi.GLOW_MIN_ANGLE_RAD),n=.7*t.widthM*t.lengthM,s=Qi.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:t.luminanceCdM2*Math.min(Qi.GLOW_MAX_SHARE,n/s)}}shine(t,e){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=t,this.glow.material.uniforms.uColor.value.setRGB(e[0],e[1],e[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(t,e,i,n){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.quaternion.set(e.x,e.y,e.z,e.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(t,e,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(t[0],t[1],t[2]),n.uTipColor.value.setRGB(e[0],e[1],e[2]),n.uTime.value=i}illuminate(t,e){this.light.intensity=t,this.light.color.setRGB(e[0],e[1],e[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
6158
|
+
`,transparent:!0,blending:Ii,depthWrite:!1,side:Ne,fog:!1}),this.object=new Ot(new je(Ei.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)<Ei.ALTITUDE_STEP_DEG)||!(Math.abs(e-this.mappedAlignment)<Ei.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)<Ei.LEAP_ALTITUDE_DEG)||!(Math.abs(e-this.pendingAlignment)<Ei.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)<Ei.ALTITUDE_STEP_DEG&&Math.abs(e-this.pendingAlignment)<Ei.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?Ei.URGENT_BUDGET_MS:Ei.BUDGET_MS;do this.sky.trace(Ei.RAYS_PER_BATCH);while(this.sky.tracedRays<Ei.RAYS&&performance.now()-e<i);if(this.sky.tracedRays>=Ei.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]=is.toHalfFloat(e[n]),this.texels[i+1]=is.toHalfFloat(e[n+1]),this.texels[i+2]=is.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 ri{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=ri.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(ri.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=ri.MAX_CONCURRENT*ri.SEGMENTS*ri.VERTICES_PER_SEGMENT;this.positions=new Float32Array(t*3),this.colors=new Float32Array(t*3);const e=new me;e.setAttribute("position",new se(this.positions,3)),e.setAttribute("color",new se(this.colors,3)),e.setDrawRange(0,0),this.object=new Ot(e,new sn({vertexColors:!0,transparent:!0,blending:Ii,depthWrite:!1,fog:!1,side:en})),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=tr.aliveAt(this.meteors,t).slice(0,ri.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=li(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=S=>v*S**1.6,g=S=>this.onSphere(c,p,d+(u-d)*S),y=S=>ri.RADIUS*((ri.MIN_HALF_WIDTH_DEG+ri.BRIGHT_HALF_WIDTH_DEG*s.brightness*S)*Math.PI/180);for(let S=1;S<ri.POINTS;S++){const _=(S-1)/ri.SEGMENTS,w=S/ri.SEGMENTS;n=this.pushRibbon(n,g(_),g(w),y(_),y(w),m(_),m(w))}}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=li(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<ri.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,y)=>g===0?y: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=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)*ri.RADIUS,y:(t.y*s+e.y*a)*ri.RADIUS,z:(t.z*s+e.z*a)*ri.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()}}const oh=Math.PI/180;function Ge(r,t,e,i,n=!1){const s=n?new sn({color:new st(...e)}):new oo({color:new st(...e)}),a=new Ot(t,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const lp=.25,cb=.002,lb=20;function hb(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 Ng=[.32,.32,.3],Og=[1,.85,.5],Ug=[.25,.25,.25],Fg=[1,.97,.85],ub=[.55,.68,.72],Rn=.03,Dn=.05,kg={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 Ri(r,t){return r?.[t]}function Cn(r,t,e,i,n,s,a,o){if(o===void 0)return;const c=new oo({color:new st(...ub),transparent:!0,opacity:o/100}),l=new Ot(new Yi(t,e,i),c);l.position.set(n,s,a),r.add(l)}const Ji=.05,ch=[.6,.58,.53],hp=[.5,.5,.48];function Vr(r,t,e,i,n,s,a,o){const c=new oo({color:new st(...o),side:Ne}),l=new Ot(new Yi(t,e,i),c);l.position.set(n,s,a),r.add(l)}function db(r,t,e,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(t?Vr(r,p,v,Ji,m,o+g,a,c):Vr(r,Ji,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 zg(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?Vr(r,v,u,Ji,0,h,m,ch):Vr(r,Ji,u,v,m,h,0,ch):db(r,p,v,u,f,s,m,h,ch)};d(a,!0,t*2,-e+Ji),d(o,!0,t*2,e-Ji),d(c,!1,e*2,-t+Ji),d(l,!1,e*2,t-Ji),Vr(r,t*2,Ji,e*2,0,i+Ji,0,hp),Vr(r,t*2,Ji,e*2,0,n-Ji,0,hp)}function ju(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:-In};case"front-right":return{x:t-i,z:-In};case"behind-left":return{x:-(t-i),z:In};case"behind-right":return{x:t-i,z:In}}}function Bg(r,t,e,i,n,s,a){const o=ed();o.scale.setScalar(i),o.rotation.y=kg[t];const{x:c,z:l}=ju(t,n,s,a);o.position.set(c,e,l),r.add(o)}const Qu=6,td=6,bs=3,Da=1.4,Ca=bs*.5,Hg=1.2,Gg=.35,fb=.75,pb=1.6;function up(r,t,e,i){const n=new Le,s=Math.max(1,r+1),a=s*bs;Ge(n,new Yi(Qu,a,td),[.55,.54,.5],a/2);const o=Qu/2,c=td/2;for(let l=0;l<s;l++){const h=l*bs+bs/2;Cn(n,Da,Ca,Dn,0,h,-c-Rn,Ri(t,"front")),Cn(n,Da,Ca,Dn,0,h,c+Rn,Ri(t,"behind")),Cn(n,Dn,Ca,Da,-o-Rn,h,0,Ri(t,"left")),Cn(n,Dn,Ca,Da,o+Rn,h,0,Ri(t,"right"))}if(e){const l=Math.min(Math.max(i??0,0),s-1);Bg(n,e,l*bs,.72,o,c,Hg);const h=u=>Ri(t,u)!==void 0?[{main:Da,center:0}]:[];zg(n,o,c,l*bs,(l+1)*bs,Ca,h("front"),h("behind"),h("left"),h("right"))}return n}function dp(){const r=new Le,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 je(n,10,7);a.scale(1,.85,1),a.translate(e,0,i),Ge(r,a,[.26,.28,.17],s)}return r}function fp(){const r=new Le;return Ge(r,new zn(.15,.22,2,8),[.32,.22,.14],1),Ge(r,new la(1.4,3,8),[.16,.32,.14],3.5),r}const pp=.275,mb=.35,gb=.9,vb=34,Mb=8,xb=1.4;function mp(){const r=new Le,t=new je(pp,7,3,0,Math.PI*2,0,Math.PI/2);t.scale(1,mb/pp,1);const e=hi.repeatOnGrid(t,vb,gb,Mb,xb),i=Ge(r,e,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=e.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=t.getAttribute("position").count,t.dispose(),r}function gp(){const r=new Le,t=new je(1,7,3,0,Math.PI*2,0,Math.PI/2);return Ge(r,t,[.38,.36,.32],0),r}function vp(r){const t=new Le;return Ge(t,new zn(.05,.08,5,8),[.28,.28,.3],2.5),Ge(t,new je(.25,12,8),r?Og:Ng,5.1,!0),t}const _b=[.08,.08,.08],ys=.8,kr=1,En=1.7,lh=.6,Hs=.4,ac=1.2,Or=.7,In=.5,yb=En;function Mp(r,t,e){const i=new Le;Ge(i,new Yi(1.8,1.4,4.2),[.45,.14,.14],.7),Ge(i,new Yi(ys*2,lh,kr*2),[.4,.12,.12],En);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Ge(i,new zn(.4,.4,.3,12),_b,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?Fg:Ug;for(const s of[-.7,.7])Ge(i,new je(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(Cn(i,ac,Hs,Dn,0,En,-kr-Rn,Ri(t,"front")),Cn(i,ac,Hs,Dn,0,En,kr+Rn,Ri(t,"behind")),Cn(i,Dn,Hs,Or,-ys-Rn,En,-In,Ri(t,"front-left")),Cn(i,Dn,Hs,Or,-ys-Rn,En,In,Ri(t,"behind-left")),Cn(i,Dn,Hs,Or,ys+Rn,En,-In,Ri(t,"front-right")),Cn(i,Dn,Hs,Or,ys+Rn,En,In,Ri(t,"behind-right")),e){Bg(i,e,fb,.5,ys,kr,Gg);const s=(c,l)=>{const h=[];return Ri(t,c)!==void 0&&h.push({main:Or,center:-In}),Ri(t,l)!==void 0&&h.push({main:Or,center:In}),h},a=Ri(t,"front")!==void 0?[{main:ac,center:0}]:[],o=Ri(t,"behind")!==void 0?[{main:ac,center:0}]:[];zg(i,ys,kr,En-lh/2,En+lh/2,Hs,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const xp=new Map;function _p(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 hh(r,t){return t>1e-6?r/t:1}const Vg=[.95,.9,.82],yp=[.72,.74,.78];function Sp(){const r=new Le;Ge(r,new zn(.25,.3,1.5,10),yp,.75),Ge(r,new je(.26,10,8),yp,1.74);const t=Ge(r,new la(.07,.16,8),Vg,1.74);return t.rotation.x=-Math.PI/2,t.position.z=-.22,r}function ed(){const r=new Le;Ge(r,new zn(.25,.3,1.5,10),[.3,.3,.35],.75),Ge(r,new je(.22,10,8),[.62,.52,.46],1.72);const t=Ge(r,new la(.07,.16,8),Vg,1.72);return t.rotation.x=-Math.PI/2,t.position.z=-.2,r}const Sb=17,bp=18.5,uh=[.16,.16,.18];function wp(){const r=new Le,t=Ge(r,new zn(1.8,1.8,bp*2,10),uh,0);t.rotation.x=Math.PI/2,Ge(r,new Yi(Sb*2,.5,4.5),uh,0);const e=Ge(r,new Yi(.4,5.5,4),uh,3);return e.position.z=-bp+2,r}class hi{static groundUnderFootprint(t,e,i,n,s,a=0){const o=hi.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));let u=-1/0;for(let d=0;d<l;d++){const f=(d/(l-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=e+Math.sin(c)*f+Math.cos(c)*v,g=i-Math.cos(c)*f+Math.sin(c)*v;u=Math.max(u,s(m,g))}}return Number.isFinite(u)?u:s(e,i)}static occupantView(t){const e=t.witnessSide;if(!e)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=t.kind==="vehicle"?ju(e,ys,kr,Gg):ju(e,Qu/2,td/2,Hg),s=t.kind==="vehicle"?yb:(t.occupiedFloor??0)*bs+pb,a=(t.headingDeg??0)-kg[e]/oh,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(hi.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 y=0;y<n;y++)for(let S=0;S<e;S++,m++){const _=v+y*s,w=p+S*i;for(let E=0;E<l;E++){const R=(m*l+E)*3;u[R]=a.getX(E)+_,u[R+1]=a.getY(E),u[R+2]=a.getZ(E)+w,d[R]=o.getX(E),d[R+1]=o.getY(E),d[R+2]=o.getZ(E)}for(let E=0;E<c.count;E++)f[m*c.count+E]=c.getX(E)+m*l}const g=new me;return g.setAttribute("position",new pe(u,3)),g.setAttribute("normal",new pe(d,3)),g.setIndex(new xd(f,1)),g}static fitCropToGround(t,e){t.updateMatrixWorld(!0);const i=new D;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 Yt().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"?up(t.floors??g0,t.windows,t.witnessSide,t.occupiedFloor):t.kind==="tree"?fp():t.kind==="shrub"?dp():t.kind==="crop"?mp():t.kind==="mound"?gp():t.kind==="streetlight"?vp(e):t.kind==="vehicle"?Mp(e,t.windows,t.witnessSide):t.kind==="aircraft"?wp():t.kind==="entity"?Sp():ed();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Le;return i.name=hi.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*oh),this.addLights(s,t.lights),t.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(t){const e=t.sizeM;if(!e)return new D(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new D(e.widthM===void 0?1:hh(e.widthM,i.widthM),e.heightM===void 0?1:hh(e.heightM,i.heightM),e.lengthM===void 0?1:hh(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??g0)+1):0,n=`${t}:${i}`,s=xp.get(n);if(s)return s;const a=t==="building"?up(i-1,void 0,void 0,void 0):t==="tree"?fp():t==="shrub"?dp():t==="crop"?mp():t==="mound"?gp():t==="streetlight"?vp(!1):t==="vehicle"?Mp(!1,void 0,void 0):t==="aircraft"?wp():t==="entity"?Sp():ed(),o=new rn().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),xp.set(n,c),c}static usesModel(t){return t.model!==void 0&&!(t.witnessSide!==void 0&&dm(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),a=new Le;a.name=hi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*oh,i.updateMatrixWorld(!0);const o=new rn().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=_p(e.sizeM,c)??_p(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new D).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 Ot&&(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 exemptFromFog(t){t.traverse(e=>{if(!(e instanceof Ot))return;const i=e.material;i.fog=!1,i.needsUpdate=!0})}static addLights(t,e){for(const i of e??[]){const n=hb(i.color),s=Ge(t,new je(lp,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}}static setLights(t,e,i,n,s=0){if(!e||e.length===0)return;const a=new Map(e.map(c=>[c.id,c])),o=Math.max(1,n*cb/lp);for(const c of t.children){if(!(c instanceof Ot))continue;const l=c.userData.lightId;if(!l)continue;const h=a.get(l);if(!h)continue;const u=s>0?fm(h,i,i+s):B1(h,i)?1:0;c.visible=u>0;const d=c.material,f=c.userData.lightColor;if(f){const p=s>0?u*lb*(h.intensity??1):u;d.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}c.scale.setScalar(o)}}static setLit(t,e,i){const n=e==="streetlight"?i?Og:Ng:i?Fg:Ug;t.traverse(s=>{const a=s.userData;!(s instanceof Ot)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(t){t.traverse(e=>{if(!(e instanceof Ot))return;e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const dh="https://ufoathome.org/models/index.json";class bb{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??wb()}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 wb(){const r=`?v=${encodeURIComponent("0.64.1")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==dh?[t,dh]:[dh]).map(e=>e+r)}const Eb=[{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 bb}];async function Ep(r){const{GLTFLoader:t}=await Ec(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-BumifFuq.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const Wg=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class Qi{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new Qm(16777215,0,0,2);glow;constructor(){const t=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);t.push(new yt(Math.max(o,1e-4),-a))}const i=new il(t,48),n=new ge({uniforms:{uTime:{value:0},uColor:{value:new st(1,1,1)},uTipColor:{value:new st(1,1,1)}},vertexShader:Qi.VERTEX,fragmentShader:Qi.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,side:en,toneMapped:!1});this.mesh=new Ot(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=Qi.RENDER_ORDER,this.mesh.visible=!1,this.glow=new Ot(new an(2,2),new ge({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:Qi.GLOW_VERTEX,fragmentShader:Qi.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=Qi.RENDER_ORDER,this.glow.visible=!1}static glowFor(t,e){const i=Math.max(t.widthM*.6,e*Qi.GLOW_MIN_ANGLE_RAD),n=.7*t.widthM*t.lengthM,s=Qi.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:t.luminanceCdM2*Math.min(Qi.GLOW_MAX_SHARE,n/s)}}shine(t,e){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=t,this.glow.material.uniforms.uColor.value.setRGB(e[0],e[1],e[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(t,e,i,n){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.quaternion.set(e.x,e.y,e.z,e.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(t,e,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(t[0],t[1],t[2]),n.uTipColor.value.setRGB(e[0],e[1],e[2]),n.uTime.value=i}illuminate(t,e){this.light.intensity=t,this.light.color.setRGB(e[0],e[1],e[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
6159
6159
|
uniform float uRadius;
|
|
6160
6160
|
varying vec2 vOffset;
|
|
6161
6161
|
void main() {
|
|
@@ -6574,7 +6574,7 @@ void main()
|
|
|
6574
6574
|
if (ice <= 0.0) discard;
|
|
6575
6575
|
gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
|
|
6576
6576
|
}
|
|
6577
|
-
`,transparent:!0,blending:Ii,depthWrite:!1,side:Nt,fog:!1}),this.object=new Oe(new jt(Ei.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(e){this.hostedByDeck=e,this.show(this.shown)}show(e){this.shown=e,this.object.visible=e&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=e?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(e){this.urgent=e}set onReady(e){this.onRepaint=e}update(e,t,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(e.x,e.y,e.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(t,a)}requestMap(e,t){if(!(!(Math.abs(e-this.mappedAltitudeDeg)<Ei.ALTITUDE_STEP_DEG)||!(Math.abs(t-this.mappedAlignment)<Ei.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(e,t)){this.next=void 0;return}if(!(!(Math.abs(e-this.pendingAltitudeDeg)<Ei.LEAP_ALTITUDE_DEG)||!(Math.abs(t-this.pendingAlignment)<Ei.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:e,alignment:t};return}}this.next=void 0,this.pendingAltitudeDeg=e,this.pendingAlignment=t,this.sky.begin(e,t),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(e,t){return this.tracing&&Math.abs(e-this.pendingAltitudeDeg)<Ei.ALTITUDE_STEP_DEG&&Math.abs(t-this.pendingAlignment)<Ei.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const e=()=>{if(this.workHandle=void 0,!this.tracing)return;const t=performance.now(),i=this.urgent?Ei.URGENT_BUDGET_MS:Ei.BUDGET_MS;do this.sky.trace(Ei.RAYS_PER_BATCH);while(this.sky.tracedRays<Ei.RAYS&&performance.now()-t<i);if(this.sky.tracedRays>=Ei.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(e)};this.workHandle=requestAnimationFrame(e)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const t=this.sky.harvest().data;for(let i=0,n=0;n<t.length;i+=4,n+=3)this.texels[i]=rs.toHalfFloat(t[n]),this.texels[i+1]=rs.toHalfFloat(t[n+1]),this.texels[i+2]=rs.toHalfFloat(t[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 ri{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=ri.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(ri.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 e=ri.MAX_CONCURRENT*ri.SEGMENTS*ri.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new mt;t.setAttribute("position",new st(this.positions,3)),t.setAttribute("color",new st(this.colors,3)),t.setDrawRange(0,0),this.object=new Oe(t,new sn({vertexColors:!0,transparent:!0,blending:Ii,depthWrite:!1,fog:!1,side:tn})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(e,t,i){this.meteors=e,this.radiantAltitudeDeg=t,this.radiantAzimuthDeg=i}update(e){const t=this.object.geometry;if(this.meteors.length===0){t.setDrawRange(0,0);return}const i=rr.aliveAt(this.meteors,e).slice(0,ri.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=li(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=S=>v*S**1.6,g=S=>this.onSphere(c,p,d+(u-d)*S),_=S=>ri.RADIUS*((ri.MIN_HALF_WIDTH_DEG+ri.BRIGHT_HALF_WIDTH_DEG*s.brightness*S)*Math.PI/180);for(let S=1;S<ri.POINTS;S++){const y=(S-1)/ri.SEGMENTS,w=S/ri.SEGMENTS;n=this.pushRibbon(n,g(y),g(w),_(y),_(w),m(y),m(w))}}t.setDrawRange(0,n),t.getAttribute("position").needsUpdate=!0,t.getAttribute("color").needsUpdate=!0}midpointOf(e){const t=this.radiantOf(e);if(!t)return;const i=li(t.altitudeDeg,t.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,e.bearingDeg),o=this.onSphere(i,a,e.fromRadiantDeg+e.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(e){return e.radiant?e.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(e,t,i,n,s,a,o){const c=this.normalise(this.cross(this.normalise(t),this.normalise(this.subtract(i,t))));for(let l=0;l<ri.ACROSS-1;l++){const h=l-1,u=l,d=this.across(t,c,n,h),f=this.across(i,c,s,h),p=this.across(t,c,n,u),v=this.across(i,c,s,u),m=(g,_)=>g===0?_:0;e=this.push(e,d,m(h,a)),e=this.push(e,f,m(h,o)),e=this.push(e,p,m(u,a)),e=this.push(e,f,m(h,o)),e=this.push(e,v,m(u,o)),e=this.push(e,p,m(u,a))}return e}across(e,t,i,n){return{x:e.x+t.x*i*n,y:e.y+t.y*i*n,z:e.z+t.z*i*n}}push(e,t,i){const n=e*3;this.positions[n]=t.x,this.positions[n+1]=t.y,this.positions[n+2]=t.z;const s=Math.max(0,Math.min(1,i));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,e+1}turn(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:e.x*s+t.x*a,y:e.y*s+t.y*a,z:e.z*s+t.z*a}}onSphere(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(e.x*s+t.x*a)*ri.RADIUS,y:(e.y*s+t.y*a)*ri.RADIUS,z:(e.z*s+t.z*a)*ri.RADIUS}}basisAround(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(e,t));return[i,this.normalise(this.cross(e,i))]}subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}const vh=Math.PI/180;function Vt(r,e,t,i,n=!1){const s=n?new sn({color:new se(...t)}):new mo({color:new se(...t)}),a=new Oe(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const Ep=.25,Bw=.002,Hw=20;function Gw(r){const e=/^#([0-9a-f]{6})$/i.exec(r);if(!e)return[1,1,1];const t=parseInt(e[1],16);return[(t>>16&255)/255,(t>>8&255)/255,(t&255)/255]}const t1=[.32,.32,.3],i1=[1,.85,.5],n1=[.25,.25,.25],s1=[1,.97,.85],Vw=[.55,.68,.72],Dn=.03,Cn=.05,r1={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 Ri(r,e){return r?.[e]}function In(r,e,t,i,n,s,a,o){if(o===void 0)return;const c=new mo({color:new se(...Vw),transparent:!0,opacity:o/100}),l=new Oe(new $i(e,t,i),c);l.position.set(n,s,a),r.add(l)}const ji=.05,Mh=[.6,.58,.53],Ap=[.5,.5,.48];function Kr(r,e,t,i,n,s,a,o){const c=new mo({color:new se(...o),side:Nt}),l=new Oe(new $i(e,t,i),c);l.position.set(n,s,a),r.add(l)}function Ww(r,e,t,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?Kr(r,p,v,ji,m,o+g,a,c):Kr(r,ji,v,p,a,o+g,m,c))};h(t,l,0,i/2-l/2),h(t,l,0,-(i/2-l/2));const u=[...n].sort((p,v)=>p.center-v.center);let d=-t/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=t/2-d;h(f,s,d+f/2,0)}function a1(r,e,t,i,n,s,a,o,c,l){const h=(i+n)/2,u=n-i,d=(f,p,v,m)=>{f.length===0?p?Kr(r,v,u,ji,0,h,m,Mh):Kr(r,ji,u,v,m,h,0,Mh):Ww(r,p,v,u,f,s,m,h,Mh)};d(a,!0,e*2,-t+ji),d(o,!0,e*2,t-ji),d(c,!1,t*2,-e+ji),d(l,!1,t*2,e-ji),Kr(r,e*2,ji,t*2,0,i+ji,0,Ap),Kr(r,e*2,ji,t*2,0,n-ji,0,Ap)}function hd(r,e,t,i){switch(r){case"front":return{x:0,z:-(t-i)};case"behind":return{x:0,z:t-i};case"left":return{x:-(e-i),z:0};case"right":return{x:e-i,z:0};case"front-left":return{x:-(e-i),z:-Pn};case"front-right":return{x:e-i,z:-Pn};case"behind-left":return{x:-(e-i),z:Pn};case"behind-right":return{x:e-i,z:Pn}}}function o1(r,e,t,i,n,s,a){const o=fd();o.scale.setScalar(i),o.rotation.y=r1[e];const{x:c,z:l}=hd(e,n,s,a);o.position.set(c,t,l),r.add(o)}const ud=6,dd=6,Rs=3,Na=1.4,Oa=Rs*.5,c1=1.2,l1=.35,Xw=.75,qw=1.6;function Tp(r,e,t,i){const n=new Lt,s=Math.max(1,r+1),a=s*Rs;Vt(n,new $i(ud,a,dd),[.55,.54,.5],a/2);const o=ud/2,c=dd/2;for(let l=0;l<s;l++){const h=l*Rs+Rs/2;In(n,Na,Oa,Cn,0,h,-c-Dn,Ri(e,"front")),In(n,Na,Oa,Cn,0,h,c+Dn,Ri(e,"behind")),In(n,Cn,Oa,Na,-o-Dn,h,0,Ri(e,"left")),In(n,Cn,Oa,Na,o+Dn,h,0,Ri(e,"right"))}if(t){const l=Math.min(Math.max(i??0,0),s-1);o1(n,t,l*Rs,.72,o,c,c1);const h=u=>Ri(e,u)!==void 0?[{main:Na,center:0}]:[];a1(n,o,c,l*Rs,(l+1)*Rs,Oa,h("front"),h("behind"),h("left"),h("right"))}return n}function Rp(){const r=new Lt,e=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[t,i,n,s]of e){const a=new jt(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),Vt(r,a,[.26,.28,.17],s)}return r}function Dp(){const r=new Lt;return Vt(r,new Bn(.15,.22,2,8),[.32,.22,.14],1),Vt(r,new pa(1.4,3,8),[.16,.32,.14],3.5),r}const Cp=.275,Yw=.35,$w=.9,Kw=34,Zw=8,Jw=1.4;function Ip(){const r=new Lt,e=new jt(Cp,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,Yw/Cp,1);const t=hi.repeatOnGrid(e,Kw,$w,Zw,Jw),i=Vt(r,t,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Pp(){const r=new Lt,e=new jt(1,7,3,0,Math.PI*2,0,Math.PI/2);return Vt(r,e,[.38,.36,.32],0),r}function Lp(r){const e=new Lt;return Vt(e,new Bn(.05,.08,5,8),[.28,.28,.3],2.5),Vt(e,new jt(.25,12,8),r?i1:t1,5.1,!0),e}const jw=[.08,.08,.08],As=.8,Wr=1,An=1.7,xh=.6,Xs=.4,fc=1.2,Hr=.7,Pn=.5,Qw=An;function Np(r,e,t){const i=new Lt;Vt(i,new $i(1.8,1.4,4.2),[.45,.14,.14],.7),Vt(i,new $i(As*2,xh,Wr*2),[.4,.12,.12],An);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Vt(i,new Bn(.4,.4,.3,12),jw,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?s1:n1;for(const s of[-.7,.7])Vt(i,new jt(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(In(i,fc,Xs,Cn,0,An,-Wr-Dn,Ri(e,"front")),In(i,fc,Xs,Cn,0,An,Wr+Dn,Ri(e,"behind")),In(i,Cn,Xs,Hr,-As-Dn,An,-Pn,Ri(e,"front-left")),In(i,Cn,Xs,Hr,-As-Dn,An,Pn,Ri(e,"behind-left")),In(i,Cn,Xs,Hr,As+Dn,An,-Pn,Ri(e,"front-right")),In(i,Cn,Xs,Hr,As+Dn,An,Pn,Ri(e,"behind-right")),t){o1(i,t,Xw,.5,As,Wr,l1);const s=(c,l)=>{const h=[];return Ri(e,c)!==void 0&&h.push({main:Hr,center:-Pn}),Ri(e,l)!==void 0&&h.push({main:Hr,center:Pn}),h},a=Ri(e,"front")!==void 0?[{main:fc,center:0}]:[],o=Ri(e,"behind")!==void 0?[{main:fc,center:0}]:[];a1(i,As,Wr,An-xh/2,An+xh/2,Xs,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Op=new Map;function Up(r,e){if(!r)return;const t=[[r.lengthM,e.lengthM],[r.heightM,e.heightM],[r.widthM,e.widthM]];for(const[i,n]of t)if(i!==void 0&&n>1e-6)return i/n}function yh(r,e){return e>1e-6?r/e:1}const h1=[.95,.9,.82],Fp=[.72,.74,.78];function kp(){const r=new Lt;Vt(r,new Bn(.25,.3,1.5,10),Fp,.75),Vt(r,new jt(.26,10,8),Fp,1.74);const e=Vt(r,new pa(.07,.16,8),h1,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function fd(){const r=new Lt;Vt(r,new Bn(.25,.3,1.5,10),[.3,.3,.35],.75),Vt(r,new jt(.22,10,8),[.62,.52,.46],1.72);const e=Vt(r,new pa(.07,.16,8),h1,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const e5=17,zp=18.5,_h=[.16,.16,.18];function Bp(){const r=new Lt,e=Vt(r,new Bn(1.8,1.8,zp*2,10),_h,0);e.rotation.x=Math.PI/2,Vt(r,new $i(e5*2,.5,4.5),_h,0);const t=Vt(r,new $i(.4,5.5,4),_h,3);return t.position.z=-zp+2,r}class hi{static groundUnderFootprint(e,t,i,n,s,a=0){const o=hi.sizeOf(e);if(a>o.heightM)return s(t,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));let u=-1/0;for(let d=0;d<l;d++){const f=(d/(l-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=t+Math.sin(c)*f+Math.cos(c)*v,g=i-Math.cos(c)*f+Math.sin(c)*v;u=Math.max(u,s(m,g))}}return Number.isFinite(u)?u:s(t,i)}static occupantView(e){const t=e.witnessSide;if(!t)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=e.kind==="vehicle"?hd(t,As,Wr,l1):hd(t,ud/2,dd/2,c1),s=e.kind==="vehicle"?Qw:(e.occupiedFloor??0)*Rs+qw,a=(e.headingDeg??0)-r1[t]/vh,o=this.scaleFor(e);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(e){return e.getObjectByName(hi.BODY_NAME)??e}static repeatOnGrid(e,t,i,n,s){const a=e.getAttribute("position"),o=e.getAttribute("normal"),c=e.getIndex();if(!c)throw new Error("repeatOnGrid needs an indexed geometry");const l=a.count,h=t*n,u=new Float32Array(l*h*3),d=new Float32Array(l*h*3),f=new Uint32Array(c.count*h),p=-((t-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let _=0;_<n;_++)for(let S=0;S<t;S++,m++){const y=v+_*s,w=p+S*i;for(let E=0;E<l;E++){const R=(m*l+E)*3;u[R]=a.getX(E)+y,u[R+1]=a.getY(E),u[R+2]=a.getZ(E)+w,d[R]=o.getX(E),d[R+1]=o.getY(E),d[R+2]=o.getZ(E)}for(let E=0;E<c.count;E++)f[m*c.count+E]=c.getX(E)+m*l}const g=new mt;return g.setAttribute("position",new pt(u,3)),g.setAttribute("normal",new pt(d,3)),g.setIndex(new Id(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new D;e.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 Ye().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=t(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(e,t){e.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(t)})}static build(e,t){const i=e.kind==="building"?Tp(e.floors??g0,e.windows,e.witnessSide,e.occupiedFloor):e.kind==="tree"?Dp():e.kind==="shrub"?Rp():e.kind==="crop"?Ip():e.kind==="mound"?Pp():e.kind==="streetlight"?Lp(t):e.kind==="vehicle"?Np(t,e.windows,e.witnessSide):e.kind==="aircraft"?Bp():e.kind==="entity"?kp():fd();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new Lt;return i.name=hi.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*vh),this.addLights(s,e.lights),e.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(e){const t=e.sizeM;if(!t)return new D(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new D(t.widthM===void 0?1:yh(t.widthM,i.widthM),t.heightM===void 0?1:yh(t.heightM,i.heightM),t.lengthM===void 0?1:yh(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??g0)+1):0,n=`${e}:${i}`,s=Op.get(n);if(s)return s;const a=e==="building"?Tp(i-1,void 0,void 0,void 0):e==="tree"?Dp():e==="shrub"?Rp():e==="crop"?Ip():e==="mound"?Pp():e==="streetlight"?Lp(!1):e==="vehicle"?Np(!1,void 0,void 0):e==="aircraft"?Bp():e==="entity"?kp():fd(),o=new rn().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),Op.set(n,c),c}static usesModel(e){return e.model!==void 0&&!(e.witnessSide!==void 0&&Dm(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new Lt;a.name=hi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*vh,i.updateMatrixWorld(!0);const o=new rn().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=Up(t.sizeM,c)??Up(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new D).multiplyScalar(l);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=t.kind==="aircraft"?h.y:o.min.y*l,i.traverse(u=>{u instanceof Oe&&(u.castShadow=!0,u.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):e.add(a),this.dispose(s)}static sizeOf(e){const t=this.naturalSize(e.kind,e.floors);return{widthM:e.sizeM?.widthM??t.widthM,lengthM:e.sizeM?.lengthM??t.lengthM,heightM:e.sizeM?.heightM??t.heightM}}static exemptFromFog(e){e.traverse(t=>{if(!(t instanceof Oe))return;const i=t.material;i.fog=!1,i.needsUpdate=!0})}static addLights(e,t){for(const i of t??[]){const n=Gw(i.color),s=Vt(e,new jt(Ep,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}}static setLights(e,t,i,n,s=0){if(!t||t.length===0)return;const a=new Map(t.map(c=>[c.id,c])),o=Math.max(1,n*Bw/Ep);for(const c of e.children){if(!(c instanceof Oe))continue;const l=c.userData.lightId;if(!l)continue;const h=a.get(l);if(!h)continue;const u=s>0?Im(h,i,i+s):$1(h,i)?1:0;c.visible=u>0;const d=c.material,f=c.userData.lightColor;if(f){const p=s>0?u*Hw*(h.intensity??1):u;d.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}c.scale.setScalar(o)}}static setLit(e,t,i){const n=t==="streetlight"?i?i1:t1:i?s1:n1;e.traverse(s=>{const a=s.userData;!(s instanceof Oe)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(e){e.traverse(t=>{if(!(t instanceof Oe))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const Sh="https://ufoathome.org/models/index.json";class t5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??i5()}async entries(e){const t=await this.load();return e?t.filter(i=>i.kind===e):t}async entry(e){return(await this.load()).find(t=>t.id===e)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const e of this.indexUrls){const t=await this.fetchIndex(e);if(t)return t}return[]}async fetchIndex(e){try{const t=await this.fetchImpl(e);if(!t.ok)return;const i=await t.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,e).href})):void 0}catch{return}}}function i5(){const r=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return r&&r!==Sh?[r,Sh]:[Sh]}const n5=[{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 t5}];async function Hp(r){const{GLTFLoader:e}=await as(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-D3g0zZHB.js");return{GLTFLoader:i}},[],import.meta.url),t=new e;return new Promise((i,n)=>{t.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const u1=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class en{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new yg(16777215,0,0,2);glow;constructor(){const e=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);e.push(new _e(Math.max(o,1e-4),-a))}const i=new dl(e,48),n=new gt({uniforms:{uTime:{value:0},uColor:{value:new se(1,1,1)},uTipColor:{value:new se(1,1,1)}},vertexShader:en.VERTEX,fragmentShader:en.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,side:tn,toneMapped:!1});this.mesh=new Oe(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=en.RENDER_ORDER,this.mesh.visible=!1,this.glow=new Oe(new an(2,2),new gt({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:en.GLOW_VERTEX,fragmentShader:en.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=en.RENDER_ORDER,this.glow.visible=!1}static glowFor(e,t){const i=Math.max(e.widthM*.6,t*en.GLOW_MIN_ANGLE_RAD),n=.7*e.widthM*e.lengthM,s=en.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:e.luminanceCdM2*Math.min(en.GLOW_MAX_SHARE,n/s)}}shine(e,t){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=e,this.glow.material.uniforms.uColor.value.setRGB(t[0],t[1],t[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(e,t,i,n){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.quaternion.set(t.x,t.y,t.z,t.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(e,t,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(e[0],e[1],e[2]),n.uTipColor.value.setRGB(t[0],t[1],t[2]),n.uTime.value=i}illuminate(e,t){this.light.intensity=e,this.light.color.setRGB(t[0],t[1],t[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
6577
|
+
`,transparent:!0,blending:Ii,depthWrite:!1,side:Nt,fog:!1}),this.object=new Oe(new jt(Ei.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(e){this.hostedByDeck=e,this.show(this.shown)}show(e){this.shown=e,this.object.visible=e&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=e?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(e){this.urgent=e}set onReady(e){this.onRepaint=e}update(e,t,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(e.x,e.y,e.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(t,a)}requestMap(e,t){if(!(!(Math.abs(e-this.mappedAltitudeDeg)<Ei.ALTITUDE_STEP_DEG)||!(Math.abs(t-this.mappedAlignment)<Ei.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(e,t)){this.next=void 0;return}if(!(!(Math.abs(e-this.pendingAltitudeDeg)<Ei.LEAP_ALTITUDE_DEG)||!(Math.abs(t-this.pendingAlignment)<Ei.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:e,alignment:t};return}}this.next=void 0,this.pendingAltitudeDeg=e,this.pendingAlignment=t,this.sky.begin(e,t),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(e,t){return this.tracing&&Math.abs(e-this.pendingAltitudeDeg)<Ei.ALTITUDE_STEP_DEG&&Math.abs(t-this.pendingAlignment)<Ei.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const e=()=>{if(this.workHandle=void 0,!this.tracing)return;const t=performance.now(),i=this.urgent?Ei.URGENT_BUDGET_MS:Ei.BUDGET_MS;do this.sky.trace(Ei.RAYS_PER_BATCH);while(this.sky.tracedRays<Ei.RAYS&&performance.now()-t<i);if(this.sky.tracedRays>=Ei.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(e)};this.workHandle=requestAnimationFrame(e)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const t=this.sky.harvest().data;for(let i=0,n=0;n<t.length;i+=4,n+=3)this.texels[i]=rs.toHalfFloat(t[n]),this.texels[i+1]=rs.toHalfFloat(t[n+1]),this.texels[i+2]=rs.toHalfFloat(t[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 ri{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=ri.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(ri.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 e=ri.MAX_CONCURRENT*ri.SEGMENTS*ri.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new mt;t.setAttribute("position",new st(this.positions,3)),t.setAttribute("color",new st(this.colors,3)),t.setDrawRange(0,0),this.object=new Oe(t,new sn({vertexColors:!0,transparent:!0,blending:Ii,depthWrite:!1,fog:!1,side:tn})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(e,t,i){this.meteors=e,this.radiantAltitudeDeg=t,this.radiantAzimuthDeg=i}update(e){const t=this.object.geometry;if(this.meteors.length===0){t.setDrawRange(0,0);return}const i=rr.aliveAt(this.meteors,e).slice(0,ri.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const c=li(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=S=>v*S**1.6,g=S=>this.onSphere(c,p,d+(u-d)*S),_=S=>ri.RADIUS*((ri.MIN_HALF_WIDTH_DEG+ri.BRIGHT_HALF_WIDTH_DEG*s.brightness*S)*Math.PI/180);for(let S=1;S<ri.POINTS;S++){const y=(S-1)/ri.SEGMENTS,w=S/ri.SEGMENTS;n=this.pushRibbon(n,g(y),g(w),_(y),_(w),m(y),m(w))}}t.setDrawRange(0,n),t.getAttribute("position").needsUpdate=!0,t.getAttribute("color").needsUpdate=!0}midpointOf(e){const t=this.radiantOf(e);if(!t)return;const i=li(t.altitudeDeg,t.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,e.bearingDeg),o=this.onSphere(i,a,e.fromRadiantDeg+e.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(e){return e.radiant?e.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(e,t,i,n,s,a,o){const c=this.normalise(this.cross(this.normalise(t),this.normalise(this.subtract(i,t))));for(let l=0;l<ri.ACROSS-1;l++){const h=l-1,u=l,d=this.across(t,c,n,h),f=this.across(i,c,s,h),p=this.across(t,c,n,u),v=this.across(i,c,s,u),m=(g,_)=>g===0?_:0;e=this.push(e,d,m(h,a)),e=this.push(e,f,m(h,o)),e=this.push(e,p,m(u,a)),e=this.push(e,f,m(h,o)),e=this.push(e,v,m(u,o)),e=this.push(e,p,m(u,a))}return e}across(e,t,i,n){return{x:e.x+t.x*i*n,y:e.y+t.y*i*n,z:e.z+t.z*i*n}}push(e,t,i){const n=e*3;this.positions[n]=t.x,this.positions[n+1]=t.y,this.positions[n+2]=t.z;const s=Math.max(0,Math.min(1,i));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,e+1}turn(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:e.x*s+t.x*a,y:e.y*s+t.y*a,z:e.z*s+t.z*a}}onSphere(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(e.x*s+t.x*a)*ri.RADIUS,y:(e.y*s+t.y*a)*ri.RADIUS,z:(e.z*s+t.z*a)*ri.RADIUS}}basisAround(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(e,t));return[i,this.normalise(this.cross(e,i))]}subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}const vh=Math.PI/180;function Vt(r,e,t,i,n=!1){const s=n?new sn({color:new se(...t)}):new mo({color:new se(...t)}),a=new Oe(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const Ep=.25,Bw=.002,Hw=20;function Gw(r){const e=/^#([0-9a-f]{6})$/i.exec(r);if(!e)return[1,1,1];const t=parseInt(e[1],16);return[(t>>16&255)/255,(t>>8&255)/255,(t&255)/255]}const t1=[.32,.32,.3],i1=[1,.85,.5],n1=[.25,.25,.25],s1=[1,.97,.85],Vw=[.55,.68,.72],Dn=.03,Cn=.05,r1={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 Ri(r,e){return r?.[e]}function In(r,e,t,i,n,s,a,o){if(o===void 0)return;const c=new mo({color:new se(...Vw),transparent:!0,opacity:o/100}),l=new Oe(new $i(e,t,i),c);l.position.set(n,s,a),r.add(l)}const ji=.05,Mh=[.6,.58,.53],Ap=[.5,.5,.48];function Kr(r,e,t,i,n,s,a,o){const c=new mo({color:new se(...o),side:Nt}),l=new Oe(new $i(e,t,i),c);l.position.set(n,s,a),r.add(l)}function Ww(r,e,t,i,n,s,a,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?Kr(r,p,v,ji,m,o+g,a,c):Kr(r,ji,v,p,a,o+g,m,c))};h(t,l,0,i/2-l/2),h(t,l,0,-(i/2-l/2));const u=[...n].sort((p,v)=>p.center-v.center);let d=-t/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=t/2-d;h(f,s,d+f/2,0)}function a1(r,e,t,i,n,s,a,o,c,l){const h=(i+n)/2,u=n-i,d=(f,p,v,m)=>{f.length===0?p?Kr(r,v,u,ji,0,h,m,Mh):Kr(r,ji,u,v,m,h,0,Mh):Ww(r,p,v,u,f,s,m,h,Mh)};d(a,!0,e*2,-t+ji),d(o,!0,e*2,t-ji),d(c,!1,t*2,-e+ji),d(l,!1,t*2,e-ji),Kr(r,e*2,ji,t*2,0,i+ji,0,Ap),Kr(r,e*2,ji,t*2,0,n-ji,0,Ap)}function hd(r,e,t,i){switch(r){case"front":return{x:0,z:-(t-i)};case"behind":return{x:0,z:t-i};case"left":return{x:-(e-i),z:0};case"right":return{x:e-i,z:0};case"front-left":return{x:-(e-i),z:-Pn};case"front-right":return{x:e-i,z:-Pn};case"behind-left":return{x:-(e-i),z:Pn};case"behind-right":return{x:e-i,z:Pn}}}function o1(r,e,t,i,n,s,a){const o=fd();o.scale.setScalar(i),o.rotation.y=r1[e];const{x:c,z:l}=hd(e,n,s,a);o.position.set(c,t,l),r.add(o)}const ud=6,dd=6,Rs=3,Na=1.4,Oa=Rs*.5,c1=1.2,l1=.35,Xw=.75,qw=1.6;function Tp(r,e,t,i){const n=new Lt,s=Math.max(1,r+1),a=s*Rs;Vt(n,new $i(ud,a,dd),[.55,.54,.5],a/2);const o=ud/2,c=dd/2;for(let l=0;l<s;l++){const h=l*Rs+Rs/2;In(n,Na,Oa,Cn,0,h,-c-Dn,Ri(e,"front")),In(n,Na,Oa,Cn,0,h,c+Dn,Ri(e,"behind")),In(n,Cn,Oa,Na,-o-Dn,h,0,Ri(e,"left")),In(n,Cn,Oa,Na,o+Dn,h,0,Ri(e,"right"))}if(t){const l=Math.min(Math.max(i??0,0),s-1);o1(n,t,l*Rs,.72,o,c,c1);const h=u=>Ri(e,u)!==void 0?[{main:Na,center:0}]:[];a1(n,o,c,l*Rs,(l+1)*Rs,Oa,h("front"),h("behind"),h("left"),h("right"))}return n}function Rp(){const r=new Lt,e=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[t,i,n,s]of e){const a=new jt(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),Vt(r,a,[.26,.28,.17],s)}return r}function Dp(){const r=new Lt;return Vt(r,new Bn(.15,.22,2,8),[.32,.22,.14],1),Vt(r,new pa(1.4,3,8),[.16,.32,.14],3.5),r}const Cp=.275,Yw=.35,$w=.9,Kw=34,Zw=8,Jw=1.4;function Ip(){const r=new Lt,e=new jt(Cp,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,Yw/Cp,1);const t=hi.repeatOnGrid(e,Kw,$w,Zw,Jw),i=Vt(r,t,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Pp(){const r=new Lt,e=new jt(1,7,3,0,Math.PI*2,0,Math.PI/2);return Vt(r,e,[.38,.36,.32],0),r}function Lp(r){const e=new Lt;return Vt(e,new Bn(.05,.08,5,8),[.28,.28,.3],2.5),Vt(e,new jt(.25,12,8),r?i1:t1,5.1,!0),e}const jw=[.08,.08,.08],As=.8,Wr=1,An=1.7,xh=.6,Xs=.4,fc=1.2,Hr=.7,Pn=.5,Qw=An;function Np(r,e,t){const i=new Lt;Vt(i,new $i(1.8,1.4,4.2),[.45,.14,.14],.7),Vt(i,new $i(As*2,xh,Wr*2),[.4,.12,.12],An);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Vt(i,new Bn(.4,.4,.3,12),jw,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?s1:n1;for(const s of[-.7,.7])Vt(i,new jt(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(In(i,fc,Xs,Cn,0,An,-Wr-Dn,Ri(e,"front")),In(i,fc,Xs,Cn,0,An,Wr+Dn,Ri(e,"behind")),In(i,Cn,Xs,Hr,-As-Dn,An,-Pn,Ri(e,"front-left")),In(i,Cn,Xs,Hr,-As-Dn,An,Pn,Ri(e,"behind-left")),In(i,Cn,Xs,Hr,As+Dn,An,-Pn,Ri(e,"front-right")),In(i,Cn,Xs,Hr,As+Dn,An,Pn,Ri(e,"behind-right")),t){o1(i,t,Xw,.5,As,Wr,l1);const s=(c,l)=>{const h=[];return Ri(e,c)!==void 0&&h.push({main:Hr,center:-Pn}),Ri(e,l)!==void 0&&h.push({main:Hr,center:Pn}),h},a=Ri(e,"front")!==void 0?[{main:fc,center:0}]:[],o=Ri(e,"behind")!==void 0?[{main:fc,center:0}]:[];a1(i,As,Wr,An-xh/2,An+xh/2,Xs,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Op=new Map;function Up(r,e){if(!r)return;const t=[[r.lengthM,e.lengthM],[r.heightM,e.heightM],[r.widthM,e.widthM]];for(const[i,n]of t)if(i!==void 0&&n>1e-6)return i/n}function yh(r,e){return e>1e-6?r/e:1}const h1=[.95,.9,.82],Fp=[.72,.74,.78];function kp(){const r=new Lt;Vt(r,new Bn(.25,.3,1.5,10),Fp,.75),Vt(r,new jt(.26,10,8),Fp,1.74);const e=Vt(r,new pa(.07,.16,8),h1,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function fd(){const r=new Lt;Vt(r,new Bn(.25,.3,1.5,10),[.3,.3,.35],.75),Vt(r,new jt(.22,10,8),[.62,.52,.46],1.72);const e=Vt(r,new pa(.07,.16,8),h1,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const e5=17,zp=18.5,_h=[.16,.16,.18];function Bp(){const r=new Lt,e=Vt(r,new Bn(1.8,1.8,zp*2,10),_h,0);e.rotation.x=Math.PI/2,Vt(r,new $i(e5*2,.5,4.5),_h,0);const t=Vt(r,new $i(.4,5.5,4),_h,3);return t.position.z=-zp+2,r}class hi{static groundUnderFootprint(e,t,i,n,s,a=0){const o=hi.sizeOf(e);if(a>o.heightM)return s(t,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));let u=-1/0;for(let d=0;d<l;d++){const f=(d/(l-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=t+Math.sin(c)*f+Math.cos(c)*v,g=i-Math.cos(c)*f+Math.sin(c)*v;u=Math.max(u,s(m,g))}}return Number.isFinite(u)?u:s(t,i)}static occupantView(e){const t=e.witnessSide;if(!t)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=e.kind==="vehicle"?hd(t,As,Wr,l1):hd(t,ud/2,dd/2,c1),s=e.kind==="vehicle"?Qw:(e.occupiedFloor??0)*Rs+qw,a=(e.headingDeg??0)-r1[t]/vh,o=this.scaleFor(e);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(e){return e.getObjectByName(hi.BODY_NAME)??e}static repeatOnGrid(e,t,i,n,s){const a=e.getAttribute("position"),o=e.getAttribute("normal"),c=e.getIndex();if(!c)throw new Error("repeatOnGrid needs an indexed geometry");const l=a.count,h=t*n,u=new Float32Array(l*h*3),d=new Float32Array(l*h*3),f=new Uint32Array(c.count*h),p=-((t-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let _=0;_<n;_++)for(let S=0;S<t;S++,m++){const y=v+_*s,w=p+S*i;for(let E=0;E<l;E++){const R=(m*l+E)*3;u[R]=a.getX(E)+y,u[R+1]=a.getY(E),u[R+2]=a.getZ(E)+w,d[R]=o.getX(E),d[R+1]=o.getY(E),d[R+2]=o.getZ(E)}for(let E=0;E<c.count;E++)f[m*c.count+E]=c.getX(E)+m*l}const g=new mt;return g.setAttribute("position",new pt(u,3)),g.setAttribute("normal",new pt(d,3)),g.setIndex(new Id(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new D;e.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 Ye().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=t(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(e,t){e.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(t)})}static build(e,t){const i=e.kind==="building"?Tp(e.floors??g0,e.windows,e.witnessSide,e.occupiedFloor):e.kind==="tree"?Dp():e.kind==="shrub"?Rp():e.kind==="crop"?Ip():e.kind==="mound"?Pp():e.kind==="streetlight"?Lp(t):e.kind==="vehicle"?Np(t,e.windows,e.witnessSide):e.kind==="aircraft"?Bp():e.kind==="entity"?kp():fd();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new Lt;return i.name=hi.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*vh),this.addLights(s,e.lights),e.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(e){const t=e.sizeM;if(!t)return new D(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new D(t.widthM===void 0?1:yh(t.widthM,i.widthM),t.heightM===void 0?1:yh(t.heightM,i.heightM),t.lengthM===void 0?1:yh(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??g0)+1):0,n=`${e}:${i}`,s=Op.get(n);if(s)return s;const a=e==="building"?Tp(i-1,void 0,void 0,void 0):e==="tree"?Dp():e==="shrub"?Rp():e==="crop"?Ip():e==="mound"?Pp():e==="streetlight"?Lp(!1):e==="vehicle"?Np(!1,void 0,void 0):e==="aircraft"?Bp():e==="entity"?kp():fd(),o=new rn().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),Op.set(n,c),c}static usesModel(e){return e.model!==void 0&&!(e.witnessSide!==void 0&&Dm(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new Lt;a.name=hi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*vh,i.updateMatrixWorld(!0);const o=new rn().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=Up(t.sizeM,c)??Up(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new D).multiplyScalar(l);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=t.kind==="aircraft"?h.y:o.min.y*l,i.traverse(u=>{u instanceof Oe&&(u.castShadow=!0,u.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):e.add(a),this.dispose(s)}static sizeOf(e){const t=this.naturalSize(e.kind,e.floors);return{widthM:e.sizeM?.widthM??t.widthM,lengthM:e.sizeM?.lengthM??t.lengthM,heightM:e.sizeM?.heightM??t.heightM}}static exemptFromFog(e){e.traverse(t=>{if(!(t instanceof Oe))return;const i=t.material;i.fog=!1,i.needsUpdate=!0})}static addLights(e,t){for(const i of t??[]){const n=Gw(i.color),s=Vt(e,new jt(Ep,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}}static setLights(e,t,i,n,s=0){if(!t||t.length===0)return;const a=new Map(t.map(c=>[c.id,c])),o=Math.max(1,n*Bw/Ep);for(const c of e.children){if(!(c instanceof Oe))continue;const l=c.userData.lightId;if(!l)continue;const h=a.get(l);if(!h)continue;const u=s>0?Im(h,i,i+s):$1(h,i)?1:0;c.visible=u>0;const d=c.material,f=c.userData.lightColor;if(f){const p=s>0?u*Hw*(h.intensity??1):u;d.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}c.scale.setScalar(o)}}static setLit(e,t,i){const n=t==="streetlight"?i?i1:t1:i?s1:n1;e.traverse(s=>{const a=s.userData;!(s instanceof Oe)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(e){e.traverse(t=>{if(!(t instanceof Oe))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const Sh="https://ufoathome.org/models/index.json";class t5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??i5()}async entries(e){const t=await this.load();return e?t.filter(i=>i.kind===e):t}async entry(e){return(await this.load()).find(t=>t.id===e)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const e of this.indexUrls){const t=await this.fetchIndex(e);if(t)return t}return[]}async fetchIndex(e){try{const t=await this.fetchImpl(e);if(!t.ok)return;const i=await t.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,e).href})):void 0}catch{return}}}function i5(){const r=`?v=${encodeURIComponent("0.64.1")}`,e=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(e&&e!==Sh?[e,Sh]:[Sh]).map(t=>t+r)}const n5=[{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 t5}];async function Hp(r){const{GLTFLoader:e}=await as(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-D3g0zZHB.js");return{GLTFLoader:i}},[],import.meta.url),t=new e;return new Promise((i,n)=>{t.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const u1=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class en{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new yg(16777215,0,0,2);glow;constructor(){const e=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);e.push(new _e(Math.max(o,1e-4),-a))}const i=new dl(e,48),n=new gt({uniforms:{uTime:{value:0},uColor:{value:new se(1,1,1)},uTipColor:{value:new se(1,1,1)}},vertexShader:en.VERTEX,fragmentShader:en.FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,side:tn,toneMapped:!1});this.mesh=new Oe(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=en.RENDER_ORDER,this.mesh.visible=!1,this.glow=new Oe(new an(2,2),new gt({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:en.GLOW_VERTEX,fragmentShader:en.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Ii,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=en.RENDER_ORDER,this.glow.visible=!1}static glowFor(e,t){const i=Math.max(e.widthM*.6,t*en.GLOW_MIN_ANGLE_RAD),n=.7*e.widthM*e.lengthM,s=en.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:e.luminanceCdM2*Math.min(en.GLOW_MAX_SHARE,n/s)}}shine(e,t){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=e,this.glow.material.uniforms.uColor.value.setRGB(t[0],t[1],t[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(e,t,i,n){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.quaternion.set(t.x,t.y,t.z,t.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(e,t,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(e[0],e[1],e[2]),n.uTipColor.value.setRGB(t[0],t[1],t[2]),n.uTime.value=i}illuminate(e,t){this.light.intensity=e,this.light.color.setRGB(t[0],t[1],t[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
6578
6578
|
uniform float uRadius;
|
|
6579
6579
|
varying vec2 vOffset;
|
|
6580
6580
|
void main() {
|
|
@@ -7105,4 +7105,4 @@ void main() {
|
|
|
7105
7105
|
}
|
|
7106
7106
|
`;let bc;function rE(){if(bc)return bc;const r=128,e=document.createElement("canvas");e.width=r,e.height=r;const t=e.getContext("2d"),i=t.createRadialGradient(r/2,r/2,0,r/2,r/2,r/2);return i.addColorStop(0,"rgba(255,255,255,1)"),i.addColorStop(.4,"rgba(255,255,255,0.35)"),i.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=i,t.fillRect(0,0,r,r),bc=new zn(e),bc}function vm(r){const t=document.createElement("canvas");t.width=128,t.height=128;const i=t.getContext("2d"),n=128/2-2,s=128/2,a=128/2,o="#2e2b26",c="#f4f1e2";i.fillStyle=o,i.beginPath(),i.arc(s,a,n,0,Math.PI*2),i.fill();const l=eo(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 zn(t)}function aE(r){const e=document.createElement("canvas");e.width=128,e.height=128;const t=e.getContext("2d");return t.fillStyle="rgba(0, 0, 0, 0.55)",t.beginPath(),t.arc(64,64,60,0,Math.PI*2),t.fill(),t.fillStyle="#ffffff",t.font="bold 52px sans-serif",t.textAlign="center",t.textBaseline="middle",t.fillText(r,64,68),new zn(e)}function Oh(r){let e=r;return function(){e|=0,e=e+1831565813|0;let i=Math.imul(e^e>>>15,1|e);return i=i+Math.imul(i^i>>>7,61|i)^i,((i^i>>>14)>>>0)/4294967296}}const Uh=7.5,Fh=9;class Tn{static cache=new Map;static load(e){let t=Tn.cache.get(e);return t||(t=fetch(e).then(i=>i.arrayBuffer()).then(i=>Tn.parse(i)),Tn.cache.set(e,t)),t}static upTo(e,t){const i=e.filter((a,o)=>o===0||e[o-1].magnitudeLimit<t);if(i.length<=1)return Tn.load(e[0].url);const n=i.map(a=>a.url).join(`
|
|
7107
7107
|
`);let s=Tn.cache.get(n);return s||(s=Promise.all(i.map(a=>Tn.load(a.url))).then(a=>a.reduce((o,c)=>Tn.concat(o,c))),Tn.cache.set(n,s)),s}static parse(e){const t=e.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=t*Float32Array.BYTES_PER_ELEMENT;return{count:t,ra:new Float32Array(e,0*i,t),dec:new Float32Array(e,1*i,t),mag:new Float32Array(e,2*i,t),ci:new Float32Array(e,3*i,t)}}static concat(e,t){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:e.count+t.count,ra:i(e.ra,t.ra),dec:i(e.dec,t.dec),mag:i(e.mag,t.mag),ci:i(e.ci,t.ci)}}}const oE=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,cE=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,lE=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,hE=20,uE=1;class dE{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};resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(e){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",e);return}}this.context.state==="suspended"&&this.context.resume()}setAmbient(e,t,i){if(this.requested={type:e,intensity:t,windSpeed:i},!this.context)return;this.paused&&(e="none",t=0,i=0);const n=e==="rain"||e==="hail"?e:"none";if(this.ambientVolume=n==="hail"?Math.min(1,t*1.3+.2):n==="rain"?t: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(oE,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/hE,1);const s=i>uE;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(cE,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(e){if(e===this.paused)return;this.paused=e;const{type:t,intensity:i,windSpeed:n}=this.requested;this.setAmbient(t,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(lE,.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.buffers.clear()}applyIfCurrent(e,t,i,n){if(t!==i()){e?.source.stop();return}n(e)}async startLoop(e,t){const i=this.context;if(i)try{const n=await this.getBuffer(e),s=i.createBufferSource();s.buffer=n,s.loop=!0;const a=i.createGain();return a.gain.value=t,s.connect(a).connect(i.destination),s.start(),{source:s,gain:a}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(e,t){const i=this.context;if(i)try{const n=await this.getBuffer(e),s=i.createBufferSource();s.buffer=n;const a=i.createGain();a.gain.value=t,s.connect(a).connect(i.destination),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(e){const t=this.context;if(!t)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(e);return i||(i=fetch(e).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${e}`);return n.arrayBuffer()}).then(n=>t.decodeAudioData(n)),this.buffers.set(e,i)),i}stopSource(e,t){try{e?.stop()}catch{}e?.disconnect(),t?.disconnect()}}class Zn{constructor(e){this.elements=e;const{eccentricity:t,perihelionAu:i}=e,[n,s]=this.perifocalAxes(),a=Math.sqrt(Zn.SUN_GM_AU3_PER_DAY2*(1+t)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,a),this.inverseSemiMajorAxis=(1-t)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(e){const t=e-this.elements.perihelionJd,i=this.universalAnomaly(t),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,a=1-i*i/s*Zn.stumpffC(n),o=t-i*i*i/Math.sqrt(Zn.SUN_GM_AU3_PER_DAY2)*Zn.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(e){const t=this.positionAt(e);return Math.hypot(t.x,t.y,t.z)}universalAnomaly(e){if(e===0)return 0;const t=Math.sign(e),i=Math.sqrt(Zn.SUN_GM_AU3_PER_DAY2)*Math.abs(e),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*Zn.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<Zn.MAX_ITERATIONS&&s-a>1e-13*Math.max(1,s);o++){const c=(a+s)/2;n(c)<i?a=c:s=c}return t*(a+s)/2}perifocalAxes(){const e=this.elements.ascendingNodeDeg*Math.PI/180,t=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(e),s=Math.sin(e),a=Math.cos(t),o=Math.sin(t),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(e,t){return{x:e.x*t,y:e.y*t,z:e.z*t}}static stumpffC(e){if(Math.abs(e)<1e-6)return 1/2-e/24+e*e/720;if(e>0)return(1-Math.cos(Math.sqrt(e)))/e;const t=Math.sqrt(-e);return(Math.cosh(t)-1)/-e}static stumpffS(e){if(Math.abs(e)<1e-6)return 1/6-e/120+e*e/5040;if(e>0){const i=Math.sqrt(e);return(i-Math.sin(i))/(i*i*i)}const t=Math.sqrt(-e);return(Math.sinh(t)-t)/(t*t*t)}}const p1=[{id:"halley-1910",designation:"1P/Halley",name:{en:"Halley's Comet",fr:"comète de Halley"},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:{en:"Comet Brooks",fr:"comète 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:{en:"Comet Skjellerup-Maristany",fr:"comète 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:{en:"Comet de Kock-Paraskevopoulos",fr:"comète 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:{en:"the Southern Comet",fr:"comète australe"},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:{en:"the Eclipse Comet",fr:"comète de l'éclipse"},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:{en:"Comet Arend-Roland",fr:"comète 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:{en:"Comet Mrkos",fr:"comète 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:{en:"Comet Seki-Lines",fr:"comète 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:{en:"Comet Ikeya-Seki",fr:"comète 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:{en:"Comet Bennett",fr:"comète 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:{en:"Comet White-Ortiz-Bolelli",fr:"comète 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:{en:"Comet Kohoutek",fr:"comète 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:{en:"Comet West",fr:"comète 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:{en:"Comet IRAS-Araki-Alcock",fr:"comète 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:{en:"Halley's Comet",fr:"comète de Halley"},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:{en:"Comet Hyakutake",fr:"comète 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:{en:"Comet Hale-Bopp",fr:"comète 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:{en:"Comet McNaught",fr:"comète 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:{en:"Comet Lovejoy",fr:"comète 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:{en:"Comet PANSTARRS",fr:"comète 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:{en:"Comet NEOWISE",fr:"comète 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:{en:"Comet Tsuchinshan-ATLAS",fr:"comète 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 fE{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(e){const t=this.julianDayOf(e);return p1.filter(i=>Math.abs(t-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(e,t){return this.aroundDate(e).map(i=>this.appearanceOf(i,e,t)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(e,t,i){const n=Ot(t),s=this.earthPositionAt(n),a=this.apparentPositionOf(e,2451545+n.tt,s),o=this.subtract(a,s),c=this.length(a),l=this.length(o),h=this.tailEndAt(e,a,s,c,n,t,i),u=this.horizontalOf(o,n,t,i);return{apparition:e,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(e,c,l)}}static magnitudeAt(e,t,i){const n=e.absoluteMagnitude+5*Math.log10(i)+2.5*e.activityExponent*Math.log10(t);return Math.max(n,e.peakMagnitude)}static tailEndAt(e,t,i,n,s,a,o){if(e.tailLengthAu===void 0)return{};const c=1+e.tailLengthAu/n,l=this.subtract({x:t.x*c,y:t.y*c,z:t.z*c},i),h=this.subtract(t,i);return{tailEnd:this.horizontalOf(l,s,a,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(e,t,i){const n=this.orbitOf(e);let s=n.positionAt(t);for(let a=0;a<2;a++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(t-o)}return s}static horizontalOf(e,t,i,n){const s=aa(hw(),new At(e.x,e.y,e.z,t)),a=aa(Qg(t),s),o=Vb(t,new jd(n.lat,n.lng,n.elevationM)),c=new At(a.x-o.x,a.y-o.y,a.z-o.z,t),l=e0(c);return t0(l.ra,l.dec,i,n)}static earthPositionAt(e){return aa(lw(),Os(be.Earth,e))}static julianDayOf(e){return 2451545+Ot(e).tt}static orbitOf(e){const t=this.orbits.get(e.id);if(t)return t;const i=new Zn(e.orbit);return this.orbits.set(e.id,i),i}static subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}static length(e){return Math.hypot(e.x,e.y,e.z)}static angleBetween(e,t){const i=(e.x*t.x+e.y*t.y+e.z*t.z)/(this.length(e)*this.length(t)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const kh=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:{en:"Supernova of 1006",fr:"supernova de 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:{en:"Supernova of 1054",fr:"supernova de 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:{en:"Supernova of 1181",fr:"supernova de 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:{en:"Tycho's Supernova",fr:"supernova de Tycho"},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:{en:"Kepler's Supernova",fr:"supernova de Kepler"},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:{en:"Nova Coronae Borealis 1866",fr:"nova de la Couronne boréale 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:{en:"Nova Aurigae 1891",fr:"nova du Cocher 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:{en:"Nova Persei 1901",fr:"nova de Persée 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:{en:"Nova Geminorum 1912",fr:"nova des Gémeaux 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:{en:"Nova Aquilae 1918",fr:"nova de l'Aigle 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:{en:"Nova Cygni 1920",fr:"nova du Cygne 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:{en:"Nova Pictoris 1925",fr:"nova du Peintre 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:{en:"Nova Herculis 1934",fr:"nova d'Hercule 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:{en:"Nova Lacertae 1936",fr:"nova du Lézard 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:{en:"Nova Puppis 1942",fr:"nova de la Poupe 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:{en:"Nova Coronae Borealis 1946",fr:"nova de la Couronne boréale 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:{en:"Nova Herculis 1960",fr:"nova d'Hercule 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:{en:"Nova Herculis 1963",fr:"nova d'Hercule 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:{en:"Nova Delphini 1967",fr:"nova du Dauphin 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:{en:"Nova Vulpeculae 1968",fr:"nova du Petit Renard 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:{en:"Nova Serpentis 1970",fr:"nova du Serpent 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:{en:"Nova Cygni 1975",fr:"nova du Cygne 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:{en:"Nova Centauri 1986",fr:"nova du Centaure 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:{en:"Supernova 1987A",fr:"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:{en:"Nova Cygni 1992",fr:"nova du Cygne 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:{en:"Nova Velorum 1999",fr:"nova des Voiles 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:{en:"Nova Aquilae 1999",fr:"nova de l'Aigle 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:{en:"Nova Sagittarii 2002",fr:"nova du Sagittaire 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:{en:"Nova Ophiuchi 2006",fr:"nova d'Ophiuchus 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:{en:"Nova Scorpii 2007",fr:"nova du Scorpion 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:{en:"Nova Delphini 2013",fr:"nova du Dauphin 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:{en:"Nova Centauri 2013",fr:"nova du Centaure 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:{en:"Nova Ophiuchi 2021",fr:"nova d'Ophiuchus 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 Mm{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(e){const t=this.julianDayOf(e);return kh.filter(i=>this.magnitudeAt(i,t)!==void 0)}static appearancesAt(e,t){const i=this.julianDayOf(e),n=[];for(const s of kh){const a=this.magnitudeAt(s,i);a!==void 0&&n.push({outburst:s,position:fn.ofJ2000(s.raHours,s.decDeg,e,t),magnitude:a})}return n.sort((s,a)=>s.magnitude-a.magnitude)}static brightestAt(e,t){return this.appearancesAt(e,t)[0]}static byId(e){return kh.find(t=>t.id===e)}static magnitudeAt(e,t){const i=e.lightCurve,n=t-e.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(e){return e.getTime()/864e5+this.UNIX_EPOCH_JD}}const pE=[{id:"quadrantids",code:"QUA",name:{en:"Quadrantids",fr:"Quadrantides"},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:{en:"April Lyrids",fr:"Lyrides d'avril"},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:{en:"eta Aquariids",fr:"Êta Aquarides"},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:{en:"alpha Capricornids",fr:"Alpha Capricornides"},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:{en:"Southern delta Aquariids",fr:"Delta Aquarides du Sud"},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:{en:"Perseids",fr:"Perséides"},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:{en:"Southern Taurids",fr:"Taurides du Sud"},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:{en:"October Draconids",fr:"Draconides d'octobre"},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:{en:"Orionids",fr:"Orionides"},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:{en:"Northern Taurids",fr:"Taurides du Nord"},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:{en:"Leonids",fr:"Léonides"},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:{en:"Geminids",fr:"Géminides"},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:{en:"Ursids",fr:"Ursides"},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}],rl=6.5;class zh{static activeAt(e){return pE.flatMap(t=>{const i=this.nearness(t,e);return i<=0?[]:[{shower:t,zhr:t.peakZhr*i,nearness:i}]})}static nearness(e,t){const i=this.dayOfYear(t),n=this.dayOfYear(this.asDate(e.start)),s=this.dayOfYear(this.asDate(e.peak)),a=this.dayOfYear(this.asDate(e.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(e,t,i,n=rl){if(t<=0)return 0;const s=rl-n;return e*Math.sin(t*Math.PI/180)/Math.pow(i,s)}static radiantPosition(e,t,i){return fn.ofJ2000(e.radiantRaHours,e.radiantDecDeg,t,i)}static dayOfYear(e){const t=Date.UTC(e.getUTCFullYear(),0,1);return Math.floor((Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate())-t)/864e5)+1}static asDate(e){return new Date(Date.UTC(2001,e.month-1,e.day))}static wrappedDelta(e,t){const i=e-t;return i>182?i-365:i<-182?i+365:i}}class Ht{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(e,t){const i=Ot(e),n=new Ml(0,Hb(e).elon-90,1),s=aa(dw(i),Qd(n,i)),a=e0(s);return t0(a.ra,a.dec,e,t)}static observedRatePerHour(e,t=rl){const i=Ht.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(e*Math.PI/180)),n=rl-t;return(Ht.QUIET_RATE_PER_HOUR+i)/Math.pow(Ht.POPULATION_INDEX,n)}static schedule(e){const t=new _l(e.seed^1542469173);return rr.schedule(e).map(i=>{const n=Ht.toCartesian({altitudeDeg:Math.asin(t.next())*180/Math.PI,azimuthDeg:t.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,a=Ht.turnAround(n,t.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:Ht.toHorizontal(o),bearingDeg:Ht.bearingFrom(o,n)}})}static turnAround(e,t){const[i,n]=Ht.basisAround(e),s=t*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(e,t){const[i,n]=Ht.basisAround(e),s=e.x*t.x+e.y*t.y+e.z*t.z,a=Ht.normalise({x:t.x-e.x*s,y:t.y-e.y*s,z:t.z-e.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(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=Ht.normalise(Ht.cross(e,t));return[i,Ht.normalise(Ht.cross(e,i))]}static toHorizontal(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,e.y/t)))*180/Math.PI,azimuthDeg:(Math.atan2(e.x,-e.z)*180/Math.PI%360+360)%360}}static appearanceOf(e){const t=Ht.toCartesian(e.radiant??{altitudeDeg:90,azimuthDeg:0}),i=Ht.turnAround(t,e.bearingDeg),n=e.fromRadiantDeg*Math.PI/180;return Ht.toHorizontal({x:t.x*Math.cos(n)+i.x*Math.sin(n),y:t.y*Math.cos(n)+i.y*Math.sin(n),z:t.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(e){const t=e.altitudeDeg*Math.PI/180,i=e.azimuthDeg*Math.PI/180,n=Math.cos(t);return{x:n*Math.sin(i),y:Math.sin(t),z:-n*Math.cos(i)}}static cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}static normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}static TYPICAL_VELOCITY_KM_S=40}const xm="https://ufoathome.org/tle/index.json";class yi{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??yi.defaultIndexUrls()}static defaultIndexUrls(){const e=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&e.push(new URL("/tle/index.json",location.href).href),e.includes(xm)||e.push(xm),e}static FIRST_SNAPSHOT="2021-02-22";async covers(e){const t=Date.parse(`${yi.FIRST_SNAPSHOT}T00:00:00Z`)-yi.MAX_ELEMENT_AGE_DAYS*yi.DAY_MS;if(e.getTime()<t)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>e.getTime()>=Date.parse(n.from)-yi.MAX_ELEMENT_AGE_DAYS*yi.DAY_MS&&e.getTime()<=Date.parse(n.to)+yi.MAX_ELEMENT_AGE_DAYS*yi.DAY_MS):!1}async at(e){const t=await this.loadIndex();if(!t)return;const{index:i,base:n}=t,s=[],a=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,e,i,n);s.push(...c),a.push(this.coverageOf(o,e,i,c.length>0))}return{objects:s,coverage:a,credit:i.credit,creditUrl:i.source}}async kindAt(e,t,i,n){const s=t.getTime(),a=i.binDays*yi.DAY_MS,o=Math.floor(s/a),c=s-o*a<a/2?o-1:o+1,l=new Set(i.kinds[e].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-${e}.json`,n).href),...h.map(v=>this.binary(new URL(`${e}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of yi.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)/yi.DAY_MS;if(m>yi.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:e,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(e,t,i,n){const{from:s,to:a}=i.kinds[e],o=t.getTime(),c=yi.MAX_ELEMENT_AGE_DAYS*yi.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(a)+c?"after":"gap";return{kind:e,status:l,from:s,to:a}}static decode(e,t){const i=new DataView(e),n=[];for(let s=0;s+t<=e.byteLength;s+=t)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 e of this.indexUrls)try{const t=await this.fetchImpl(e);if(!t.ok)continue;return{index:await t.json(),base:e}}catch{}})(),this.index}json(e){return this.cached(e,async t=>t.json())}binary(e){return this.cached(e,async t=>t.arrayBuffer())}cached(e,t){let i=this.files.get(e);return i||(i=this.fetchImpl(e).then(n=>{if(!n.ok)throw new Error(`${e}: ${n.status}`);return t(n)}),i.catch(()=>this.files.delete(e)),this.files.set(e,i)),i}}class mE{lowerM;upperM;add(e,t){if(!(e<=0)){if(t.behindM!==void 0){const i=Et.sizeMAt(t.behindM,e);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(t.inFrontM!==void 0){const i=Et.sizeMAt(t.inFrontM,e);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(e){return e<=0?{}:{minM:this.lowerM===void 0?void 0:Et.distanceMAt(this.lowerM,e),maxM:this.upperM===void 0?void 0:Et.distanceMAt(this.upperM,e)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class ar{static DEG_PER_SECOND=360/86164.0905;static degOver(e){return Math.max(0,e)*ar.DEG_PER_SECOND}static instants(e,t){if(!(t>0))return 1;const i=ar.degOver(e)/t;return i<1?1:Math.min(ar.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class Ti{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 ar.DEG_PER_SECOND*3600}static graspOf(e,t={}){const i=t.exposureSeconds??e.exposureSeconds,n=t.fNumber??e.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return Ti.EYE;const s=t.focalLengthMm??e.frame?.focalLengthMm??Ti.UNKNOWN_CAMERA_FOCAL_MM,a=s/n,o=Ti.resolutionArcsec(e,s,a);return{apertureMm:a,exposureSeconds:Math.min(i,Ti.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(e,t,i){const s=(e.detailUm??Ti.UNKNOWN_CAMERA_DETAIL_UM)/1e3/t*Ti.ARCSEC_PER_RADIAN,a=1.22*Ti.WAVELENGTH_M/(i/1e3)*Ti.ARCSEC_PER_RADIAN;return Math.max(s,a)}static trailLimitedSeconds(e){return e/Ti.skyDriftArcsecPerSecond}static gainOverEye(e,t={}){const i=Ti.graspOf(e,t),n=Ti.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(e,t){const i=t.fieldOfViewDeg===void 0?void 0:$t.focalLengthMmFor(e,t.fieldOfViewDeg);return Ti.gainOverEye(e,{fNumber:t.fNumber,focalLengthMm:i,exposureSeconds:t.exposureSeconds})}}const ym=111320,ka=Math.PI/180,gE=1.02,vE=1;class to{static of(e,t){const i=to.sightings(e,t);if(i.length<2)return;const n=to.baseline(i);if(!n)return;const{near:s,far:a,closedM:o}=n,c=Math.tan(a.widthDeg/2*ka)===0?0:Math.tan(s.widthDeg/2*ka)/Math.tan(a.widthDeg/2*ka);if(c<gE)return;const l=o/(c-1),h=Et.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:Et.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(e,t){return e.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===t)?.shape,s=n?.angular?.widthDeg,a=Gt(e,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(e){let t;for(const i of e)for(const n of e){if(i.t>=n.t)continue;const s=to.closedAlongSight(i,n),[a,o,c]=s>=0?[n,i,s]:[i,n,-s];c<vE||a.widthDeg<=o.widthDeg||(!t||c>t.closedM)&&(t={near:a,far:o,closedM:c})}return t}static closedAlongSight(e,t){const i=(t.lat-e.lat)*ym,n=(t.lng-e.lng)*ym*Math.cos(e.lat*ka),s=(e.sightAzimuthDeg??0)*ka;return i*Math.cos(s)+n*Math.sin(s)}}class Ai{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(e){if(e.statedM!==void 0&&e.statedM>0)return{distanceM:Ai.atLeastNearest(e.statedM),basis:"stated"};if(e.hypothesisM!==void 0&&e.hypothesisM>0)return{distanceM:Ai.atLeastNearest(e.hypothesisM),basis:"hypothesis"};if(e.derivedM!==void 0&&e.derivedM>0)return{distanceM:Ai.atLeastNearest(e.derivedM),basis:"derived"};const t=Ai.largest(e.range?.minM,e.crossing?.behindM),i=Ai.smallest(e.range?.maxM,e.crossing?.inFrontM),n=t===void 0?void 0:t*Ai.MARGIN,s=i===void 0?void 0:i/Ai.MARGIN;return n!==void 0&&s!==void 0?{distanceM:Ai.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:Ai.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<Ai.CONVENTIONAL_M?{distanceM:Ai.atLeastNearest(s),basis:"bounded"}:{distanceM:Ai.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(e){return Math.max(Ai.NEAREST_M,e)}static largest(...e){const t=e.filter(i=>i!==void 0&&i>0);return t.length===0?void 0:Math.max(...t)}static smallest(...e){const t=e.filter(i=>i!==void 0&&i>0);return t.length===0?void 0:Math.min(...t)}}const Bh=Math.PI/180;class wt{constructor(e,t,i){this.body=e,this.ground=t,this.keys=this.place([...e.track].sort((n,s)=>n.t-s.t),i)}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};keys;static eyeOf(e,t,i){const n=Gt(e,0),s=Gt(e,t);if(n?.lat===void 0||n.lng===void 0||s?.lat===void 0||s.lng===void 0)return;const a=ui(s.lat,s.lng,n.lat,n.lng),o=a.x,c=-a.z;return{eastM:o,northM:c,upM:i.heightAt(o,c)+wt.EYE_HEIGHT_M+s.elevationM,headingDeg:s.headingDeg}}static lineOfSightMeetsGround(e,t,i,n){const s=wt.directionOf(t,i),a=l=>e.upM+s.upM*l-n.heightAt(e.eastM+s.eastM*l,e.northM+s.northM*l);let o=0,c=0;for(;c<wt.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(e,t){const i=e*Bh,n=t*Bh;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(e){const t=this.keys;if(t.length===0||e<t[0].t)return;let i=t.length-1;for(;i>0&&t[i].t>e;)i--;const n=t[i];if(!n.present)return;const s=t[Math.min(i+1,t.length-1)],a=s===n||s.t===n.t?0:Math.min(1,(e-n.t)/(s.t-n.t)),o=wt.lerp(n.eastM,s.eastM,a),c=wt.lerp(n.northM,s.northM,a),l={widthM:wt.lerp(n.sizeM.widthM,s.sizeM.widthM,a),lengthM:wt.lerp(n.sizeM.lengthM,s.sizeM.lengthM,a),heightM:wt.lerp(n.sizeM.heightM,s.sizeM.heightM,a)},h={headingDeg:wt.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,a),pitchDeg:wt.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,a),rollDeg:wt.lerp(n.attitude.rollDeg,s.attitude.rollDeg,a)};let u;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const d=wt.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,a);u=this.groundUnderFootprint(o,c,l,h.headingDeg)+d+l.heightM/2}else u=wt.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:wt.lerp(n.appearance.albedo,s.appearance.albedo,a)},flame:wt.flameBetween(n.flame,s.flame,a),throwsFlame:this.body.track.some(d=>d.flame!==void 0&&d.flame.luminanceCdM2>0)}}static flameBetween(e,t,i){if(!e||e.luminanceCdM2<=0)return i>=1&&t&&t.luminanceCdM2>0?t:void 0;const n=e,s=t??e,a={...i<1?n:s,lengthM:wt.lerp(n.lengthM,s.lengthM,i),widthM:wt.lerp(n.widthM,s.widthM,i),luminanceCdM2:wt.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return a.luminanceCdM2>0?a:void 0}centreUpOf(e){return"upM"in e.vertical?e.vertical.upM:this.groundUnderFootprint(e.eastM,e.northM,e.sizeM,e.attitude.headingDeg)+e.vertical.aboveGroundM+e.sizeM.heightM/2}groundUnderFootprint(e,t,i,n){const s=n*Bh,a={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(e,t);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(e+a.eastM*u+o.eastM*d,t+a.northM*u+o.northM*d))}return c}place(e,t){const i=[];let n;for(const s of e){const a=s.sizeM??n?.sizeM??wt.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??wt.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??wt.DEFAULT_APPEARANCE.albedo},l=this.positionOf(s,t)??(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(e){if(e.onGround)return{aboveGroundM:0};if(e.altitudeAboveGroundM!==void 0)return{aboveGroundM:e.altitudeAboveGroundM}}positionOf(e,t){if(e.eastM!==void 0&&e.northM!==void 0)return{eastM:e.eastM,northM:e.northM,vertical:this.verticalOf(e)??{aboveGroundM:0}};if(e.azimuthDeg===void 0||e.altitudeDeg===void 0)return;const i=t(e.t);if(!i)return;const n=e.distanceM??(e.onGround?wt.lineOfSightMeetsGround(i,e.azimuthDeg,e.altitudeDeg,this.ground):void 0);if(n===void 0)return;const s=wt.directionOf(e.azimuthDeg,e.altitudeDeg),a=i.eastM+s.eastM*n,o=i.northM+s.northM*n;return{eastM:a,northM:o,vertical:this.verticalOf(e)??{upM:i.upM+s.upM*n}}}static lerp(e,t,i){return e+(t-e)*i}static lerpAngle(e,t,i){const n=((t-e)%360+540)%360-180;return((e+n*i)%360+360)%360}}const Vr=Math.PI/180,za=180/Math.PI;class Bt{constructor(e){this.timeline=e}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(e,t,i,n){const s=[];for(const a of t){const o=Bt.projectionOf(a,i,n?.(a));if(o)for(const c of a.explains){const l=this.timeline.getInterpolatedShapeAt(e,c);!l||l.transparency>=1||s.push({...Bt.compare(c,a.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(e,t,i,n){const s=[],a=i.aim?Bt.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(Bt.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&&!Bt.withinSize(o)&&s.push("width"),c!==void 0&&!Bt.withinSize(c)&&s.push("height"),{sourceId:e,bodyId:t,stated:i,predicted:n,separationDeg:a,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(e,t,i){const n=i&&i.length>0?i:Bt.outlineOf(e),s=i&&i.length>0?Bt.centreOf(i):e,a=Bt.normalized({eastM:s.eastM-t.eastM,northM:s.northM-t.northM,upM:s.upM-t.upM});if(!a)return;const o=Bt.normalized({eastM:a.northM,northM:-a.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=Bt.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-t.eastM,northM:f.northM-t.northM,upM:f.upM-t.upM},v=Bt.dot(p,a);if(v<=0)return;const m=Math.atan2(Bt.dot(p,o),v),g=Math.atan2(Bt.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)*za+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,a.upM)))*za},angular:{widthDeg:(h-l)*za,heightDeg:(d-u)*za}}}static centreOf(e){const t=i=>(Math.min(...e.map(n=>n[i]))+Math.max(...e.map(n=>n[i])))/2;return{eastM:t("eastM"),northM:t("northM"),upM:t("upM")}}static separationDeg(e,t){const i=e.altitudeDeg*Vr,n=t.altitudeDeg*Vr,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((e.azimuthDeg-t.azimuthDeg)*Vr);return Math.acos(Math.max(-1,Math.min(1,s)))*za}static withinSize(e){return e<=Bt.SIZE_TOLERANCE&&e>=1/Bt.SIZE_TOLERANCE}static outlineOf(e){const t=e.sizeM.widthM/2,i=e.sizeM.lengthM/2,n=e.sizeM.heightM/2,s=[],a=e.model.url===void 0?e.model.id:void 0;if(a!==void 0&&a!=="box"&&u1.includes(a))for(let u=0;u<=Bt.RINGS;u++){const d=u/Bt.RINGS*Math.PI;for(let f=0;f<Bt.SEGMENTS;f++){const p=f/Bt.SEGMENTS*2*Math.PI;s.push([t*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-t,t])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=e.attitude.headingDeg*Vr,l=e.attitude.pitchDeg*Vr,h=e.attitude.rollDeg*Vr;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:e.eastM+p*Math.cos(c)+m*Math.sin(c),northM:e.northM-p*Math.sin(c)+m*Math.cos(c),upM:e.upM+g}})}static dot(e,t){return e.eastM*t.eastM+e.northM*t.northM+e.upM*t.upM}static cross(e,t){return{eastM:e.northM*t.upM-e.upM*t.northM,northM:e.upM*t.eastM-e.eastM*t.upM,upM:e.eastM*t.northM-e.northM*t.eastM}}static normalized(e){const t=Math.hypot(e.eastM,e.northM,e.upM);return t>1e-9?{eastM:e.eastM/t,northM:e.northM/t,upM:e.upM/t}:void 0}}Gm();const ME={sun:{en:"Sun",fr:"Soleil"},moon:{en:"Moon",fr:"Lune"},Venus:{en:"Venus",fr:"Vénus"},Mars:{en:"Mars",fr:"Mars"},Jupiter:{en:"Jupiter",fr:"Jupiter"},Saturn:{en:"Saturn",fr:"Saturne"}},xE=["en","fr"],yE={en:"{name} — mag {mag}, {alt}° above the horizon",fr:"{name} — mag {mag}, {alt}° au-dessus de l'horizon"},_E={en:"{name} — satellite, mag {mag}, {height} km up",fr:"{name} — satellite, mag {mag}, à {height} km d'altitude"},SE="satellites-change",m1="rr0-confrontation",bE={en:"{name} — mag {mag}, {alt}° below the horizontal",fr:"{name} — mag {mag}, {alt}° sous l'horizontale"},_m="comet:",Sm="nova:",wE={building:{en:"Building",fr:"Bâtiment"},tree:{en:"Tree",fr:"Arbre"},shrub:{en:"Shrub",fr:"Buisson"},crop:{en:"Crop row",fr:"Rang de culture"},mound:{en:"Stone heap",fr:"Tas de pierres"},streetlight:{en:"Streetlight",fr:"Lampadaire"},vehicle:{en:"Vehicle",fr:"Véhicule"},witness:{en:"Witness",fr:"Témoin"},aircraft:{en:"Aircraft",fr:"Aéronef"},entity:{en:"Being",fr:"Être"}},EE=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,AE=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,TE=-18,RE={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Hh={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class i0 extends HTMLElement{static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",is,ns]}shadow;stageElement;frameElement;sceneCanvas;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new D;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new yi;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;starCatalogDepth=0;weatherAudio=new dE;animateWhilePausedValue=!1;set animateWhilePaused(e){e!==this.animateWhilePausedValue&&(this.animateWhilePausedValue=e,this.syncAnimationsToPlayback())}get animateWhilePaused(){return this.animateWhilePausedValue}thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=e=>{this.sceneRenderer.setCompassHovered(!0);const t=this.ufoElement.canvasElement,i=t.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(e.clientX-i.left)/i.width*t.width,s=(e.clientY-i.top)/i.height*t.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const a=(e.clientX-i.left)/i.width*2-1,o=-((e.clientY-i.top)/i.height*2-1),c=ll(oa.preferencesFor(this),xE),l=this.sceneRenderer.pickBodyAt(a,o);if(l){this.showHoverTooltip(e,this.bodyName(l,c));return}const h=this.sceneRenderer.pickDecorAt(a,o),u=h?this.ufoElement.sighting.decor.find(p=>p.id===h):void 0;if(u){this.showHoverTooltip(e,this.said.read(u.title)||wE[u.kind][c]);return}const d=this.sceneRenderer.pickSatelliteAt(a,o);if(d){this.showHoverTooltip(e,_E[c].replace("{name}",d.name).replace("{mag}",d.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(d.heightKm).toLocaleString()));return}const f=this.sceneRenderer.pickStarAt(a,o);if(f){const p=f.star.mag,v=f.altitudeDeg,m=(v<0?bE:yE)[c];this.showHoverTooltip(e,m.replace("{name}",f.star.name[c]).replace("{mag}",p.toLocaleString(void 0,{maximumFractionDigits:Math.abs(p)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(v)))));return}this.hoverTooltip.hidden=!0};bodyName(e,t){const i=e.startsWith(_m)?e.slice(_m.length):void 0,n=i?p1.find(a=>a.id===i):void 0,s=e.startsWith(Sm)?Mm.byId(e.slice(Sm.length)):void 0;return n?.name[t]??s?.name[t]??ME[e]?.[t]??e}showHoverTooltip(e,t){this.hoverTooltip.textContent=t,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${e.clientX-i.left+12}px`,this.hoverTooltip.style.top=`${e.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(e){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),Qt.thunderDelayMs(e))}handleFirstInteraction=()=>{this.removeEventListener("pointerdown",this.handleFirstInteraction,!0),this.removeEventListener("keydown",this.handleFirstInteraction,!0),this.weatherAudio.resume(),this.setWeather(ws(this.ufoElement.sighting,this.lastTimeMs))};handleTimeUpdate=e=>{this.lastTimeMs=e.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now())};syncAnimationsToPlayback(){const e=this.ufoElement.playbackState==="playing",t=e||this.animateWhilePaused;this.sceneRenderer.setAnimationsRunning(t,e),this.weatherAudio.setPaused(!t),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${i2}</style>${t2}`,this.shadow.appendChild(e.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 Qi(this.sceneCanvas);const t=this.shadow.getElementById("scene-loader");this.sceneRenderer.onFirstFrameHold=i=>{t.hidden=!i},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(qh),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",i=>this.lookToward(i.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.sceneRenderer.onMapSubjectBounds=i=>this.ufoElement.setMapSubjectBounds(i),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.addEventListener("referenceview",i=>this.applyReferenceView(i.detail)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave),this.addEventListener("pointerdown",this.handleFirstInteraction,!0),this.addEventListener("keydown",this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new pn(oa.preferencesFor(this))}saidTexts;connectedCallback(){this.saidTexts=void 0,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);const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(e,t,i){if(e==="src"&&i&&i!==t&&this.isConnected&&this.loadFromSrc(i),(e==="star-catalog-src"||e==="deep-star-catalog-src")&&i!==t&&this.isConnected&&this.loadStars(),e==="show-compass"&&i!==t&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),e==="max-pixel-ratio"&&i!==t){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(e===is||e===ns)&&i!==t&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const e of[is,ns])this.ufoElement.toggleAttribute(e,this.hasAttribute(e))}setCompassForced(e){this.sceneRenderer.setCompassForced(e)}lookToward(e){const t=Gt(this.ufoElement.sighting,this.lastTimeMs);if(e.kind==="witness"||t?.lat===void 0||t.lng===void 0||t.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=ui(e.lat,e.lng,t.lat,t.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-t.headingDeg)%360+540)%360-180,-t.pitchDeg)}setLookOffset(e,t){this.sceneRenderer.setLookOffset(e,t),this.ufoElement.setLookOffset(e,t),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(e,t){this.sceneRenderer.setIndoorLook(e,t)}setCloudRendering(e){this.sceneRenderer.setCloudRendering(e)}setWeather(e){this.sceneRenderer.setWeather(e),this.weatherAudio.setAmbient(e.precipitationType,e.precipitationIntensity,e.windSpeed)}pickCloudAt(e,t){return this.sceneRenderer.pickCloudAt(e,t)}cloudDirectionAt(e,t){return this.sceneRenderer.cloudDirectionAt(e,t)}pickDecorAt(e,t){return this.sceneRenderer.pickDecorAt(e,t)}resumeWeatherAudio(){this.weatherAudio.resume()}async loadFromSrc(e){this.sightingData=await Ka.json(e)}get sightingData(){return this.ufoElement.sightingData}set sightingData(e){this.ufoElement.sightingData=e,this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}referenceAspect(e){return this.sceneRenderer.referenceAspect(e)}screenPointOf(e){return this.sceneRenderer.screenPointOf(e)}directionAt(e,t){return this.sceneRenderer.directionAt(e,t)}referenceFailedToLoad(e){return this.sceneRenderer.referenceFailedToLoad(e)}applyReferenceView(e){this.sceneRenderer.setReferencesShown(e.shown);for(const t of this.ufoElement.sighting.references)this.sceneRenderer.setReferenceView(t.id,{opacity:e.opacity})}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}setTerrainProviders(e){this.sceneRenderer.setTerrainProviders(e)}setDecorModelProvider(e){this.sceneRenderer.setDecorModelProvider(e)}get decorModelCredits(){return this.sceneRenderer.currentDecorModelCredits}applyFrameFormat(){const e=this.ufoElement.sighting.instrument,t=Et.CANVAS_HEIGHT_PX,i=$t.frameWidthPx(e,t);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${t}`)}resizeToStage(){const e=this.frameElement.getBoundingClientRect(),t=Math.max(1,Math.round(e.width)),i=Math.max(1,Math.round(e.height));this.sceneCanvas.width=t,this.sceneCanvas.height=i,this.sceneRenderer.resize(t,i)}async loadStars(){const e=[{magnitudeLimit:Uh,url:this.getAttribute("star-catalog-src")??EE},{magnitudeLimit:Fh,url:this.getAttribute("deep-star-catalog-src")??AE}],t=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=t>Uh?Fh:Uh;const n=await Tn.upTo(e,t);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Fh||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const e=this.ufoElement.sighting,t=Ti.gainFor(e.instrument,{fNumber:Gt(e,0)?.fNumber,fieldOfViewDeg:Bi.fovOf(e,0),exposureSeconds:e.exposure});return Xu(TE,t)}updateAstronomy(e){this.ensureStarsDeepEnough(),this.applySceneAt(e);const t=dn.windowEndingAt(e,this.exposureSeconds()),i=t.seconds,n=this.degreesPerPixelAt(e),s=ar.instants(i,n),a=Math.max(s,this.ufoElement.exposureTimes(e).length,dn.instants(this.ufoElement.sighting.decor,Gt(this.ufoElement.sighting,e)?.elevationM??0,t.fromMs,i,n));if(a<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(a,o=>this.applySceneAt(t.fromMs+t.ms*o/(a-1),{sky:Math.floor(o*s/a)!==Math.floor((o-1)*s/a),stepMs:t.ms/a}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(e){const t=this.sceneCanvas.height;return t<=0?0:Bi.fovOf(this.ufoElement.sighting,e)/t}applySceneAt(e,t){const i=this.ufoElement.sighting;this.setWeather(ws(i,e)),this.sceneRenderer.setInstrument(i.instrument),this.updateMeteorShower(i,e),this.updateLightning(i,e,t!==void 0),this.sceneRenderer.setDecor(i.decor),this.sceneRenderer.setReferences(i.references);const n=Gt(i,e),s=Gt(i,0),a=ws(i,0),o=Object.fromEntries(Oc(ws(i,e)).map(S=>[S.id,S0(e,i.weatherTrack,a,s,n,S.id)]));this.sceneRenderer.setCloudOffset(S0(e,i.weatherTrack,a,s,n),o),this.sceneRenderer.setObserverPose(n??Hh),this.sceneRenderer.setLensOptics(this.lensOpticsAt(e)),this.sceneRenderer.setInstrumentGain(Ti.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:Bi.fovOf(i,e),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0),this.sceneRenderer.setGait(Jt.of(i)?.offsetAt(e)??Jt.STILL),this.sceneRenderer.updateDecorAnchoring(Gt(i,0),n,e),this.placeBodiesAt(e,t===void 0),this.sceneRenderer.updateDecorLitState(e,t?.stepMs??0),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng),this.pushPhenomenaAt(e);const c=n?.lat??Hh.lat,l=n?.lng??Hh.lng,h=qa(i.event.time??{},l,i.event.utcOffsetHours),u={lat:c,lng:l,elevationM:n?.elevationM??0};if(this.pushSatellitesAt(h,e,u),t&&!t.sky)return;if(!h){this.sceneRenderer.setAstronomy(RE);return}const d=new Date(h.getTime()+e),f=Math.max(1,Math.round(.25*this.degreesPerPixelAt(e)/ar.DEG_PER_SECOND*1e3)),p=Math.max(1e-8,this.degreesPerPixelAt(e)*.1),v=`${Math.floor(d.getTime()/f)}|${Math.round(c/p)}|${Math.round(l/p)}|${Math.round(u.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(v===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=v;const m={...mh("Sun",d,u),magnitude:gh("Sun",d)},g={...mh("Moon",d,u),phase:pw(d),magnitude:gh("Moon",d)},_=fw.map(S=>({body:S,position:mh(S,d,u),magnitude:gh(S,d)}));this.sceneRenderer.setAstronomy({sun:m,moon:g,planets:_,comet:this.cometAt(d,u),novae:Mm.appearancesAt(d,u).map(({outburst:S,position:y,magnitude:w})=>({id:S.id,position:y,magnitude:w})),stars:this.starCatalog?{catalog:this.starCatalog,date:d,observer:u}:void 0,frame:{date:d,observer:u}}),this.ufoElement.setSunAltitude(m.altitudeDeg)}pushSatellitesAt(e,t,i){if(this.ensureSatellites(e),!e||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(e.getTime()+t),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)}ensureSatellites(e){const t=e?String(e.getTime()):"";if(t===this.satellitesFor)return;this.satellitesFor=t,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!e){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=a=>{i===this.satelliteRequest&&(this.satelliteStatus=a,this.dispatchEvent(new CustomEvent(SE)))},s=i0.tleArchive;(async()=>{if(!await s.covers(e))return n("outside");const[a,o]=await Promise.all([s.at(e),as(()=>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.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const e=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:e?.coverage,credit:e?.credit,creditUrl:e?.creditUrl}}satellitePassesDuring(e){const t=this.satellites,i=this.ufoElement.sighting,n=Gt(i,0),s=i.event.place?.[0],a=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!t||a===void 0||o===void 0)return[];const c=qa(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(e,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=t.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(e,t){const i=fE.brightestAt(e,t);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(e){const t=this.ufoElement.sighting;t!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=t);const i=t.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,a=this.projectionAt(e),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(e,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(un.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,S=_?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(_||v.aim)&&l.delete(p);const y=v.angular?.widthDeg??a.pxToDeg(v.bounds.width),w=this.sizeEstimateOf(p);w.add(y,S);const E=to.of(t,p);c.set(p,Ai.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:E&&y>0?Et.distanceMAt(E.widthM,y):void 0,range:w.distanceRangeAt(y),crossing:S}))}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 S=c.get(m);S&&c.set(p,{distanceM:S.distanceM*.999,basis:S.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,ghost:this.interpretationShown!==void 0&&this.comparing});const f=(Gt(t,e)?.rollDeg??0)+(Jt.of(t)?.offsetAt(e)??Jt.STILL).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:$t.starPointsOf(t.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(e){this.interpretationShown=e,this.updateAstronomy(this.lastTimeMs)}get testimonyInTheRound(){return this.inTheRound}set testimonyInTheRound(e){this.inTheRound=e}get compareTestimony(){return this.comparing}set compareTestimony(e){this.comparing=e,this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}placeBodiesAt(e,t){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],a=[];const o=this.sceneRenderer.bodyGround,c=p=>wt.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new wt(p,o,c).at(e)).filter(p=>p!==void 0));const l=ws(n,e),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,e/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(e):void 0;if(d&&(a=new Bt(n.timeline).at(e,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=a,!t)return;const f=JSON.stringify(a);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(m1,{detail:a})))}setDistanceHypothesis(e,t){t===void 0||!(t>0)?this.distanceHypotheses.delete(e):this.distanceHypotheses.set(e,t),this.updateAstronomy(this.lastTimeMs)}depthOf(e){return this.depths.get(e)}sizeRangeOf(e){return this.sizeEstimateOf(e).sizeRange}distanceRangeAt(e,t){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(t,e);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(t).pxToDeg(i.bounds.width);return this.sizeEstimateOf(e).distanceRangeAt(n)}sizeContradictory(e){return this.sizeEstimateOf(e).contradictory}updateMeteorShower(e,t){this.ensureMeteorSchedule(e),this.sceneRenderer.updateMeteors(t)}updateLightning(e,t,i){if(this.ensureLightningSchedule(e),this.sceneRenderer.updateLightning(t),i)return;const n=this.lastLightningT;if(this.lastLightningT=t,n===void 0||t<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(a=>a.t>n&&a.t<=t).pop();s&&ws(e,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(e){const t=ws(e,0).precipitationIntensity,i=`${this.meteorInputsOf(e)}|${t}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=e.event.time,s=e.event.place?.[0],a=n?.year!==void 0?qa(n,s?.lng??0,e.event.utcOffsetHours):void 0,o=(e.event.durationSeconds??0)*1e3||e.timeline.duration||2e4,c=Math.round((a?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=Qt.schedule({durationMs:o,seed:c,intensity:t}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(e){const t=this.meteorInputsOf(e);t!==this.meteorScheduleFor&&(this.meteorScheduleFor=t,this.scheduleMeteors(e))}meteorInputsOf(e){const t=e.event.place?.[0],i=e.event.time;return JSON.stringify([t?.lat,t?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,e.event.utcOffsetHours,e.event.durationSeconds,e.timeline.duration])}scheduleMeteors(e){const t=e.event.place?.[0],i=e.event.time,n=t?.lat!==void 0&&t.lng!==void 0&&i?.year!==void 0?qa(i,t.lng,e.event.utcOffsetHours):void 0;if(!n||t?.lat===void 0||t.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:t.lat,lng:t.lng,elevationM:0},a=(e.event.durationSeconds??0)*1e3||e.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(t.lat*1e3),c=Ht.schedule({ratePerHour:Ht.observedRatePerHour(Ht.apexPosition(n,s).altitudeDeg),durationMs:a,velocityKmS:Ht.TYPICAL_VELOCITY_KM_S,seed:o}),l=zh.activeAt(n).map(u=>{const d=zh.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:zh.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=rr.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(e){this.ensureMeteorSchedule(this.ufoElement.sighting);const t=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,a)=>a.brightness-s.brightness);if(t.length===0)return;const i=t[e%t.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(e){const t=this.ufoElement.sighting,i=t.instrument,n=i.frame,s=Gt(t,e),a=s?.fNumber??i.fNumber;if(!n||a===void 0)return;const o=$t.focalLengthMmFor(i,Bi.fovOf(t,e));if(o!==void 0)return{focalLengthMm:o,fNumber:a,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(e){const t=this.ufoElement.sighting;return es.of(t.instrument,Et.CANVAS_HEIGHT_PX,Bi.fovOf(t,e))}sizeEstimateOf(e){let t=this.sizeEstimates.get(e);return t||(t=new mE,this.sizeEstimates.set(e,t)),t}}const md="rr0-scene";function g1(){Gm(),customElements.get(md)||customElements.define(md,i0)}const DE={color:"Color",transparency:"Transparency",halo:"Halo",blur:"Blur",brightness:"Brilliance",shapeTitle:"Name",utcOffset:"Time zone",cloudBase:"Cloud base",elevation:"Altitude",heightAboveGround:"Height above ground",duration:"Duration",placeName:"Place",latitude:"Latitude",longitude:"Longitude",heading:"Heading",pitch:"Tilt",roll:"Roll",observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Witness info"},assessmentVerdicts:{"hynek.nl":"NL — nocturnal light","hynek.dd":"DD — daylight disc","hynek.rv":"RV — radar-visual","hynek.ce1":"CE1 — close encounter","hynek.ce2":"CE2 — with a physical trace","hynek.ce3":"CE3 — with entities"},witnessGroup:"Witness",witnessId:"ID",witnessTitle:"Title",witnessLastName:"Last name",witnessFirstNames:"First names",sightingId:"ID",tags:"Tags",cloudCover:"Cloud cover",highCloudCover:"Ice cloud (cirrus)",focalLength:"Focal length",fieldOfView:"Field of view",aperture:"Aperture",exposure:"Exposure",focusDistance:"Focused at",iceCrystalAlignment:"Crystal alignment",cloudDarkness:"Cloud darkness",precipitationType:"Precipitation",precipitationNone:"None",precipitationRain:"Rain",precipitationSnow:"Snow",precipitationHail:"Hail",precipitationIntensity:"Intensity",windDirection:"Wind direction",windSpeed:"Wind speed",storm:"Storm",cloudsGroup:"Clouds",precipitationGroup:"Precipitation",windGroup:"Wind",soundKind:"Sound",soundNone:"None (silent)",soundHum:"Hum",soundWhistle:"Whistle",soundRumble:"Rumble",soundCrackle:"Crackle",soundVolume:"Loudness",soundPitch:"Pitch",soundSrc:"Recording",instrument:"Observed through",decorAircraft:"Aircraft",decorEntity:"Being",decorAltitude:"Altitude",decorLights:"Lights",decorLightsNone:"none",decor:"Environment",decorBuilding:"Building",decorTree:"Tree",decorShrub:"Shrub",decorCrop:"Crop row",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorWitness:"Other witness",decorEast:"Distance east",decorNorth:"Distance north",decorHeading:"Heading",decorColor:"Colour",decorLit:"Lit",decorTitle:"Name",milestones:"Moments",milestoneLabel:"Label",milestoneNote:"What happens",addMilestone:"Name this moment",deleteMilestone:"Delete moment",confirmAccept:"Delete",confirmDecline:"Cancel",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelAdvanced:"Model from an address",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorWitnessSide:"Witness location",decorWitnessSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},Lc={...DE,testimonyBy:"Testimony by",unnamedWitness:"Witness {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Replay",embedEdit:"Editor",embedCopy:"Copy",embedCopied:"Copied",showLabels:"Show what it states",interpretation:"Interpretation",testimony:"Testimony",interpretationBy:"{title}, by {by}",confrontation:"Against the testimony",confrontationDirection:"{deg}° off",confrontationWidth:"width ×{ratio}",confrontationHeight:"height ×{ratio}",showComparison:"Compare with the testimony",hideComparison:"Stop comparing with the testimony",hideLabels:"Hide what it states"},CE=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:Lc},Symbol.toStringTag,{value:"Module"}));g1();const IE="“Thunder” by Jerimee",PE="https://creativecommons.org/licenses/by/3.0/",LE="CC BY 3.0",NE="https://ufoathome.org",Gh="compare-testimony",Vh="testimony",bm=`${NE}/edit/`;class v1 extends HTMLElement{static get observedAttributes(){return["src","show-labels",is,ns,Gh]}shadow;sceneElement;toolbarElement;testimonyElement;testimonyPrefix;witnessText;witnessSelect;infoButton;infoPanel;infoAppLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;infoEmbedToggle;infoEmbedPanel;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new y0(Lc,"en",new pn(["en"]),new wc({}));summarySignature="";assessmentEntries=[];assessmentToken=0;supportsPopover=typeof HTMLElement.prototype.showPopover=="function";entries=[];caseSource;interpretationChoice;interpretationLabel;interpretationSelect;confrontationElement;confrontationHeading;confrontationList;compareButton;interpretationLoaders=new Map;interpretationToken=0;offeredFor;currentSrc;infoOpen=!1;creditsOpen=!1;embedOpen=!1;labelsShown=!1;language="en";messages=Lc;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${A1}</style>${E1}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.sceneElement=document.createElement(md),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.sceneElement.ufoElement.hostControls(this.shadow.getElementById("scene-controls")),this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.testimonyElement=this.shadow.getElementById("testimony"),this.testimonyPrefix=this.shadow.getElementById("testimony-prefix"),this.witnessText=this.shadow.getElementById("witness-text"),this.witnessSelect=this.shadow.getElementById("witness"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.infoObservationHeading=this.shadow.getElementById("info-observation-heading"),this.infoObservationList=this.shadow.getElementById("info-observation-list"),this.infoCreditsToggle=this.shadow.getElementById("info-credits-toggle"),this.infoCreditsList=this.shadow.getElementById("info-credits-list"),this.infoCloseButton=this.shadow.getElementById("info-close"),this.labelsToggle=this.shadow.getElementById("info-labels-toggle"),this.paramSummary=this.shadow.getElementById("param-summary"),this.labelsToggle.addEventListener("click",()=>{this.showLabels=!this.showLabels}),this.infoEmbedToggle=this.shadow.getElementById("info-embed-toggle"),this.infoEmbedPanel=this.shadow.getElementById("info-embed"),this.embedReplayRadio=this.shadow.getElementById("embed-kind-replay"),this.embedEditRadio=this.shadow.getElementById("embed-kind-edit"),this.labelEmbedReplay=this.shadow.getElementById("label-embed-replay"),this.labelEmbedEdit=this.shadow.getElementById("label-embed-edit"),this.embedMarkup=this.shadow.getElementById("embed-markup"),this.embedCopyButton=this.shadow.getElementById("embed-copy"),this.interpretationChoice=this.shadow.getElementById("interpretation-choice"),this.interpretationLabel=this.shadow.getElementById("interpretation-label"),this.interpretationSelect=this.shadow.getElementById("interpretation"),this.confrontationElement=this.shadow.getElementById("confrontation"),this.confrontationHeading=this.shadow.getElementById("confrontation-heading"),this.confrontationList=this.shadow.getElementById("confrontation-list"),this.compareButton=this.shadow.getElementById("compare-testimony"),this.compareButton.addEventListener("click",()=>this.setComparing(!this.sceneElement.compareTestimony)),this.witnessSelect.addEventListener("change",()=>this.selectWitness(this.witnessSelect.value)),this.interpretationSelect.addEventListener("change",()=>void this.chooseInterpretation(this.interpretationSelect.value)),this.sceneElement.addEventListener(m1,t=>this.showConfrontation(t.detail)),this.sceneElement.ufoElement.addEventListener("timeupdate",()=>this.refreshParamSummary()),this.supportsPopover?(this.infoPanel.setAttribute("popover","auto"),this.infoPanel.removeAttribute("hidden"),this.infoButton.setAttribute("popovertarget","info-panel"),this.infoPanel.addEventListener("beforetoggle",t=>{t.newState==="open"&&(this.populateInfoPanel(),this.bringInfoButtonIntoView())}),this.infoPanel.addEventListener("toggle",t=>this.syncInfoOpen(t.newState==="open"))):this.infoButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCloseButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCreditsToggle.addEventListener("click",()=>this.toggleCredits()),this.infoEmbedToggle.addEventListener("click",()=>this.toggleEmbed());for(const t of[this.embedReplayRadio,this.embedEditRadio])t.addEventListener("change",()=>this.refreshEmbedMarkup());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const e=++this.localeToken,t=oa.preferencesFor(this);this.preferences=t;const i=ll(t,Nm),[n,s]=i==="en"?[Lc,{}]:await Promise.all([y2(i),_2(i)]);if(e!==this.localeToken)return;const a=i!==this.language;this.language=i,this.messages=n,this.tags=new wc(s),this.said=new pn(t),this.summaryBuilder=new y0(this.messages,this.language==="fr"?"fr":"en",this.said,this.tags),this.testimonyPrefix.textContent=this.messages.testimonyBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const o=this.entries.find(c=>c.src===this.currentSrc);o&&this.offerInterpretations(o),this.updateCompareButton(),this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.syncLabelsToggle(),this.refreshParamSummary(),a&&this.currentSrc&&this.runAssessments(),this.infoEmbedToggle.textContent=this.messages.embed,this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateTestimonyLine()}preferences=[];localeToken=0;said=new pn(["en"]);tags=new wc({});connectedCallback(){oa.preferencesFor(this).join()!==this.preferences.join()&&this.loadLocaleMessages();const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick)}attributeChangedCallback(e,t,i){e==="src"&&i&&i!==t&&this.isConnected&&this.loadFromSrc(i),e==="show-labels"&&this.applyLabels(this.hasAttribute("show-labels")),(e===is||e===ns)&&this.forwardPlayerAttributes(),e===Gh&&this.setComparing(this.hasAttribute(Gh))}forwardPlayerAttributes(){for(const e of[is,ns])this.sceneElement.toggleAttribute(e,this.hasAttribute(e))}async loadFromSrc(e){const t=await Ka.json(e);if(Array.isArray(t))throw new Error(`${e} is a bare list of recordings, which is no longer read: list them as the sighting events of a case.json`);if(er.isCase(t)){const i=er.sightingUrls(t,new URL(e,location.href).href);if(i.length===0)throw new Error(`${e} is a case with no sighting event: no recording to show`);await this.loadWitnessUrls(i,{json:t,url:new URL(e,location.href).href})}else this.setEntries([{src:e,sighting:t}],void 0)}get sightingData(){return this.entries.find(e=>e.src===this.currentSrc)?.sighting}set sightingData(e){this.currentSrc="",this.setEntries([{src:"",sighting:e}],void 0)}get witnessUrls(){return this.entries.map(e=>e.src)}set witnessUrls(e){this.loadWitnessUrls(e)}async loadWitnessUrls(e,t){const i=await Promise.all(e.map(async n=>({src:n,sighting:await Ka.json(n)})));this.setEntries(i,t)}setEntries(e,t){this.entries=e,this.caseSource=t,this.toolbarElement.hidden=e.length===0;const i=e.length>1;this.witnessSelect.hidden=!i,this.witnessText.hidden=i,this.witnessSelect.innerHTML="";for(const s of e){const a=document.createElement("option");a.value=s.src,a.textContent=this.witnessDisplayName(s.sighting.witness)??this.messages.unnamedWitness.replace("{n}",String(e.indexOf(s)+1)),this.witnessSelect.appendChild(a)}const n=e.find(s=>s.src===this.currentSrc)??e[0];n?this.selectWitness(n.src):this.updateTestimonyLine()}editorUrl(){if(!this.currentSrc)return bm;const e=new URL(this.currentSrc,location.href);return`${bm}?sighting=${encodeURIComponent(e.href)}`}embedMarkupFor(e){const t=e==="edit"?"rr0-sighting-editor":"rr0-sighting",i=new URL(`${t}.mjs`,import.meta.url).href,n=this.currentSrc?new URL(this.currentSrc,location.href).href:"";return`<script type="module" src="${i}"><\/script>
|
|
7108
|
-
<${t} src="${n}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyEmbedMarkup(){try{await navigator.clipboard.writeText(this.embedMarkup.value),this.embedCopyButton.textContent=this.messages.embedCopied,window.setTimeout(()=>this.embedCopyButton.textContent=this.messages.embedCopy,1500)}catch{this.embedMarkup.select()}}offerInterpretations(e){const t=this.offeredFor===e.sighting,i=this.interpretationSelect.value;this.offeredFor=e.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=e===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(Vh,this.messages.testimony,()=>Promise.resolve(s));const a=this.caseSource;a&&er.interpretationEvents(a.json,e.sighting.id).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>er.interpretationOf(l,a.url,f=>Ka.json(f)))});const c=t&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:Vh;this.interpretationSelect.value=c,c===Vh?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(e){this.sceneElement.compareTestimony=e,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const e=this.sceneElement.compareTestimony;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(e));const t=e?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=t,this.compareButton.setAttribute("aria-label",t)}get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(e){const t=++this.interpretationToken,i=this.interpretationLoaders.get(e),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${e}":`,s)}):void 0;t===this.interpretationToken&&(this.sceneElement.interpretation=n,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(e){if("people"in e){const[t,...i]=e.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,t].join(" ")}return"org"in e?e.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.witnessDisplayName(e)??""}showConfrontation(e){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareTestimony;const t=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of e){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const a=[];n.separationDeg!==void 0&&a.push([this.messages.confrontationDirection.replace("{deg}",t.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&a.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&a.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),a.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}selectWitness(e){const t=this.entries.find(i=>i.src===e);t&&(this.currentSrc=e,this.witnessSelect.value=e,this.sceneElement.sightingData=t.sighting,this.offerInterpretations(t),this.updateTestimonyLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(OE,{detail:{src:e}})))}async runAssessments(){const e=++this.assessmentToken,t=await new e2(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateTestimonyLine(){const e=this.entries.find(n=>n.src===this.currentSrc),t=e?this.witnessDisplayName(e.sighting.witness):void 0,i=t!==void 0||this.entries.length>1;this.testimonyElement.hidden=!i,this.witnessText.textContent=t??""}witnessDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id}formatDate(e){const t=e.place?.[0],i=qa(e.time??{},t?.lng??0,e.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;return new Intl.DateTimeFormat(this.language==="fr"?"fr-FR":"en-US",{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(e,t){return e.utcOffsetHours??Math.round(t/15)}formatLocation(e){const t=e.place?.[0];if(t)return`${t.lat.toFixed(4)}, ${t.lng.toFixed(4)}`}toggleInfoPanel(){const e=!this.infoOpen;if(this.supportsPopover){const t=this.infoPanel.matches(":popover-open");e&&!t?this.infoPanel.showPopover():!e&&t&&this.infoPanel.hidePopover();return}e&&this.bringInfoButtonIntoView(),this.syncInfoOpen(e),this.infoPanel.hidden=!e,e?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const e=this.infoButton.getBoundingClientRect(),t=window.innerHeight||document.documentElement.clientHeight;e.top>=0&&e.bottom<=t||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(e){e!==this.infoOpen&&(this.infoOpen=e,this.infoButton.setAttribute("aria-expanded",String(e)),e?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false"),this.embedOpen=!1,this.infoEmbedPanel.hidden=!0,this.infoEmbedToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=e=>{const t=e.composedPath();!t.includes(this.infoPanel)&&!t.includes(this.infoButton)&&this.toggleInfoPanel()};toggleCredits(){this.creditsOpen=!this.creditsOpen,this.infoCreditsList.hidden=!this.creditsOpen,this.infoCreditsToggle.setAttribute("aria-expanded",String(this.creditsOpen)),this.creditsOpen&&this.revealInPanel(this.infoCreditsList)}toggleEmbed(){this.embedOpen=!this.embedOpen,this.infoEmbedPanel.hidden=!this.embedOpen,this.infoEmbedToggle.setAttribute("aria-expanded",String(this.embedOpen)),this.embedOpen&&(this.refreshEmbedMarkup(),this.revealInPanel(this.infoEmbedPanel))}revealInPanel(e){e.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(e){this.toggleAttribute("show-labels",e)}applyLabels(e){this.labelsShown=e,this.syncLabelsToggle(),this.refreshParamSummary(),this.populateInfoPanel()}syncLabelsToggle(){this.labelsToggle.textContent=this.labelsShown?this.messages.hideLabels:this.messages.showLabels,this.labelsToggle.setAttribute("aria-pressed",String(this.labelsShown))}refreshParamSummary(){if(this.paramSummary.hidden=!this.labelsShown,!this.labelsShown){this.paramSummary.replaceChildren(),this.summarySignature="";return}const e=this.sceneElement.ufoElement.sighting,t=[...this.summaryBuilder.entriesFor(e,this.sceneElement.ufoElement.currentTime),...this.assessmentEntries],i=t.map(a=>`${a.field}=${a.label}=${a.value}${a.unit}${a.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const a of t){s&&s.group!==a.group&&(s=void 0);const o=a.group==="witness"?this.messages.witnessGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),s={group:a.group,element:l},n.push(l)}const c=this.paramItem(a);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n)}paramItem(e){const t=document.createElement("span");t.className=e.fromSource?"param-label from-source":"param-label";const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${e.label} `,t.append(i),e.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=e.color,t.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=e.unit===""?e.value:`${e.value} ${e.unit}`,t.append(n),t}populateInfoPanel(){const e=this.entries.find(o=>o.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){const o=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(o&&this.appendInfoRow(this.infoObservationList,this.messages.case,o),!this.labelsShown){const l=this.formatDate(e.sighting);l&&this.appendInfoRow(this.infoObservationList,this.messages.date,l);const h=this.formatLocation(e.sighting);h&&this.appendInfoRow(this.infoObservationList,this.messages.location,h)}const c=this.said.read(e.sighting.description);c&&this.appendInfoRow(this.infoObservationList,this.messages.description,c),!this.labelsShown&&e.sighting.tags&&e.sighting.tags.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,e.sighting.tags.map(l=>this.tags.name(l)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=this.editorUrl(),this.infoAppLink.textContent="UFO@home v0.64.0",this.infoAppLink.title=this.messages.editThisObservation,this.infoAppLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCreditsList.innerHTML="";const t=this.sceneElement.currentTerrainAttribution;if(t){const o=document.createElement("li");o.textContent=t,this.infoCreditsList.appendChild(o)}const i=this.sceneElement.ufoElement.witnessMapCredit;if(i&&!t?.includes(i)){const o=document.createElement("li");o.textContent=i,this.infoCreditsList.appendChild(o)}for(const o of this.sceneElement.decorModelCredits){const c=document.createElement("li"),l=o.author?` — ${o.author}`:"";if(o.sourceUrl){const h=document.createElement("a");h.href=o.sourceUrl,h.target="_blank",h.rel="noopener",h.textContent=o.title,c.append(h,document.createTextNode(`${l} (${o.license})`))}else c.textContent=`${o.title}${l} (${o.license})`;this.infoCreditsList.appendChild(c)}for(const o of this.sceneElement.ufoElement.sighting.references){if(!o.credit)continue;const c=document.createElement("li");if(o.creditUrl){const l=document.createElement("a");l.href=o.creditUrl,l.target="_blank",l.rel="noopener",l.textContent=o.credit,c.appendChild(l)}else c.textContent=o.credit;this.infoCreditsList.appendChild(c)}const n=this.sceneElement.satelliteState;if(n.status==="ready"&&n.credit){const o=document.createElement("li"),c=document.createElement("a");c.href=n.creditUrl??"",c.target="_blank",c.rel="noopener",c.textContent=n.credit,o.appendChild(c),this.infoCreditsList.appendChild(o)}const s=document.createElement("li");s.textContent=`${IE} (`;const a=document.createElement("a");a.href=PE,a.target="_blank",a.rel="noopener",a.textContent=LE,s.appendChild(a),s.appendChild(document.createTextNode(")")),this.infoCreditsList.appendChild(s)}appendInfoRow(e,t,i){const n=document.createElement("dt");n.textContent=t;const s=document.createElement("dd");s.textContent=i,e.appendChild(n),e.appendChild(s)}}const wm="rr0-sighting",OE="witnesschange",Em="rr0-eyewitness";class UE extends v1{}function FE(){g1(),customElements.get(wm)||customElements.define(wm,v1),customElements.get(Em)||customElements.define(Em,UE)}FE();export{HE as $,tn as A,st as B,se as C,Nf as D,sn as E,$E as F,Mt as G,mt as H,VE as I,GE as J,Oe as K,vo as L,qE as M,Do as N,Rt as O,yg as P,ls as Q,oo as R,to as S,kE as T,WE as U,_e as V,dg as W,XE as X,Qr as Y,Lt as Z,zi as _,BE as a,ks as a0,ug as a1,YE as a2,nM as a3,Hc as a4,Pu as a5,$c as a6,fi as a7,Mg as a8,Ud as a9,Fd as aa,et as ab,Us as ac,go as ad,rn as ae,hs as af,zE as b,mh as c,JE as d,Vc as e,ki as f,ZE as g,Ye as h,D as i,Mf as j,KE as k,jE as l,Qv as m,tr as n,Rl as o,p2 as p,sv as q,ot as r,qa as s,It as t,tu as u,Di as v,Ld as w,us as x,lM as y,Cc as z};
|
|
7108
|
+
<${t} src="${n}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyEmbedMarkup(){try{await navigator.clipboard.writeText(this.embedMarkup.value),this.embedCopyButton.textContent=this.messages.embedCopied,window.setTimeout(()=>this.embedCopyButton.textContent=this.messages.embedCopy,1500)}catch{this.embedMarkup.select()}}offerInterpretations(e){const t=this.offeredFor===e.sighting,i=this.interpretationSelect.value;this.offeredFor=e.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=e===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(Vh,this.messages.testimony,()=>Promise.resolve(s));const a=this.caseSource;a&&er.interpretationEvents(a.json,e.sighting.id).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>er.interpretationOf(l,a.url,f=>Ka.json(f)))});const c=t&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:Vh;this.interpretationSelect.value=c,c===Vh?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(e){this.sceneElement.compareTestimony=e,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const e=this.sceneElement.compareTestimony;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(e));const t=e?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=t,this.compareButton.setAttribute("aria-label",t)}get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(e){const t=++this.interpretationToken,i=this.interpretationLoaders.get(e),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${e}":`,s)}):void 0;t===this.interpretationToken&&(this.sceneElement.interpretation=n,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(e){if("people"in e){const[t,...i]=e.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,t].join(" ")}return"org"in e?e.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.witnessDisplayName(e)??""}showConfrontation(e){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareTestimony;const t=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of e){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const a=[];n.separationDeg!==void 0&&a.push([this.messages.confrontationDirection.replace("{deg}",t.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&a.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&a.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),a.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}selectWitness(e){const t=this.entries.find(i=>i.src===e);t&&(this.currentSrc=e,this.witnessSelect.value=e,this.sceneElement.sightingData=t.sighting,this.offerInterpretations(t),this.updateTestimonyLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(OE,{detail:{src:e}})))}async runAssessments(){const e=++this.assessmentToken,t=await new e2(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateTestimonyLine(){const e=this.entries.find(n=>n.src===this.currentSrc),t=e?this.witnessDisplayName(e.sighting.witness):void 0,i=t!==void 0||this.entries.length>1;this.testimonyElement.hidden=!i,this.witnessText.textContent=t??""}witnessDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id}formatDate(e){const t=e.place?.[0],i=qa(e.time??{},t?.lng??0,e.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;return new Intl.DateTimeFormat(this.language==="fr"?"fr-FR":"en-US",{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(e,t){return e.utcOffsetHours??Math.round(t/15)}formatLocation(e){const t=e.place?.[0];if(t)return`${t.lat.toFixed(4)}, ${t.lng.toFixed(4)}`}toggleInfoPanel(){const e=!this.infoOpen;if(this.supportsPopover){const t=this.infoPanel.matches(":popover-open");e&&!t?this.infoPanel.showPopover():!e&&t&&this.infoPanel.hidePopover();return}e&&this.bringInfoButtonIntoView(),this.syncInfoOpen(e),this.infoPanel.hidden=!e,e?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const e=this.infoButton.getBoundingClientRect(),t=window.innerHeight||document.documentElement.clientHeight;e.top>=0&&e.bottom<=t||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(e){e!==this.infoOpen&&(this.infoOpen=e,this.infoButton.setAttribute("aria-expanded",String(e)),e?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false"),this.embedOpen=!1,this.infoEmbedPanel.hidden=!0,this.infoEmbedToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=e=>{const t=e.composedPath();!t.includes(this.infoPanel)&&!t.includes(this.infoButton)&&this.toggleInfoPanel()};toggleCredits(){this.creditsOpen=!this.creditsOpen,this.infoCreditsList.hidden=!this.creditsOpen,this.infoCreditsToggle.setAttribute("aria-expanded",String(this.creditsOpen)),this.creditsOpen&&this.revealInPanel(this.infoCreditsList)}toggleEmbed(){this.embedOpen=!this.embedOpen,this.infoEmbedPanel.hidden=!this.embedOpen,this.infoEmbedToggle.setAttribute("aria-expanded",String(this.embedOpen)),this.embedOpen&&(this.refreshEmbedMarkup(),this.revealInPanel(this.infoEmbedPanel))}revealInPanel(e){e.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(e){this.toggleAttribute("show-labels",e)}applyLabels(e){this.labelsShown=e,this.syncLabelsToggle(),this.refreshParamSummary(),this.populateInfoPanel()}syncLabelsToggle(){this.labelsToggle.textContent=this.labelsShown?this.messages.hideLabels:this.messages.showLabels,this.labelsToggle.setAttribute("aria-pressed",String(this.labelsShown))}refreshParamSummary(){if(this.paramSummary.hidden=!this.labelsShown,!this.labelsShown){this.paramSummary.replaceChildren(),this.summarySignature="";return}const e=this.sceneElement.ufoElement.sighting,t=[...this.summaryBuilder.entriesFor(e,this.sceneElement.ufoElement.currentTime),...this.assessmentEntries],i=t.map(a=>`${a.field}=${a.label}=${a.value}${a.unit}${a.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const a of t){s&&s.group!==a.group&&(s=void 0);const o=a.group==="witness"?this.messages.witnessGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),s={group:a.group,element:l},n.push(l)}const c=this.paramItem(a);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n)}paramItem(e){const t=document.createElement("span");t.className=e.fromSource?"param-label from-source":"param-label";const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${e.label} `,t.append(i),e.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=e.color,t.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=e.unit===""?e.value:`${e.value} ${e.unit}`,t.append(n),t}populateInfoPanel(){const e=this.entries.find(o=>o.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){const o=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(o&&this.appendInfoRow(this.infoObservationList,this.messages.case,o),!this.labelsShown){const l=this.formatDate(e.sighting);l&&this.appendInfoRow(this.infoObservationList,this.messages.date,l);const h=this.formatLocation(e.sighting);h&&this.appendInfoRow(this.infoObservationList,this.messages.location,h)}const c=this.said.read(e.sighting.description);c&&this.appendInfoRow(this.infoObservationList,this.messages.description,c),!this.labelsShown&&e.sighting.tags&&e.sighting.tags.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,e.sighting.tags.map(l=>this.tags.name(l)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=this.editorUrl(),this.infoAppLink.textContent="UFO@home v0.64.1",this.infoAppLink.title=this.messages.editThisObservation,this.infoAppLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCreditsList.innerHTML="";const t=this.sceneElement.currentTerrainAttribution;if(t){const o=document.createElement("li");o.textContent=t,this.infoCreditsList.appendChild(o)}const i=this.sceneElement.ufoElement.witnessMapCredit;if(i&&!t?.includes(i)){const o=document.createElement("li");o.textContent=i,this.infoCreditsList.appendChild(o)}for(const o of this.sceneElement.decorModelCredits){const c=document.createElement("li"),l=o.author?` — ${o.author}`:"";if(o.sourceUrl){const h=document.createElement("a");h.href=o.sourceUrl,h.target="_blank",h.rel="noopener",h.textContent=o.title,c.append(h,document.createTextNode(`${l} (${o.license})`))}else c.textContent=`${o.title}${l} (${o.license})`;this.infoCreditsList.appendChild(c)}for(const o of this.sceneElement.ufoElement.sighting.references){if(!o.credit)continue;const c=document.createElement("li");if(o.creditUrl){const l=document.createElement("a");l.href=o.creditUrl,l.target="_blank",l.rel="noopener",l.textContent=o.credit,c.appendChild(l)}else c.textContent=o.credit;this.infoCreditsList.appendChild(c)}const n=this.sceneElement.satelliteState;if(n.status==="ready"&&n.credit){const o=document.createElement("li"),c=document.createElement("a");c.href=n.creditUrl??"",c.target="_blank",c.rel="noopener",c.textContent=n.credit,o.appendChild(c),this.infoCreditsList.appendChild(o)}const s=document.createElement("li");s.textContent=`${IE} (`;const a=document.createElement("a");a.href=PE,a.target="_blank",a.rel="noopener",a.textContent=LE,s.appendChild(a),s.appendChild(document.createTextNode(")")),this.infoCreditsList.appendChild(s)}appendInfoRow(e,t,i){const n=document.createElement("dt");n.textContent=t;const s=document.createElement("dd");s.textContent=i,e.appendChild(n),e.appendChild(s)}}const wm="rr0-sighting",OE="witnesschange",Em="rr0-eyewitness";class UE extends v1{}function FE(){g1(),customElements.get(wm)||customElements.define(wm,v1),customElements.get(Em)||customElements.define(Em,UE)}FE();export{HE as $,tn as A,st as B,se as C,Nf as D,sn as E,$E as F,Mt as G,mt as H,VE as I,GE as J,Oe as K,vo as L,qE as M,Do as N,Rt as O,yg as P,ls as Q,oo as R,to as S,kE as T,WE as U,_e as V,dg as W,XE as X,Qr as Y,Lt as Z,zi as _,BE as a,ks as a0,ug as a1,YE as a2,nM as a3,Hc as a4,Pu as a5,$c as a6,fi as a7,Mg as a8,Ud as a9,Fd as aa,et as ab,Us as ac,go as ad,rn as ae,hs as af,zE as b,mh as c,JE as d,Vc as e,ki as f,ZE as g,Ye as h,D as i,Mf as j,KE as k,jE as l,Qv as m,tr as n,Rl as o,p2 as p,sv as q,ot as r,qa as s,It as t,tu as u,Di as v,Ld as w,us as x,lM as y,Cc as z};
|
|
@@ -7655,7 +7655,7 @@ void main()
|
|
|
7655
7655
|
if (ice <= 0.0) discard;
|
|
7656
7656
|
gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
|
|
7657
7657
|
}
|
|
7658
|
-
`,transparent:!0,blending:Fi,depthWrite:!1,side:Ht,fog:!1}),this.object=new ke(new ii(Pi.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(e){this.hostedByDeck=e,this.show(this.shown)}show(e){this.shown=e,this.object.visible=e&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=e?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(e){this.urgent=e}set onReady(e){this.onRepaint=e}update(e,t,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(e.x,e.y,e.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(t,a)}requestMap(e,t){if(!(!(Math.abs(e-this.mappedAltitudeDeg)<Pi.ALTITUDE_STEP_DEG)||!(Math.abs(t-this.mappedAlignment)<Pi.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(e,t)){this.next=void 0;return}if(!(!(Math.abs(e-this.pendingAltitudeDeg)<Pi.LEAP_ALTITUDE_DEG)||!(Math.abs(t-this.pendingAlignment)<Pi.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:e,alignment:t};return}}this.next=void 0,this.pendingAltitudeDeg=e,this.pendingAlignment=t,this.sky.begin(e,t),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(e,t){return this.tracing&&Math.abs(e-this.pendingAltitudeDeg)<Pi.ALTITUDE_STEP_DEG&&Math.abs(t-this.pendingAlignment)<Pi.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const e=()=>{if(this.workHandle=void 0,!this.tracing)return;const t=performance.now(),i=this.urgent?Pi.URGENT_BUDGET_MS:Pi.BUDGET_MS;do this.sky.trace(Pi.RAYS_PER_BATCH);while(this.sky.tracedRays<Pi.RAYS&&performance.now()-t<i);if(this.sky.tracedRays>=Pi.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(e)};this.workHandle=requestAnimationFrame(e)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const t=this.sky.harvest().data;for(let i=0,n=0;n<t.length;i+=4,n+=3)this.texels[i]=vs.toHalfFloat(t[n]),this.texels[i+1]=vs.toHalfFloat(t[n+1]),this.texels[i+2]=vs.toHalfFloat(t[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 di{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=di.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(di.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 e=di.MAX_CONCURRENT*di.SEGMENTS*di.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new Mt;t.setAttribute("position",new lt(this.positions,3)),t.setAttribute("color",new lt(this.colors,3)),t.setDrawRange(0,0),this.object=new ke(t,new un({vertexColors:!0,transparent:!0,blending:Fi,depthWrite:!1,fog:!1,side:cn})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(e,t,i){this.meteors=e,this.radiantAltitudeDeg=t,this.radiantAzimuthDeg=i}update(e){const t=this.object.geometry;if(this.meteors.length===0){t.setDrawRange(0,0);return}const i=Sr.aliveAt(this.meteors,e).slice(0,di.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const l=mi(o.altitudeDeg,o.azimuthDeg,1),[c,h]=this.basisAround(l),d=s.fromRadiantDeg+a*s.lengthDeg,u=Math.max(s.fromRadiantDeg,d-s.lengthDeg*.6),f=Math.min(1,(1-a)*2.5),p=this.turn(c,h,s.bearingDeg),v=(.15+.85*s.brightness)*f,m=x=>v*x**1.6,g=x=>this.onSphere(l,p,u+(d-u)*x),w=x=>di.RADIUS*((di.MIN_HALF_WIDTH_DEG+di.BRIGHT_HALF_WIDTH_DEG*s.brightness*x)*Math.PI/180);for(let x=1;x<di.POINTS;x++){const b=(x-1)/di.SEGMENTS,S=x/di.SEGMENTS;n=this.pushRibbon(n,g(b),g(S),w(b),w(S),m(b),m(S))}}t.setDrawRange(0,n),t.getAttribute("position").needsUpdate=!0,t.getAttribute("color").needsUpdate=!0}midpointOf(e){const t=this.radiantOf(e);if(!t)return;const i=mi(t.altitudeDeg,t.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,e.bearingDeg),o=this.onSphere(i,a,e.fromRadiantDeg+e.lengthDeg/2),l=Math.hypot(o.x,o.y,o.z)||1;return{altitudeDeg:Math.asin(o.y/l)*180/Math.PI,azimuthDeg:(Math.atan2(o.x,-o.z)*180/Math.PI+360)%360}}radiantOf(e){return e.radiant?e.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(e,t,i,n,s,a,o){const l=this.normalise(this.cross(this.normalise(t),this.normalise(this.subtract(i,t))));for(let c=0;c<di.ACROSS-1;c++){const h=c-1,d=c,u=this.across(t,l,n,h),f=this.across(i,l,s,h),p=this.across(t,l,n,d),v=this.across(i,l,s,d),m=(g,w)=>g===0?w:0;e=this.push(e,u,m(h,a)),e=this.push(e,f,m(h,o)),e=this.push(e,p,m(d,a)),e=this.push(e,f,m(h,o)),e=this.push(e,v,m(d,o)),e=this.push(e,p,m(d,a))}return e}across(e,t,i,n){return{x:e.x+t.x*i*n,y:e.y+t.y*i*n,z:e.z+t.z*i*n}}push(e,t,i){const n=e*3;this.positions[n]=t.x,this.positions[n+1]=t.y,this.positions[n+2]=t.z;const s=Math.max(0,Math.min(1,i));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,e+1}turn(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:e.x*s+t.x*a,y:e.y*s+t.y*a,z:e.z*s+t.z*a}}onSphere(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(e.x*s+t.x*a)*di.RADIUS,y:(e.y*s+t.y*a)*di.RADIUS,z:(e.z*s+t.z*a)*di.RADIUS}}basisAround(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(e,t));return[i,this.normalise(this.cross(e,i))]}subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}const jh=Math.PI/180;function $t(r,e,t,i,n=!1){const s=n?new un({color:new se(...t)}):new Xo({color:new se(...t)}),a=new ke(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const vm=.25,j_=.002,Q_=20;function e5(r){const e=/^#([0-9a-f]{6})$/i.exec(r);if(!e)return[1,1,1];const t=parseInt(e[1],16);return[(t>>16&255)/255,(t>>8&255)/255,(t&255)/255]}const av=[.32,.32,.3],ov=[1,.85,.5],lv=[.25,.25,.25],cv=[1,.97,.85],t5=[.55,.68,.72],zn=.03,Hn=.05,hv={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 Oi(r,e){return r?.[e]}function Gn(r,e,t,i,n,s,a,o){if(o===void 0)return;const l=new Xo({color:new se(...t5),transparent:!0,opacity:o/100}),c=new ke(new tn(e,t,i),l);c.position.set(n,s,a),r.add(c)}const an=.05,Qh=[.6,.58,.53],ym=[.5,.5,.48];function ya(r,e,t,i,n,s,a,o){const l=new Xo({color:new se(...o),side:Ht}),c=new ke(new tn(e,t,i),l);c.position.set(n,s,a),r.add(c)}function i5(r,e,t,i,n,s,a,o,l){const c=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?ya(r,p,v,an,m,o+g,a,l):ya(r,an,v,p,a,o+g,m,l))};h(t,c,0,i/2-c/2),h(t,c,0,-(i/2-c/2));const d=[...n].sort((p,v)=>p.center-v.center);let u=-t/2;for(const p of d){const m=p.center-p.main/2-u;h(m,s,u+m/2,0),u=p.center+p.main/2}const f=t/2-u;h(f,s,u+f/2,0)}function dv(r,e,t,i,n,s,a,o,l,c){const h=(i+n)/2,d=n-i,u=(f,p,v,m)=>{f.length===0?p?ya(r,v,d,an,0,h,m,Qh):ya(r,an,d,v,m,h,0,Qh):i5(r,p,v,d,f,s,m,h,Qh)};u(a,!0,e*2,-t+an),u(o,!0,e*2,t-an),u(l,!1,t*2,-e+an),u(c,!1,t*2,e-an),ya(r,e*2,an,t*2,0,i+an,0,ym),ya(r,e*2,an,t*2,0,n-an,0,ym)}function Qu(r,e,t,i){switch(r){case"front":return{x:0,z:-(t-i)};case"behind":return{x:0,z:t-i};case"left":return{x:-(e-i),z:0};case"right":return{x:e-i,z:0};case"front-left":return{x:-(e-i),z:-Vn};case"front-right":return{x:e-i,z:-Vn};case"behind-left":return{x:-(e-i),z:Vn};case"behind-right":return{x:e-i,z:Vn}}}function uv(r,e,t,i,n,s,a){const o=nf();o.scale.setScalar(i),o.rotation.y=hv[e];const{x:l,z:c}=Qu(e,n,s,a);o.position.set(l,t,c),r.add(o)}const ef=6,tf=6,Us=3,lo=1.4,co=Us*.5,fv=1.2,pv=.35,n5=.75,s5=1.6;function bm(r,e,t,i){const n=new zt,s=Math.max(1,r+1),a=s*Us;$t(n,new tn(ef,a,tf),[.55,.54,.5],a/2);const o=ef/2,l=tf/2;for(let c=0;c<s;c++){const h=c*Us+Us/2;Gn(n,lo,co,Hn,0,h,-l-zn,Oi(e,"front")),Gn(n,lo,co,Hn,0,h,l+zn,Oi(e,"behind")),Gn(n,Hn,co,lo,-o-zn,h,0,Oi(e,"left")),Gn(n,Hn,co,lo,o+zn,h,0,Oi(e,"right"))}if(t){const c=Math.min(Math.max(i??0,0),s-1);uv(n,t,c*Us,.72,o,l,fv);const h=d=>Oi(e,d)!==void 0?[{main:lo,center:0}]:[];dv(n,o,l,c*Us,(c+1)*Us,co,h("front"),h("behind"),h("left"),h("right"))}return n}function Mm(){const r=new zt,e=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[t,i,n,s]of e){const a=new ii(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),$t(r,a,[.26,.28,.17],s)}return r}function wm(){const r=new zt;return $t(r,new ts(.15,.22,2,8),[.32,.22,.14],1),$t(r,new Va(1.4,3,8),[.16,.32,.14],3.5),r}const xm=.275,r5=.35,a5=.9,o5=34,l5=8,c5=1.4;function Sm(){const r=new zt,e=new ii(xm,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,r5/xm,1);const t=si.repeatOnGrid(e,o5,a5,l5,c5),i=$t(r,t,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Em(){const r=new zt,e=new ii(1,7,3,0,Math.PI*2,0,Math.PI/2);return $t(r,e,[.38,.36,.32],0),r}function _m(r){const e=new zt;return $t(e,new ts(.05,.08,5,8),[.28,.28,.3],2.5),$t(e,new ii(.25,12,8),r?ov:av,5.1,!0),e}const h5=[.08,.08,.08],Ns=.8,da=1,kn=1.7,ed=.6,nr=.4,Hl=1.2,sa=.7,Vn=.5,d5=kn;function Tm(r,e,t){const i=new zt;$t(i,new tn(1.8,1.4,4.2),[.45,.14,.14],.7),$t(i,new tn(Ns*2,ed,da*2),[.4,.12,.12],kn);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=$t(i,new ts(.4,.4,.3,12),h5,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?cv:lv;for(const s of[-.7,.7])$t(i,new ii(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(Gn(i,Hl,nr,Hn,0,kn,-da-zn,Oi(e,"front")),Gn(i,Hl,nr,Hn,0,kn,da+zn,Oi(e,"behind")),Gn(i,Hn,nr,sa,-Ns-zn,kn,-Vn,Oi(e,"front-left")),Gn(i,Hn,nr,sa,-Ns-zn,kn,Vn,Oi(e,"behind-left")),Gn(i,Hn,nr,sa,Ns+zn,kn,-Vn,Oi(e,"front-right")),Gn(i,Hn,nr,sa,Ns+zn,kn,Vn,Oi(e,"behind-right")),t){uv(i,t,n5,.5,Ns,da,pv);const s=(l,c)=>{const h=[];return Oi(e,l)!==void 0&&h.push({main:sa,center:-Vn}),Oi(e,c)!==void 0&&h.push({main:sa,center:Vn}),h},a=Oi(e,"front")!==void 0?[{main:Hl,center:0}]:[],o=Oi(e,"behind")!==void 0?[{main:Hl,center:0}]:[];dv(i,Ns,da,kn-ed/2,kn+ed/2,nr,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Am=new Map;function Im(r,e){if(!r)return;const t=[[r.lengthM,e.lengthM],[r.heightM,e.heightM],[r.widthM,e.widthM]];for(const[i,n]of t)if(i!==void 0&&n>1e-6)return i/n}function td(r,e){return e>1e-6?r/e:1}const mv=[.95,.9,.82],Dm=[.72,.74,.78];function Cm(){const r=new zt;$t(r,new ts(.25,.3,1.5,10),Dm,.75),$t(r,new ii(.26,10,8),Dm,1.74);const e=$t(r,new Va(.07,.16,8),mv,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function nf(){const r=new zt;$t(r,new ts(.25,.3,1.5,10),[.3,.3,.35],.75),$t(r,new ii(.22,10,8),[.62,.52,.46],1.72);const e=$t(r,new Va(.07,.16,8),mv,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const u5=17,Rm=18.5,id=[.16,.16,.18];function Pm(){const r=new zt,e=$t(r,new ts(1.8,1.8,Rm*2,10),id,0);e.rotation.x=Math.PI/2,$t(r,new tn(u5*2,.5,4.5),id,0);const t=$t(r,new tn(.4,5.5,4),id,3);return t.position.z=-Rm+2,r}class si{static groundUnderFootprint(e,t,i,n,s,a=0){const o=si.sizeOf(e);if(a>o.heightM)return s(t,i);const l=(n??0)*Math.PI/180,c=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));let d=-1/0;for(let u=0;u<c;u++){const f=(u/(c-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=t+Math.sin(l)*f+Math.cos(l)*v,g=i-Math.cos(l)*f+Math.sin(l)*v;d=Math.max(d,s(m,g))}}return Number.isFinite(d)?d:s(t,i)}static occupantView(e){const t=e.witnessSide;if(!t)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=e.kind==="vehicle"?Qu(t,Ns,da,pv):Qu(t,ef/2,tf/2,fv),s=e.kind==="vehicle"?d5:(e.occupiedFloor??0)*Us+s5,a=(e.headingDeg??0)-hv[t]/jh,o=this.scaleFor(e);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(e){return e.getObjectByName(si.BODY_NAME)??e}static repeatOnGrid(e,t,i,n,s){const a=e.getAttribute("position"),o=e.getAttribute("normal"),l=e.getIndex();if(!l)throw new Error("repeatOnGrid needs an indexed geometry");const c=a.count,h=t*n,d=new Float32Array(c*h*3),u=new Float32Array(c*h*3),f=new Uint32Array(l.count*h),p=-((t-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let w=0;w<n;w++)for(let x=0;x<t;x++,m++){const b=v+w*s,S=p+x*i;for(let _=0;_<c;_++){const D=(m*c+_)*3;d[D]=a.getX(_)+b,d[D+1]=a.getY(_),d[D+2]=a.getZ(_)+S,u[D]=o.getX(_),u[D+1]=o.getY(_),u[D+2]=o.getZ(_)}for(let _=0;_<l.count;_++)f[m*l.count+_]=l.getX(_)+m*c}const g=new Mt;return g.setAttribute("position",new bt(d,3)),g.setAttribute("normal",new bt(u,3)),g.setIndex(new _f(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new P;e.traverse(n=>{const s=n,a=s.userData.cropBasePositions,o=s.userData.cropVerticesPerClump;if(!s.isMesh||!a||!o)return;const l=s.geometry.getAttribute("position"),c=new Ye().copy(s.matrixWorld).invert();for(let h=0;h<l.count;h+=o){i.set(a[h*3],0,a[h*3+2]).applyMatrix4(s.matrixWorld),i.y=t(i.x,i.z),i.applyMatrix4(c);for(let d=h;d<h+o;d++)l.setY(d,a[d*3+1]+i.y)}l.needsUpdate=!0,s.geometry.computeBoundingBox(),s.geometry.computeBoundingSphere()})}static paint(e,t){e.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(t)})}static build(e,t){const i=e.kind==="building"?bm(e.floors??Ma,e.windows,e.witnessSide,e.occupiedFloor):e.kind==="tree"?wm():e.kind==="shrub"?Mm():e.kind==="crop"?Sm():e.kind==="mound"?Em():e.kind==="streetlight"?_m(t):e.kind==="vehicle"?Tm(t,e.windows,e.witnessSide):e.kind==="aircraft"?Pm():e.kind==="entity"?Cm():nf();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new zt;return i.name=si.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*jh),this.addLights(s,e.lights),e.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(e){const t=e.sizeM;if(!t)return new P(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new P(t.widthM===void 0?1:td(t.widthM,i.widthM),t.heightM===void 0?1:td(t.heightM,i.heightM),t.lengthM===void 0?1:td(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??Ma)+1):0,n=`${e}:${i}`,s=Am.get(n);if(s)return s;const a=e==="building"?bm(i-1,void 0,void 0,void 0):e==="tree"?wm():e==="shrub"?Mm():e==="crop"?Sm():e==="mound"?Em():e==="streetlight"?_m(!1):e==="vehicle"?Tm(!1,void 0,void 0):e==="aircraft"?Pm():e==="entity"?Cm():nf(),o=new fn().setFromObject(a),l={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),Am.set(n,l),l}static usesModel(e){return e.model!==void 0&&!(e.witnessSide!==void 0&&pa(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new zt;a.name=si.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*jh,i.updateMatrixWorld(!0);const o=new fn().setFromObject(i),l={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},c=Im(t.sizeM,l)??Im(n.depictedSizeM,l)??1;i.scale.multiplyScalar(c);const h=o.getCenter(new P).multiplyScalar(c);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=t.kind==="aircraft"?h.y:o.min.y*c,i.traverse(d=>{d instanceof ke&&(d.castShadow=!0,d.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):e.add(a),this.dispose(s)}static sizeOf(e){const t=this.naturalSize(e.kind,e.floors);return{widthM:e.sizeM?.widthM??t.widthM,lengthM:e.sizeM?.lengthM??t.lengthM,heightM:e.sizeM?.heightM??t.heightM}}static exemptFromFog(e){e.traverse(t=>{if(!(t instanceof ke))return;const i=t.material;i.fog=!1,i.needsUpdate=!0})}static addLights(e,t){for(const i of t??[]){const n=e5(i.color),s=$t(e,new ii(vm,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}}static setLights(e,t,i,n,s=0){if(!t||t.length===0)return;const a=new Map(t.map(l=>[l.id,l])),o=Math.max(1,n*j_/vm);for(const l of e.children){if(!(l instanceof ke))continue;const c=l.userData.lightId;if(!c)continue;const h=a.get(c);if(!h)continue;const d=s>0?Fg(h,i,i+s):m2(h,i)?1:0;l.visible=d>0;const u=l.material,f=l.userData.lightColor;if(f){const p=s>0?d*Q_*(h.intensity??1):d;u.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}l.scale.setScalar(o)}}static setLit(e,t,i){const n=t==="streetlight"?i?ov:av:i?cv:lv;e.traverse(s=>{const a=s.userData;!(s instanceof ke)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(e){e.traverse(t=>{if(!(t instanceof ke))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const nd="https://ufoathome.org/models/index.json";class f5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??p5()}async entries(e){const t=await this.load();return e?t.filter(i=>i.kind===e):t}async entry(e){return(await this.load()).find(t=>t.id===e)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const e of this.indexUrls){const t=await this.fetchIndex(e);if(t)return t}return[]}async fetchIndex(e){try{const t=await this.fetchImpl(e);if(!t.ok)return;const i=await t.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,e).href})):void 0}catch{return}}}function p5(){const r=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return r&&r!==nd?[r,nd]:[nd]}const cc=[{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 f5}];async function Lm(r){const{GLTFLoader:e}=await dn(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-BeVCsKtR.js");return{GLTFLoader:i}},[],import.meta.url),t=new e;return new Promise((i,n)=>{t.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const gv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class ln{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new _1(16777215,0,0,2);glow;constructor(){const e=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);e.push(new we(Math.max(o,1e-4),-a))}const i=new Xc(e,48),n=new wt({uniforms:{uTime:{value:0},uColor:{value:new se(1,1,1)},uTipColor:{value:new se(1,1,1)}},vertexShader:ln.VERTEX,fragmentShader:ln.FRAGMENT,transparent:!0,depthWrite:!1,blending:Fi,side:cn,toneMapped:!1});this.mesh=new ke(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=ln.RENDER_ORDER,this.mesh.visible=!1,this.glow=new ke(new pn(2,2),new wt({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:ln.GLOW_VERTEX,fragmentShader:ln.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Fi,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=ln.RENDER_ORDER,this.glow.visible=!1}static glowFor(e,t){const i=Math.max(e.widthM*.6,t*ln.GLOW_MIN_ANGLE_RAD),n=.7*e.widthM*e.lengthM,s=ln.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:e.luminanceCdM2*Math.min(ln.GLOW_MAX_SHARE,n/s)}}shine(e,t){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=e,this.glow.material.uniforms.uColor.value.setRGB(t[0],t[1],t[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(e,t,i,n){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.quaternion.set(t.x,t.y,t.z,t.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(e,t,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(e[0],e[1],e[2]),n.uTipColor.value.setRGB(t[0],t[1],t[2]),n.uTime.value=i}illuminate(e,t){this.light.intensity=e,this.light.color.setRGB(t[0],t[1],t[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
7658
|
+
`,transparent:!0,blending:Fi,depthWrite:!1,side:Ht,fog:!1}),this.object=new ke(new ii(Pi.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(e){this.hostedByDeck=e,this.show(this.shown)}show(e){this.shown=e,this.object.visible=e&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=e?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(e){this.urgent=e}set onReady(e){this.onRepaint=e}update(e,t,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(e.x,e.y,e.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(t,a)}requestMap(e,t){if(!(!(Math.abs(e-this.mappedAltitudeDeg)<Pi.ALTITUDE_STEP_DEG)||!(Math.abs(t-this.mappedAlignment)<Pi.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(e,t)){this.next=void 0;return}if(!(!(Math.abs(e-this.pendingAltitudeDeg)<Pi.LEAP_ALTITUDE_DEG)||!(Math.abs(t-this.pendingAlignment)<Pi.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:e,alignment:t};return}}this.next=void 0,this.pendingAltitudeDeg=e,this.pendingAlignment=t,this.sky.begin(e,t),this.tracing=!0,this.scheduleWork()}pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(e,t){return this.tracing&&Math.abs(e-this.pendingAltitudeDeg)<Pi.ALTITUDE_STEP_DEG&&Math.abs(t-this.pendingAlignment)<Pi.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const e=()=>{if(this.workHandle=void 0,!this.tracing)return;const t=performance.now(),i=this.urgent?Pi.URGENT_BUDGET_MS:Pi.BUDGET_MS;do this.sky.trace(Pi.RAYS_PER_BATCH);while(this.sky.tracedRays<Pi.RAYS&&performance.now()-t<i);if(this.sky.tracedRays>=Pi.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(e)};this.workHandle=requestAnimationFrame(e)}stopWork(){this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){const t=this.sky.harvest().data;for(let i=0,n=0;n<t.length;i+=4,n+=3)this.texels[i]=vs.toHalfFloat(t[n]),this.texels[i+1]=vs.toHalfFloat(t[n+1]),this.texels[i+2]=vs.toHalfFloat(t[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 di{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=di.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(di.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 e=di.MAX_CONCURRENT*di.SEGMENTS*di.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new Mt;t.setAttribute("position",new lt(this.positions,3)),t.setAttribute("color",new lt(this.colors,3)),t.setDrawRange(0,0),this.object=new ke(t,new un({vertexColors:!0,transparent:!0,blending:Fi,depthWrite:!1,fog:!1,side:cn})),this.object.frustumCulled=!1}get schedule(){return this.meteors}setShower(e,t,i){this.meteors=e,this.radiantAltitudeDeg=t,this.radiantAzimuthDeg=i}update(e){const t=this.object.geometry;if(this.meteors.length===0){t.setDrawRange(0,0);return}const i=Sr.aliveAt(this.meteors,e).slice(0,di.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const l=mi(o.altitudeDeg,o.azimuthDeg,1),[c,h]=this.basisAround(l),d=s.fromRadiantDeg+a*s.lengthDeg,u=Math.max(s.fromRadiantDeg,d-s.lengthDeg*.6),f=Math.min(1,(1-a)*2.5),p=this.turn(c,h,s.bearingDeg),v=(.15+.85*s.brightness)*f,m=x=>v*x**1.6,g=x=>this.onSphere(l,p,u+(d-u)*x),w=x=>di.RADIUS*((di.MIN_HALF_WIDTH_DEG+di.BRIGHT_HALF_WIDTH_DEG*s.brightness*x)*Math.PI/180);for(let x=1;x<di.POINTS;x++){const b=(x-1)/di.SEGMENTS,S=x/di.SEGMENTS;n=this.pushRibbon(n,g(b),g(S),w(b),w(S),m(b),m(S))}}t.setDrawRange(0,n),t.getAttribute("position").needsUpdate=!0,t.getAttribute("color").needsUpdate=!0}midpointOf(e){const t=this.radiantOf(e);if(!t)return;const i=mi(t.altitudeDeg,t.azimuthDeg,1),[n,s]=this.basisAround(i),a=this.turn(n,s,e.bearingDeg),o=this.onSphere(i,a,e.fromRadiantDeg+e.lengthDeg/2),l=Math.hypot(o.x,o.y,o.z)||1;return{altitudeDeg:Math.asin(o.y/l)*180/Math.PI,azimuthDeg:(Math.atan2(o.x,-o.z)*180/Math.PI+360)%360}}radiantOf(e){return e.radiant?e.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(e,t,i,n,s,a,o){const l=this.normalise(this.cross(this.normalise(t),this.normalise(this.subtract(i,t))));for(let c=0;c<di.ACROSS-1;c++){const h=c-1,d=c,u=this.across(t,l,n,h),f=this.across(i,l,s,h),p=this.across(t,l,n,d),v=this.across(i,l,s,d),m=(g,w)=>g===0?w:0;e=this.push(e,u,m(h,a)),e=this.push(e,f,m(h,o)),e=this.push(e,p,m(d,a)),e=this.push(e,f,m(h,o)),e=this.push(e,v,m(d,o)),e=this.push(e,p,m(d,a))}return e}across(e,t,i,n){return{x:e.x+t.x*i*n,y:e.y+t.y*i*n,z:e.z+t.z*i*n}}push(e,t,i){const n=e*3;this.positions[n]=t.x,this.positions[n+1]=t.y,this.positions[n+2]=t.z;const s=Math.max(0,Math.min(1,i));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,e+1}turn(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:e.x*s+t.x*a,y:e.y*s+t.y*a,z:e.z*s+t.z*a}}onSphere(e,t,i){const n=i*Math.PI/180,s=Math.cos(n),a=Math.sin(n);return{x:(e.x*s+t.x*a)*di.RADIUS,y:(e.y*s+t.y*a)*di.RADIUS,z:(e.z*s+t.z*a)*di.RADIUS}}basisAround(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(e,t));return[i,this.normalise(this.cross(e,i))]}subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}const jh=Math.PI/180;function $t(r,e,t,i,n=!1){const s=n?new un({color:new se(...t)}):new Xo({color:new se(...t)}),a=new ke(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const vm=.25,j_=.002,Q_=20;function e5(r){const e=/^#([0-9a-f]{6})$/i.exec(r);if(!e)return[1,1,1];const t=parseInt(e[1],16);return[(t>>16&255)/255,(t>>8&255)/255,(t&255)/255]}const av=[.32,.32,.3],ov=[1,.85,.5],lv=[.25,.25,.25],cv=[1,.97,.85],t5=[.55,.68,.72],zn=.03,Hn=.05,hv={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 Oi(r,e){return r?.[e]}function Gn(r,e,t,i,n,s,a,o){if(o===void 0)return;const l=new Xo({color:new se(...t5),transparent:!0,opacity:o/100}),c=new ke(new tn(e,t,i),l);c.position.set(n,s,a),r.add(c)}const an=.05,Qh=[.6,.58,.53],ym=[.5,.5,.48];function ya(r,e,t,i,n,s,a,o){const l=new Xo({color:new se(...o),side:Ht}),c=new ke(new tn(e,t,i),l);c.position.set(n,s,a),r.add(c)}function i5(r,e,t,i,n,s,a,o,l){const c=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?ya(r,p,v,an,m,o+g,a,l):ya(r,an,v,p,a,o+g,m,l))};h(t,c,0,i/2-c/2),h(t,c,0,-(i/2-c/2));const d=[...n].sort((p,v)=>p.center-v.center);let u=-t/2;for(const p of d){const m=p.center-p.main/2-u;h(m,s,u+m/2,0),u=p.center+p.main/2}const f=t/2-u;h(f,s,u+f/2,0)}function dv(r,e,t,i,n,s,a,o,l,c){const h=(i+n)/2,d=n-i,u=(f,p,v,m)=>{f.length===0?p?ya(r,v,d,an,0,h,m,Qh):ya(r,an,d,v,m,h,0,Qh):i5(r,p,v,d,f,s,m,h,Qh)};u(a,!0,e*2,-t+an),u(o,!0,e*2,t-an),u(l,!1,t*2,-e+an),u(c,!1,t*2,e-an),ya(r,e*2,an,t*2,0,i+an,0,ym),ya(r,e*2,an,t*2,0,n-an,0,ym)}function Qu(r,e,t,i){switch(r){case"front":return{x:0,z:-(t-i)};case"behind":return{x:0,z:t-i};case"left":return{x:-(e-i),z:0};case"right":return{x:e-i,z:0};case"front-left":return{x:-(e-i),z:-Vn};case"front-right":return{x:e-i,z:-Vn};case"behind-left":return{x:-(e-i),z:Vn};case"behind-right":return{x:e-i,z:Vn}}}function uv(r,e,t,i,n,s,a){const o=nf();o.scale.setScalar(i),o.rotation.y=hv[e];const{x:l,z:c}=Qu(e,n,s,a);o.position.set(l,t,c),r.add(o)}const ef=6,tf=6,Us=3,lo=1.4,co=Us*.5,fv=1.2,pv=.35,n5=.75,s5=1.6;function bm(r,e,t,i){const n=new zt,s=Math.max(1,r+1),a=s*Us;$t(n,new tn(ef,a,tf),[.55,.54,.5],a/2);const o=ef/2,l=tf/2;for(let c=0;c<s;c++){const h=c*Us+Us/2;Gn(n,lo,co,Hn,0,h,-l-zn,Oi(e,"front")),Gn(n,lo,co,Hn,0,h,l+zn,Oi(e,"behind")),Gn(n,Hn,co,lo,-o-zn,h,0,Oi(e,"left")),Gn(n,Hn,co,lo,o+zn,h,0,Oi(e,"right"))}if(t){const c=Math.min(Math.max(i??0,0),s-1);uv(n,t,c*Us,.72,o,l,fv);const h=d=>Oi(e,d)!==void 0?[{main:lo,center:0}]:[];dv(n,o,l,c*Us,(c+1)*Us,co,h("front"),h("behind"),h("left"),h("right"))}return n}function Mm(){const r=new zt,e=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[t,i,n,s]of e){const a=new ii(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),$t(r,a,[.26,.28,.17],s)}return r}function wm(){const r=new zt;return $t(r,new ts(.15,.22,2,8),[.32,.22,.14],1),$t(r,new Va(1.4,3,8),[.16,.32,.14],3.5),r}const xm=.275,r5=.35,a5=.9,o5=34,l5=8,c5=1.4;function Sm(){const r=new zt,e=new ii(xm,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,r5/xm,1);const t=si.repeatOnGrid(e,o5,a5,l5,c5),i=$t(r,t,[.26,.28,.22],0);return i.castShadow=!1,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Em(){const r=new zt,e=new ii(1,7,3,0,Math.PI*2,0,Math.PI/2);return $t(r,e,[.38,.36,.32],0),r}function _m(r){const e=new zt;return $t(e,new ts(.05,.08,5,8),[.28,.28,.3],2.5),$t(e,new ii(.25,12,8),r?ov:av,5.1,!0),e}const h5=[.08,.08,.08],Ns=.8,da=1,kn=1.7,ed=.6,nr=.4,Hl=1.2,sa=.7,Vn=.5,d5=kn;function Tm(r,e,t){const i=new zt;$t(i,new tn(1.8,1.4,4.2),[.45,.14,.14],.7),$t(i,new tn(Ns*2,ed,da*2),[.4,.12,.12],kn);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=$t(i,new ts(.4,.4,.3,12),h5,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?cv:lv;for(const s of[-.7,.7])$t(i,new ii(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(Gn(i,Hl,nr,Hn,0,kn,-da-zn,Oi(e,"front")),Gn(i,Hl,nr,Hn,0,kn,da+zn,Oi(e,"behind")),Gn(i,Hn,nr,sa,-Ns-zn,kn,-Vn,Oi(e,"front-left")),Gn(i,Hn,nr,sa,-Ns-zn,kn,Vn,Oi(e,"behind-left")),Gn(i,Hn,nr,sa,Ns+zn,kn,-Vn,Oi(e,"front-right")),Gn(i,Hn,nr,sa,Ns+zn,kn,Vn,Oi(e,"behind-right")),t){uv(i,t,n5,.5,Ns,da,pv);const s=(l,c)=>{const h=[];return Oi(e,l)!==void 0&&h.push({main:sa,center:-Vn}),Oi(e,c)!==void 0&&h.push({main:sa,center:Vn}),h},a=Oi(e,"front")!==void 0?[{main:Hl,center:0}]:[],o=Oi(e,"behind")!==void 0?[{main:Hl,center:0}]:[];dv(i,Ns,da,kn-ed/2,kn+ed/2,nr,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Am=new Map;function Im(r,e){if(!r)return;const t=[[r.lengthM,e.lengthM],[r.heightM,e.heightM],[r.widthM,e.widthM]];for(const[i,n]of t)if(i!==void 0&&n>1e-6)return i/n}function td(r,e){return e>1e-6?r/e:1}const mv=[.95,.9,.82],Dm=[.72,.74,.78];function Cm(){const r=new zt;$t(r,new ts(.25,.3,1.5,10),Dm,.75),$t(r,new ii(.26,10,8),Dm,1.74);const e=$t(r,new Va(.07,.16,8),mv,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function nf(){const r=new zt;$t(r,new ts(.25,.3,1.5,10),[.3,.3,.35],.75),$t(r,new ii(.22,10,8),[.62,.52,.46],1.72);const e=$t(r,new Va(.07,.16,8),mv,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const u5=17,Rm=18.5,id=[.16,.16,.18];function Pm(){const r=new zt,e=$t(r,new ts(1.8,1.8,Rm*2,10),id,0);e.rotation.x=Math.PI/2,$t(r,new tn(u5*2,.5,4.5),id,0);const t=$t(r,new tn(.4,5.5,4),id,3);return t.position.z=-Rm+2,r}class si{static groundUnderFootprint(e,t,i,n,s,a=0){const o=si.sizeOf(e);if(a>o.heightM)return s(t,i);const l=(n??0)*Math.PI/180,c=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));let d=-1/0;for(let u=0;u<c;u++){const f=(u/(c-1)-.5)*o.lengthM;for(let p=0;p<h;p++){const v=(p/(h-1)-.5)*o.widthM,m=t+Math.sin(l)*f+Math.cos(l)*v,g=i-Math.cos(l)*f+Math.sin(l)*v;d=Math.max(d,s(m,g))}}return Number.isFinite(d)?d:s(t,i)}static occupantView(e){const t=e.witnessSide;if(!t)throw new Error("occupantView requires object.witnessSide to be set");const{x:i,z:n}=e.kind==="vehicle"?Qu(t,Ns,da,pv):Qu(t,ef/2,tf/2,fv),s=e.kind==="vehicle"?d5:(e.occupiedFloor??0)*Us+s5,a=(e.headingDeg??0)-hv[t]/jh,o=this.scaleFor(e);return{x:i*o.x,z:n*o.z,eyeY:s*o.y,headingDeg:a}}static BODY_NAME="decor-body";static bodyOf(e){return e.getObjectByName(si.BODY_NAME)??e}static repeatOnGrid(e,t,i,n,s){const a=e.getAttribute("position"),o=e.getAttribute("normal"),l=e.getIndex();if(!l)throw new Error("repeatOnGrid needs an indexed geometry");const c=a.count,h=t*n,d=new Float32Array(c*h*3),u=new Float32Array(c*h*3),f=new Uint32Array(l.count*h),p=-((t-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let w=0;w<n;w++)for(let x=0;x<t;x++,m++){const b=v+w*s,S=p+x*i;for(let _=0;_<c;_++){const D=(m*c+_)*3;d[D]=a.getX(_)+b,d[D+1]=a.getY(_),d[D+2]=a.getZ(_)+S,u[D]=o.getX(_),u[D+1]=o.getY(_),u[D+2]=o.getZ(_)}for(let _=0;_<l.count;_++)f[m*l.count+_]=l.getX(_)+m*c}const g=new Mt;return g.setAttribute("position",new bt(d,3)),g.setAttribute("normal",new bt(u,3)),g.setIndex(new _f(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new P;e.traverse(n=>{const s=n,a=s.userData.cropBasePositions,o=s.userData.cropVerticesPerClump;if(!s.isMesh||!a||!o)return;const l=s.geometry.getAttribute("position"),c=new Ye().copy(s.matrixWorld).invert();for(let h=0;h<l.count;h+=o){i.set(a[h*3],0,a[h*3+2]).applyMatrix4(s.matrixWorld),i.y=t(i.x,i.z),i.applyMatrix4(c);for(let d=h;d<h+o;d++)l.setY(d,a[d*3+1]+i.y)}l.needsUpdate=!0,s.geometry.computeBoundingBox(),s.geometry.computeBoundingSphere()})}static paint(e,t){e.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const a=n.material;a?.color&&a.color.set(t)})}static build(e,t){const i=e.kind==="building"?bm(e.floors??Ma,e.windows,e.witnessSide,e.occupiedFloor):e.kind==="tree"?wm():e.kind==="shrub"?Mm():e.kind==="crop"?Sm():e.kind==="mound"?Em():e.kind==="streetlight"?_m(t):e.kind==="vehicle"?Tm(t,e.windows,e.witnessSide):e.kind==="aircraft"?Pm():e.kind==="entity"?Cm():nf();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new zt;return i.name=si.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*jh),this.addLights(s,e.lights),e.kind==="aircraft"&&this.exemptFromFog(s),s}static scaleFor(e){const t=e.sizeM;if(!t)return new P(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new P(t.widthM===void 0?1:td(t.widthM,i.widthM),t.heightM===void 0?1:td(t.heightM,i.heightM),t.lengthM===void 0?1:td(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??Ma)+1):0,n=`${e}:${i}`,s=Am.get(n);if(s)return s;const a=e==="building"?bm(i-1,void 0,void 0,void 0):e==="tree"?wm():e==="shrub"?Mm():e==="crop"?Sm():e==="mound"?Em():e==="streetlight"?_m(!1):e==="vehicle"?Tm(!1,void 0,void 0):e==="aircraft"?Pm():e==="entity"?Cm():nf(),o=new fn().setFromObject(a),l={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),Am.set(n,l),l}static usesModel(e){return e.model!==void 0&&!(e.witnessSide!==void 0&&pa(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new zt;a.name=si.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*jh,i.updateMatrixWorld(!0);const o=new fn().setFromObject(i),l={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},c=Im(t.sizeM,l)??Im(n.depictedSizeM,l)??1;i.scale.multiplyScalar(c);const h=o.getCenter(new P).multiplyScalar(c);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=t.kind==="aircraft"?h.y:o.min.y*c,i.traverse(d=>{d instanceof ke&&(d.castShadow=!0,d.receiveShadow=!0)}),a.add(i),s.parent?(s.parent.add(a),s.removeFromParent()):e.add(a),this.dispose(s)}static sizeOf(e){const t=this.naturalSize(e.kind,e.floors);return{widthM:e.sizeM?.widthM??t.widthM,lengthM:e.sizeM?.lengthM??t.lengthM,heightM:e.sizeM?.heightM??t.heightM}}static exemptFromFog(e){e.traverse(t=>{if(!(t instanceof ke))return;const i=t.material;i.fog=!1,i.needsUpdate=!0})}static addLights(e,t){for(const i of t??[]){const n=e5(i.color),s=$t(e,new ii(vm,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}}static setLights(e,t,i,n,s=0){if(!t||t.length===0)return;const a=new Map(t.map(l=>[l.id,l])),o=Math.max(1,n*j_/vm);for(const l of e.children){if(!(l instanceof ke))continue;const c=l.userData.lightId;if(!c)continue;const h=a.get(c);if(!h)continue;const d=s>0?Fg(h,i,i+s):m2(h,i)?1:0;l.visible=d>0;const u=l.material,f=l.userData.lightColor;if(f){const p=s>0?d*Q_*(h.intensity??1):d;u.color.setRGB(f[0]*p,f[1]*p,f[2]*p)}l.scale.setScalar(o)}}static setLit(e,t,i){const n=t==="streetlight"?i?ov:av:i?cv:lv;e.traverse(s=>{const a=s.userData;!(s instanceof ke)||!a.emissive||a.lightId||s.material.color.setRGB(...n)})}static dispose(e){e.traverse(t=>{if(!(t instanceof ke))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const nd="https://ufoathome.org/models/index.json";class f5{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??p5()}async entries(e){const t=await this.load();return e?t.filter(i=>i.kind===e):t}async entry(e){return(await this.load()).find(t=>t.id===e)}load(){return this.loading??=this.fetchFirstAvailable(),this.loading}async fetchFirstAvailable(){for(const e of this.indexUrls){const t=await this.fetchIndex(e);if(t)return t}return[]}async fetchIndex(e){try{const t=await this.fetchImpl(e);if(!t.ok)return;const i=await t.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,e).href})):void 0}catch{return}}}function p5(){const r=`?v=${encodeURIComponent("0.64.1")}`,e=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(e&&e!==nd?[e,nd]:[nd]).map(t=>t+r)}const cc=[{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 f5}];async function Lm(r){const{GLTFLoader:e}=await dn(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-BeVCsKtR.js");return{GLTFLoader:i}},[],import.meta.url),t=new e;return new Promise((i,n)=>{t.load(r,s=>i(s.scene),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const gv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class ln{static RENDER_ORDER=3;static LIGHT_AT=.35;static GLOW_MIN_ANGLE_RAD=.002;static GLOW_FILL=(1-Math.exp(-4))/4;static GLOW_MAX_SHARE=.3;mesh;light=new _1(16777215,0,0,2);glow;constructor(){const e=[];for(let s=0;s<=32;s++){const a=s/32,o=.5*(.7+.3*Math.sin(Math.min(1,a/.33)*Math.PI/2))*Math.pow(1-a,.55);e.push(new we(Math.max(o,1e-4),-a))}const i=new Xc(e,48),n=new wt({uniforms:{uTime:{value:0},uColor:{value:new se(1,1,1)},uTipColor:{value:new se(1,1,1)}},vertexShader:ln.VERTEX,fragmentShader:ln.FRAGMENT,transparent:!0,depthWrite:!1,blending:Fi,side:cn,toneMapped:!1});this.mesh=new ke(i,n),this.mesh.name="flame",this.mesh.frustumCulled=!1,this.mesh.renderOrder=ln.RENDER_ORDER,this.mesh.visible=!1,this.glow=new ke(new pn(2,2),new wt({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:ln.GLOW_VERTEX,fragmentShader:ln.GLOW_FRAGMENT,transparent:!0,depthWrite:!1,blending:Fi,toneMapped:!1})),this.glow.name="flame-glow",this.glow.frustumCulled=!1,this.glow.renderOrder=ln.RENDER_ORDER,this.glow.visible=!1}static glowFor(e,t){const i=Math.max(e.widthM*.6,t*ln.GLOW_MIN_ANGLE_RAD),n=.7*e.widthM*e.lengthM,s=ln.GLOW_FILL*Math.PI*i*i;return{radiusM:i,luminanceCdM2:e.luminanceCdM2*Math.min(ln.GLOW_MAX_SHARE,n/s)}}shine(e,t){this.glow.visible=!0,this.glow.position.set(0,-.5,0).applyMatrix4(this.mesh.matrixWorld),this.glow.material.uniforms.uRadius.value=e,this.glow.material.uniforms.uColor.value.setRGB(t[0],t[1],t[2])}putOut(){this.mesh.visible=!1,this.glow.visible=!1,this.light.intensity=0}place(e,t,i,n){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.quaternion.set(t.x,t.y,t.z,t.w),this.mesh.scale.set(n,i,n),this.mesh.updateMatrixWorld(),this.light.position.set(0,-.35,0).applyMatrix4(this.mesh.matrixWorld)}set(e,t,i){const n=this.mesh.material.uniforms;n.uColor.value.setRGB(e[0],e[1],e[2]),n.uTipColor.value.setRGB(t[0],t[1],t[2]),n.uTime.value=i}illuminate(e,t){this.light.intensity=e,this.light.color.setRGB(t[0],t[1],t[2])}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose(),this.glow.geometry.dispose(),this.glow.material.dispose()}static GLOW_VERTEX=`
|
|
7659
7659
|
uniform float uRadius;
|
|
7660
7660
|
varying vec2 vOffset;
|
|
7661
7661
|
void main() {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rr0/ufoathome",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.64.
|
|
4
|
+
"version": "0.64.1",
|
|
5
5
|
"description": "UFO@home — record and replay a UFO sighting's shape, movement and appearance",
|
|
6
6
|
"author": "Jérôme Beau <rr0@rr0.org> (https://rr0.org)",
|
|
7
7
|
"license": "MIT",
|