@rr0/ufoathome 0.80.0 → 0.80.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.
@@ -625,11 +625,13 @@ class $e{static svg(e){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5
625
625
  <div class="stage" id="stage">
626
626
  <div class="frame" id="frame">
627
627
  <canvas id="scene-canvas"></canvas>
628
- <!-- The spinner, and under it what a reader waiting on a picture may take this for: a video. It is
629
- not one — see SceneNames.notAVideo. Both live and die with the hold on the first frame. -->
628
+ <!-- The spinner in the middle, with above it what a reader waiting on a picture may take this for — a
629
+ video, which it is not — and below it what it is: a simulation (see SceneNames.notAVideo and
630
+ isASimulation). All three live and die with the hold on the first frame. -->
630
631
  <div id="scene-loader" class="scene-loader" role="progressbar" hidden>
632
+ <p id="scene-loader-not-video" class="scene-loader-note scene-loader-not-video">This is not a video</p>
631
633
  <div class="scene-loader-spinner"></div>
632
- <p id="scene-loader-note" class="scene-loader-note">This is not a video: it is a simulation, computed in real time in your browser.</p>
634
+ <p id="scene-loader-note" class="scene-loader-note scene-loader-is-simulation">It is a real-time simulation.</p>
633
635
  </div>
634
636
  </div>
635
637
  <div id="ufo-slot"></div>
@@ -771,10 +773,10 @@ class $e{static svg(e){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5
771
773
  .scene-loader {
772
774
  position: absolute;
773
775
  inset: 0;
774
- display: flex;
775
- flex-direction: column;
776
- align-items: center;
777
- justify-content: center;
776
+ /* The spinner stays in the middle whatever the two sentences weigh: each takes one of two equal rows. */
777
+ display: grid;
778
+ grid-template-rows: 1fr auto 1fr;
779
+ justify-items: center;
778
780
  gap: 1em;
779
781
  animation: scene-loader-appear 0.2s ease-out 0.25s both;
780
782
  pointer-events: none;
@@ -791,8 +793,9 @@ class $e{static svg(e){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5
791
793
  border-top-color: rgba(255, 255, 255, 0.9);
792
794
  animation: scene-loader-spin 0.9s linear infinite;
793
795
  }
794
- /* What the waiting picture is NOT: a video. Said only while it waits, and only where there is room
795
- for a sentence — a catalogue card's picture is too small for one. */
796
+ /* What the waiting picture is NOT (a video) above the spinner, and what it IS (a simulation) below it.
797
+ Said only while it waits, and only where there is room for a sentence — a catalogue card's picture
798
+ is too small for one. */
796
799
  .scene-loader-note {
797
800
  max-width: 24em;
798
801
  margin: 0;
@@ -802,6 +805,15 @@ class $e{static svg(e){return`<svg viewBox="0 0 24 24" width="1.5em" height="1.5
802
805
  text-align: center;
803
806
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9);
804
807
  }
808
+ .scene-loader-not-video {
809
+ align-self: end;
810
+ font-weight: bold;
811
+ font-variant: small-caps;
812
+ letter-spacing: 0.04em;
813
+ }
814
+ .scene-loader-is-simulation {
815
+ align-self: start;
816
+ }
805
817
  @container (max-width: 360px) {
806
818
  .scene-loader-note {
807
819
  display: none;
@@ -1927,7 +1939,7 @@ canvas[data-cursor="rotate"] {
1927
1939
  }
1928
1940
  `;class Ar{constructor(e){this.points=e}static STATIONARY_M=5;static of(e){const t=[];for(const i of e.observerTrack.allKeyframes){const{lat:n,lng:s,headingDeg:a}=i.pose;n===void 0||s===void 0||t.push({t:i.t,lat:n,lng:s,headingDeg:a})}if(t.length===0){const i=e.event.place?.[0];if(!i)return;t.push({t:0,lat:i.lat,lng:i.lng})}return new Ar(t)}static TRAVEL_M=50;get travels(){return this.spanM>Ar.TRAVEL_M}get moved(){return this.spanM>Ar.STATIONARY_M}get spanM(){const e=this.box,t=(e.south+e.north)/2,i=(e.west+e.east)/2;return Math.max(Math.abs(ri(t,e.east,t,e.west).x),Math.abs(ri(e.north,i,e.south,i).z))}get center(){const e=this.box;return{lat:(e.south+e.north)/2,lng:(e.west+e.east)/2}}boundsAround(e,t){const{lat:i,lng:n}=this.center,s=Math.max(this.spanM*(1+t),e)/2;return{north:_s(0,-s,i,n).lat,south:_s(0,s,i,n).lat,east:_s(s,0,i,n).lng,west:_s(-s,0,i,n).lng}}get box(){const e=this.points.map(i=>i.lat),t=this.points.map(i=>i.lng);return{south:Math.min(...e),north:Math.max(...e),west:Math.min(...t),east:Math.max(...t)}}}class vn{constructor(e,t){this.rotationPassed=e,this.scale=t}static SWAY_M=.012;static BREATH_M=.003;static DRIFT_YAW_DEG=.5;static DRIFT_PITCH_DEG=.4;static DRIFT_ROLL_DEG=.3;static GAZE_DRIFT_SHARE=.35;static HAND_HELD_S=.5;static HZ=[.11,.23,.17,.29,.37,.07];static of(e){const t=e.event.tags?.includes("paralysis")||(e.exposure??0)>vn.HAND_HELD_S,i=e.sway??(t?0:1);if(i>0)return new vn(Math.max(1-(e.instrument.stabilization??0),vn.GAZE_DRIFT_SHARE),i)}offsetAt(e){const t=e/1e3,i=this.scale,n=(d,u)=>Math.sin(2*Math.PI*d*t+u),[s,a,o,l,c,h]=vn.HZ;return{eastM:i*vn.SWAY_M*(.7*n(s,.3)+.3*n(l,1.9)),northM:i*vn.SWAY_M*(.6*n(o,2.2)+.4*n(c,.8)),upM:i*vn.BREATH_M*n(a,0),yawDeg:i*this.rotationPassed*vn.DRIFT_YAW_DEG*(.6*n(h,1.1)+.4*n(l,2.7)),pitchDeg:i*this.rotationPassed*vn.DRIFT_PITCH_DEG*(.5*n(a,1.6)+.5*n(o,.4)),rollDeg:i*this.rotationPassed*vn.DRIFT_ROLL_DEG*n(s,2.9)}}}class bt{constructor(e,t){this.stretches=e,this.rotationPassed=t}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STOP_LURCH_M=.035;static STOP_PITCH_DEG=3;static START_LURCH_M=.015;static START_PITCH_DEG=1.2;static JOLT_HZ=1.4;static JOLT_DECAY_S=.35;static JOLT_LASTS_MS=1500;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(e){const t=Ar.of(e);if(!t||t.points.length<2)return;const i=[];let n=0;for(let s=1;s<t.points.length;s++){const a=t.points[s-1],o=t.points[s],l=(o.t-a.t)/1e3;if(l<=0)continue;const c=ri(o.lat,o.lng,a.lat,a.lng),h=c.x,d=-c.z,u=Math.hypot(h,d),f=u/l,p=bt.stepHzFor(f);i.push({startMs:a.t,endMs:o.t,speedMPerS:f,eastUnit:u>0?h/u:0,northUnit:u>0?d/u:0,stepHz:p,stepsBefore:n,rampsIn:!0,rampsOut:!0}),n+=p*l}for(let s=0;s<i.length;s++){const a=i[s-1],o=i[s+1];i[s].rampsIn=a===void 0||a.stepHz===0,i[s].rampsOut=o===void 0||o.stepHz===0}if(i.some(s=>s.stepHz>0))return new bt(i,1-(e.instrument.stabilization??0))}static bodyAt(e,t,i=!1){const n=bt.of(e)?.offsetAt(t)??bt.STILL;return i?n:bt.add(n,vn.of(e)?.offsetAt(t))}static stepHzFor(e){return e<bt.SLOWEST_WALK_M_PER_S||e>bt.FASTEST_WALK_M_PER_S?0:bt.REFERENCE_STEP_HZ*Math.pow(e/bt.REFERENCE_SPEED_M_PER_S,bt.CADENCE_EXPONENT)}offsetAt(e){return bt.add(this.cycleAt(e),this.joltAt(e))}joltAt(e){for(const t of this.stretches){if(t.stepHz===0)continue;const i=t.speedMPerS/bt.REFERENCE_SPEED_M_PER_S,n=(o,l,c,h)=>{if(o<0||o>bt.JOLT_LASTS_MS)return;const d=o/1e3,u=Math.exp(-d/bt.JOLT_DECAY_S)*Math.sin(2*Math.PI*bt.JOLT_HZ*d),f=h*l*i*u;return{eastM:f*t.eastUnit,northM:f*t.northUnit,upM:-Math.abs(f)*.3,rollDeg:0,pitchDeg:-h*c*i*u*this.rotationPassed,yawDeg:0}},s=t.rampsOut?n(e-t.endMs,bt.STOP_LURCH_M,bt.STOP_PITCH_DEG,1):void 0;if(s)return s;const a=t.rampsIn?n(e-t.startMs,bt.START_LURCH_M,bt.START_PITCH_DEG,-1):void 0;if(a)return a}}static add(e,t){return t?{eastM:e.eastM+t.eastM,northM:e.northM+t.northM,upM:e.upM+t.upM,rollDeg:e.rollDeg+t.rollDeg,pitchDeg:e.pitchDeg+t.pitchDeg,yawDeg:e.yawDeg+t.yawDeg}:e}cycleAt(e){const t=this.stretches.find(l=>e>=l.startMs&&e<=l.endMs);if(!t||t.stepHz===0)return bt.STILL;const i=t.stepsBefore+t.stepHz*(e-t.startMs)/1e3,n=2*Math.PI*i,s=this.amplitudeAt(t,e),a=bt.SWAY_M*s*Math.cos(n/2),o=s*this.rotationPassed*t.speedMPerS/bt.REFERENCE_SPEED_M_PER_S;return{eastM:a*t.northUnit,northM:-a*t.eastUnit,upM:bt.RISE_M_PER_M_PER_S*t.speedMPerS*s*Math.cos(n),rollDeg:bt.HEAD_ROLL_DEG*o*Math.cos(n/2),pitchDeg:-1.25*o*Math.cos(n),yawDeg:bt.HEAD_YAW_DEG*o*Math.cos(n/2)}}amplitudeAt(e,t){const i=1e3/e.stepHz,n=Math.min(i,(e.endMs-e.startMs)/2);if(n<=0)return 1;const s=t-e.startMs,a=e.endMs-t,o=Math.min(e.rampsIn?s/n:1,e.rampsOut?a/n:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class r2{constructor(e,t){this.timeline=e,this.onFrame=t}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const e=()=>{if(this.state!=="playing")return;const t=performance.now();if(this.currentT+=(t-this.lastWallTime)*this.playbackRate,this.lastWallTime=t,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e)};this.rafId=requestAnimationFrame(e)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(e){this.currentT=Math.max(0,Math.min(e,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(e){const t=new Map;for(const i of this.timeline.sourceIds){const n=this.timeline.getInterpolatedShapeAt(e,i);n&&t.set(i,n)}this.onFrame(e,t)}}const Cg=["nw","n","ne","e","se","s","sw","w"],o2=24,ll=8,l2=3,c2=8;function cl(r,e,t){const i=r.x-e.x,n=r.y-e.y,s=Math.cos(t),a=Math.sin(t);return{x:e.x+i*s-n*a,y:e.y+i*a+n*s}}function Zr(r){return{x:r.x+r.width/2,y:r.y+r.height/2}}const h2={nw:{left:!0,top:!0},n:{top:!0},ne:{right:!0,top:!0},e:{right:!0},se:{right:!0,bottom:!0},s:{bottom:!0},sw:{left:!0,bottom:!0},w:{left:!0}};class hn{static handlePointsFor(e){const{x:t,y:i,width:n,height:s}=e.bounds,a={nw:{x:t,y:i},n:{x:t+n/2,y:i},ne:{x:t+n,y:i},e:{x:t+n,y:i+s/2},se:{x:t+n,y:i+s},s:{x:t+n/2,y:i+s},sw:{x:t,y:i+s},w:{x:t,y:i+s/2},rotate:{x:t+n/2,y:i-o2}},o=Zr(e.bounds),l={};for(const c of Object.keys(a))l[c]=cl(a[c],o,e.angle);return l}static hitTestHandle(e,t,i=8,n=[...Cg,"rotate"]){const s=hn.handlePointsFor(e);for(const a of n)if(Math.hypot(t.x-s[a].x,t.y-s[a].y)<=i)return a}static HANDLE_DIRECTION_DEG={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315};static resizeAxisFor(e,t){const n=((hn.HANDLE_DIRECTION_DEG[e]+t*180/Math.PI)%180+180)%180/45,s=["ew","nwse","ns","nesw"];return s[Math.round(n)%s.length]}static resizeBounds(e,t,i,n){const s=Zr(e),a=cl(n,s,-t),{x:o,y:l,width:c,height:h}=e,d=h2[i];let u=o,f=l,p=o+c,v=l+h;return d.left&&(u=Math.min(a.x,p-ll)),d.right&&(p=Math.max(a.x,u+ll)),d.top&&(f=Math.min(a.y,v-ll)),d.bottom&&(v=Math.max(a.y,f+ll)),{x:u,y:f,width:p-u,height:v-f}}static resizeShape(e,t,i){if(t==="rotate")throw new Error("resizeShape does not accept the rotate handle");const{width:n,height:s}=e.bounds,a=hn.resizeBounds(e.bounds,e.angle,t,i);if(e.kind==="oval")return{...e,bounds:a};const o=n===0?1:a.width/n,l=s===0?1:a.height/s;return{...e,bounds:a,points:e.points.map(c=>({x:c.x*o,y:c.y*l}))}}static rotateShape(e,t){const i=Zr(e.bounds),n=Math.atan2(t.y-i.y,t.x-i.x)+Math.PI/2;return{...e,angle:n}}static groupBoundsFor(e){const t=Math.min(...e.map(a=>a.x)),i=Math.min(...e.map(a=>a.y)),n=Math.max(...e.map(a=>a.x+a.width)),s=Math.max(...e.map(a=>a.y+a.height));return{x:t,y:i,width:n-t,height:s-i}}static vertexPointsFor(e){const t=Zr(e.bounds);return e.points.map(i=>cl({x:e.bounds.x+i.x,y:e.bounds.y+i.y},t,e.angle))}static hitTestVertex(e,t,i=c2){const n=hn.vertexPointsFor(e);let s,a=i;return n.forEach((o,l)=>{const c=Math.hypot(t.x-o.x,t.y-o.y);c<=a&&(a=c,s=l)}),s}static toLocalPoint(e,t){const i=Zr(e.bounds),n=cl(t,i,-e.angle);return{x:n.x-e.bounds.x,y:n.y-e.bounds.y}}static moveVertex(e,t,i){const n=e.points.map((d,u)=>u===t?hn.toLocalPoint(e,i):d),s=Math.min(...n.map(d=>d.x)),a=Math.min(...n.map(d=>d.y)),o=Math.max(...n.map(d=>d.x)),l=Math.max(...n.map(d=>d.y)),c={x:e.bounds.x+s,y:e.bounds.y+a,width:o-s,height:l-a},h=n.map(d=>({x:d.x-s,y:d.y-a}));return{...e,bounds:c,points:h}}static insertVertexNear(e,t){const i=hn.toLocalPoint(e,t),{points:n}=e;let s=n.length-1,a=1/0;for(let l=0;l<n.length;l++){const c=n[l],h=n[(l+1)%n.length],d=hn.distanceToSegment(i,c,h);d<a&&(a=d,s=l)}const o=[...n.slice(0,s+1),i,...n.slice(s+1)];return{...e,points:o}}static distanceToSegment(e,t,i){const n=i.x-t.x,s=i.y-t.y,a=n*n+s*s,o=a===0?0:Math.max(0,Math.min(1,((e.x-t.x)*n+(e.y-t.y)*s)/a)),l=t.x+o*n,c=t.y+o*s;return Math.hypot(e.x-l,e.y-c)}static deleteVertex(e,t){return e.points.length<=l2?e:{...e,points:e.points.filter((i,n)=>n!==t)}}}const Ud=6,hl=Ud/2,Af=20,Tf=24,Rf=9,Cf=6,Df=7,If=6,Xn=4;class Vo{constructor(e){this.ctx=e}starPoints=0;roll=0;clear(e,t){this.ctx.clearRect(0,0,e,t)}static paintExtent(e){const{x:t,y:i,width:n,height:s}=e.bounds,a=t+n/2,o=i+s/2,l=e.angle%(2*Math.PI)!==0,c=Math.hypot(n,s)/2,h=l?c:n/2,d=l?c:s/2,u=Math.max(n,s)/2,f=e.brightness??0,p=f>0?Math.max(u*(1+Rf*f),If*f)-u:0,v=f>0?u*(1+Df*f)-u:0,m=3*Tf*(e.blur??0)+1.5*Af*e.haloScale,g=Math.max(p,v,0)+m+2;return{x:a-h-g,y:o-d-g,width:2*(h+g),height:2*(d+g)}}paintInto(e,t,i,n=!1){this.ctx.save(),this.ctx.scale(i,i),this.ctx.translate(-t.x,-t.y);const s=e.selected?{...e,selected:!1}:e;n?this.paintGhost(s,1.5):this.paintShape(s),this.ctx.restore()}paintShape(e){this.ctx.save(),this.ctx.globalAlpha=1-e.transparency;const t=e.blur??0;t>0&&(this.ctx.filter=`blur(${(Tf*t).toFixed(2)}px)`);const i=e.brightness??0;i>0&&this.paintDazzle(e,i),e.haloScale>0&&this.paintHalo(e),this.paintBase(e),this.ctx.restore(),e.selected&&this.paintSelectionHandles(e)}setStarPoints(e){this.starPoints=Math.max(0,Math.floor(e))}setRoll(e){this.roll=e}paintDazzle(e,t){const{x:i,y:n,width:s,height:a}=e.bounds,o=i+s/2,l=n+a/2,c=Math.max(s,a)/2,h=Math.max(c*(1+Rf*t),If*t);if(h<=0)return;this.ctx.save(),this.ctx.globalCompositeOperation="lighter";const d=this.ctx.createRadialGradient(o,l,0,o,l,h);for(let u=0;u<=Cf;u++){const f=u/Cf,p=1/(1+24*f*f);this.ctx.globalAlpha=1,d.addColorStop(f,this.withAlpha(e.color,p*t*.55))}if(this.ctx.fillStyle=d,this.ctx.beginPath(),this.ctx.arc(o,l,h,0,2*Math.PI),this.ctx.fill(),this.starPoints>0){const u=c*(1+Df*t);this.ctx.lineWidth=Math.max(1,c*.12),this.ctx.lineCap="round";for(let f=0;f<this.starPoints;f++){const p=f/this.starPoints*Math.PI*2+this.roll,v=o+Math.cos(p)*u,m=l+Math.sin(p)*u,g=this.ctx.createLinearGradient(o,l,v,m);g.addColorStop(0,this.withAlpha(e.color,t*.55)),g.addColorStop(.35,this.withAlpha(e.color,t*.22)),g.addColorStop(1,this.withAlpha(e.color,0)),this.ctx.strokeStyle=g,this.ctx.beginPath(),this.ctx.moveTo(o,l),this.ctx.lineTo(v,m),this.ctx.stroke()}}this.ctx.restore()}dazzledFill(e,t){if(t<=0)return e.color;const i=/^#([0-9a-f]{6})$/i.exec(e.color.trim());if(!i)return e.color;const n=Number.parseInt(i[1],16),s=a=>Math.round(a+(255-a)*t);return`rgb(${s(n>>16&255)}, ${s(n>>8&255)}, ${s(n&255)})`}withAlpha(e,t){const i=Math.max(0,Math.min(1,t)),n=/^#([0-9a-f]{6})$/i.exec(e.trim());if(!n)return e;const s=Number.parseInt(n[1],16);return`rgba(${s>>16&255}, ${s>>8&255}, ${s&255}, ${i.toFixed(3)})`}paintBase(e){this.ctx.fillStyle=this.dazzledFill(e,e.brightness??0),this.tracePath(e),this.ctx.fill()}paintGhost(e,t){this.ctx.save(),this.tracePath(e),this.ctx.setLineDash([t*3,t*2]),this.ctx.lineWidth=t,this.ctx.strokeStyle=e.color,this.ctx.stroke(),this.ctx.restore()}tracePath(e){if(this.ctx.beginPath(),e.kind==="oval"){const{x:t,y:i,width:n,height:s}=e.bounds,a=n/2,o=s/2;this.ctx.ellipse(t+a,i+o,a,o,e.angle,0,2*Math.PI)}else{const{x:t,y:i,width:n,height:s}=e.bounds;this.ctx.save(),this.ctx.translate(t+n/2,i+s/2),this.ctx.rotate(e.angle),this.ctx.translate(-n/2,-s/2),e.points.forEach((a,o)=>{o===0?this.ctx.moveTo(a.x,a.y):this.ctx.lineTo(a.x,a.y)}),this.ctx.closePath(),this.ctx.restore()}}paintHalo(e){this.ctx.save(),this.ctx.shadowColor=e.color,this.ctx.shadowBlur=Af*e.haloScale,this.paintBase(e),this.ctx.restore()}paintSelectionHandles(e){this.paintHandleFrame(hn.handlePointsFor(e),{includeRotate:!0}),e.kind==="polygon"&&this.paintVertexHandles(e)}paintVertexHandles(e){this.ctx.fillStyle="#39f";for(const t of hn.vertexPointsFor(e))this.ctx.beginPath(),this.ctx.ellipse(t.x,t.y,Xn,Xn,0,0,2*Math.PI),this.ctx.fill()}paintMemberOutline(e){this.paintOutline(hn.handlePointsFor(e))}paintSelectionOnly(e){this.paintSelectionHandles(e)}paintPictureFrame(e,t,i){const n=this.ctx;if(n.save(),e&&e.length===4){n.strokeStyle="#39f",n.lineWidth=1.5,n.setLineDash([6,4]),n.beginPath(),n.moveTo(e[0].x,e[0].y);for(const s of e.slice(1))n.lineTo(s.x,s.y);n.closePath(),n.stroke(),n.setLineDash([])}for(const s of t){const a=Vo.landmarkColour(s.residualDeg),o=s.selected?3:2;s.selected&&(n.strokeStyle="#fff",n.lineWidth=o+3,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Xn+2,Xn+2,0,0,2*Math.PI),n.stroke()),s.scene&&(n.strokeStyle=a,n.lineWidth=1,n.beginPath(),n.moveTo(s.picture.x,s.picture.y),n.lineTo(s.scene.x,s.scene.y),n.stroke(),n.fillStyle=a,n.beginPath(),n.ellipse(s.scene.x,s.scene.y,Xn,Xn,0,0,2*Math.PI),n.fill()),n.strokeStyle=a,n.lineWidth=o,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Xn+2,Xn+2,0,0,2*Math.PI),n.stroke(),this.paintLabel(s.label,s.picture.x+Xn+5,s.picture.y-Xn-2,a)}i&&this.paintLabel(i,8,8,"#fff",13),n.restore()}static landmarkColour(e){return e===void 0?"#ffb000":e<=1?"#3c3":e<=3?"#ffb000":"#f33"}paintLabel(e,t,i,n,s=11){const a=this.ctx;a.save(),a.font=`${s}px system-ui, sans-serif`,a.textBaseline="top";const o=a.measureText(e).width;a.fillStyle="rgba(0, 0, 0, 0.6)",a.fillRect(t-3,i-2,o+6,s+4),a.fillStyle=n,a.fillText(e,t,i),a.restore()}paintGroupHandles(e){this.paintHandleFrame(hn.handlePointsFor({bounds:e,angle:0}),{includeRotate:!0})}paintOutline(e){this.ctx.strokeStyle="lightgray",this.ctx.beginPath(),this.ctx.moveTo(e.nw.x,e.nw.y),this.ctx.lineTo(e.ne.x,e.ne.y),this.ctx.lineTo(e.se.x,e.se.y),this.ctx.lineTo(e.sw.x,e.sw.y),this.ctx.closePath(),this.ctx.stroke()}paintHandleFrame(e,{includeRotate:t}){this.paintOutline(e),this.ctx.fillStyle="lightgray";for(const i of Cg){const n=e[i];this.ctx.fillRect(n.x-hl,n.y-hl,Ud,Ud)}t&&(this.ctx.beginPath(),this.ctx.moveTo(e.n.x,e.n.y),this.ctx.lineTo(e.rotate.x,e.rotate.y),this.ctx.stroke(),this.ctx.beginPath(),this.ctx.ellipse(e.rotate.x,e.rotate.y,hl+1,hl+1,0,0,2*Math.PI),this.ctx.fill())}}const Pf=.05,Lf=.08,Of=2,Nf=3,d2=14,u2=.02;class f2{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;level=1;master;output(e){return this.master||(this.master=e.createGain(),this.master.gain.value=this.level,this.master.connect(e.destination)),this.master}setLevel(e){this.level=e,this.master&&(this.master.gain.value=e)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(e){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",e);return}}Oa.unlock(this.context)}setSound(e){if(this.requested=e,!this.context)return;const t=this.keyFor(e);if(!t){this.silence();return}if(this.voice?.key!==t){this.stopVoice();const i=++this.voiceToken;t.startsWith("src:")?this.buildRecordedVoice(e.src,t,i):this.voice=this.buildSynthesizedVoice(e,t)}this.applyTo(this.voice,e)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(e){if(!(e.volume<=0))return e.src?`src:${e.src}`:e.kind==="none"?void 0:e.kind}applyTo(e,t){const i=this.context;if(!e||!i)return;const n=i.currentTime;e.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,t.volume))*e.gainScale,n,Pf);for(const{param:s,ratio:a}of e.pitch)s.setTargetAtTime(Math.min(t.pitchHz*a,i.sampleRate/2-1),n,Pf)}buildSynthesizedVoice(e,t){const i=this.context;if(i)switch(e.kind){case"hum":return this.buildHum(i,t);case"whistle":return this.buildWhistle(i,t);case"rumble":return this.buildRumble(i,t);case"crackle":return this.buildCrackle(i,t);default:return}}buildHum(e,t){const i=e.createOscillator();i.type="sawtooth";const n=e.createOscillator();n.type="sawtooth";const s=e.createBiquadFilter();s.type="lowpass",s.Q.value=1;const a=e.createGain();return a.gain.value=0,i.connect(s),n.connect(s),s.connect(a).connect(this.output(e)),i.start(),n.start(),{key:t,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.16,pitch:[{param:i.frequency,ratio:1},{param:n.frequency,ratio:1.006},{param:s.frequency,ratio:6}]}}buildWhistle(e,t){const i=e.createOscillator();i.type="sine";const n=e.createOscillator();n.type="sine",n.frequency.value=5;const s=e.createGain(),a=e.createGain();return a.gain.value=0,n.connect(s).connect(i.frequency),i.connect(a).connect(this.output(e)),i.start(),n.start(),{key:t,nodes:[s,a],sources:[i,n],volumeParam:a.gain,gainScale:.22,pitch:[{param:i.frequency,ratio:1},{param:s.gain,ratio:.012}]}}buildRumble(e,t){const i=e.createBufferSource();i.buffer=this.brownNoise(e),i.loop=!0;const n=e.createBiquadFilter();n.type="lowpass",n.Q.value=.8;const s=e.createGain();return s.gain.value=0,i.connect(n).connect(s).connect(this.output(e)),i.start(),{key:t,nodes:[n,s],sources:[i],volumeParam:s.gain,gainScale:1.4,pitch:[{param:n.frequency,ratio:1}]}}buildCrackle(e,t){const i=e.createBufferSource();i.buffer=this.whiteNoise(e),i.loop=!0;const n=e.createBiquadFilter();n.type="bandpass",n.Q.value=1.2;const s=e.createGain();s.gain.value=0;const a=e.createBufferSource();a.buffer=this.crackleEnvelope(e),a.loop=!0;const o=e.createGain();return o.gain.value=0,a.connect(o).connect(s.gain),i.connect(n).connect(s).connect(this.output(e)),i.start(),a.start(),{key:t,nodes:[n,s,o],sources:[i,a],volumeParam:o.gain,gainScale:.9,pitch:[{param:n.frequency,ratio:4}]}}async buildRecordedVoice(e,t,i){const n=this.context;if(!n)return;let s;try{s=await this.getBuffer(e)}catch(l){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",l);return}if(i!==this.voiceToken||!this.context)return;const a=n.createBufferSource();a.buffer=s,a.loop=!0;const o=n.createGain();o.gain.value=0,a.connect(o).connect(this.output(n)),a.start(),this.voice={key:t,nodes:[o],sources:[a],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(e){const t=this.context;if(!t)throw new Error("SightingAudio: 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}whiteNoise(e){if(!this.noiseBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*Of),e.sampleRate),i=t.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;this.noiseBuffer=t}return this.noiseBuffer}brownNoise(e){const t=e.createBuffer(1,Math.floor(e.sampleRate*Of),e.sampleRate),i=t.getChannelData(0);let n=0,s=0;for(let a=0;a<i.length;a++)n=(n+.02*(Math.random()*2-1))/1.02,i[a]=n,s=Math.max(s,Math.abs(n));if(s>0)for(let a=0;a<i.length;a++)i[a]/=s;return t}crackleEnvelope(e){if(!this.crackleBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*Nf),e.sampleRate),i=t.getChannelData(0),n=Math.max(1,Math.floor(u2*e.sampleRate)),s=Math.round(Nf*d2);for(let a=0;a<s;a++){const o=Math.floor(Math.random()*i.length),l=.4+Math.random()*.6;for(let c=0;c<n&&o+c<i.length;c++)i[o+c]=Math.max(i[o+c],l*(1-c/n))}this.crackleBuffer=t}return this.crackleBuffer}stopVoice(){const e=this.voice,t=this.context;if(this.voice=void 0,!e||!t)return;const i=t.currentTime;e.volumeParam.cancelScheduledValues(i),e.volumeParam.setTargetAtTime(0,i,Lf/3);const n=i+Lf;for(const s of e.sources){s.onended=()=>{s.disconnect();for(const a of e.nodes)a.disconnect()};try{s.stop(n)}catch{s.disconnect();for(const a of e.nodes)a.disconnect()}}}}function Do(r){return[...r].sort((e,t)=>e.t-t.t)}function fh(r,e){let t;for(const i of Do(r)){if(i.t>e)break;t=i}return t}const ph=Math.PI/180,dl=180/Math.PI;class ws{constructor(e,t,i){this.kind=e,this.canvasHeightPx=t,this.fovDeg=i;const n=i*ph/2;this.focalPx=e==="equidistant"?t/2/n:t/2/Math.tan(n)}focalPx;static of(e,t,i){return new ws(e.projection,t,i)}degToPx(e){const t=e*ph;return this.kind==="equidistant"?this.focalPx*t:2*this.focalPx*Math.tan(t/2)}pxToDeg(e){return this.kind==="equidistant"?e/this.focalPx*dl:2*Math.atan(e/(2*this.focalPx))*dl}angleDegToRadiusPx(e){const t=e*ph;return this.kind==="equidistant"?this.focalPx*t:this.focalPx*Math.tan(t)}halfWidthAngleDeg(e){return this.radiusPxToAngleDeg(this.canvasHeightPx*e/2)}radiusPxToAngleDeg(e){return this.kind==="equidistant"?e/this.focalPx*dl:Math.atan(e/this.focalPx)*dl}ofBounds(e){return{widthDeg:this.pxToDeg(e.width),heightDeg:this.pxToDeg(e.height)}}toBoundsSize(e){return{width:this.degToPx(e.widthDeg),height:this.degToPx(e.heightDeg)}}widthPx(e){return this.degToPx(Tt.angularWidthDeg(e))}}class Qi{static fovOf(e,t){return ti(e,t)?.fovDeg??oi.fieldOfViewDeg(e.instrument)}static toAngular(e){this.eachKeyframe(e,(t,i)=>({...t,angular:i.ofBounds(t.bounds)}))}static toBounds(e){this.eachKeyframe(e,(t,i)=>{if(!t.angular)return t;const{width:n,height:s}=i.toBoundsSize(t.angular),a={x:t.bounds.x+(t.bounds.width-n)/2,y:t.bounds.y+(t.bounds.height-s)/2,width:n,height:s};if(t.kind!=="polygon")return{...t,bounds:a};const o=t.bounds.width===0?1:n/t.bounds.width,l=t.bounds.height===0?1:s/t.bounds.height;return{...t,bounds:a,points:t.points.map(c=>({x:c.x*o,y:c.y*l}))}})}static toAim(e){this.eachKeyframe(e,(t,i,n)=>{const s=t.aim&&this.positionOf(e,t.aim,t.bounds,i,n);if(s&&Math.abs(s.x-t.bounds.x)<Qi.UNMOVED_PX&&Math.abs(s.y-t.bounds.y)<Qi.UNMOVED_PX)return t;const a=this.aimFrom(e,i,n,t.bounds);return a?{...t,aim:a}:t})}static UNMOVED_PX=.01;static aimOf(e,t,i){const n=ws.of(e.instrument,Tt.CANVAS_HEIGHT_PX,this.fovOf(e,t));return this.aimFrom(e,n,ti(e,t),i)}static aimFrom(e,t,i,n){if(i?.headingDeg===void 0)return;const s=this.frameCentre(e),a=t.radiusPxToAngleDeg(n.x+n.width/2-s.x),o=t.radiusPxToAngleDeg(s.y-(n.y+n.height/2));return{azimuthDeg:((i.headingDeg+a)%360+360)%360,altitudeDeg:i.pitchDeg+o}}static toPosition(e){this.eachKeyframe(e,(t,i,n)=>{const s=t.aim&&this.positionOf(e,t.aim,t.bounds,i,n);return s?{...t,bounds:{...t.bounds,...s}}:t})}static positionOf(e,t,i,n,s){if(s?.headingDeg===void 0)return;const a=this.frameCentre(e),o=this.shortestArc(t.azimuthDeg-s.headingDeg),l=t.altitudeDeg-s.pitchDeg;return{x:a.x+this.offAxisPx(n,o)-i.width/2,y:a.y-this.offAxisPx(n,l)-i.height/2}}static frameCentre(e){return{x:oi.frameWidthPx(e.instrument,Tt.CANVAS_HEIGHT_PX)/2,y:Tt.CANVAS_HEIGHT_PX/2}}static shortestArc(e){return(e%360+540)%360-180}static offAxisPx(e,t){return Math.abs(t)>=Qi.OFF_CANVAS_DEG?Math.sign(t)*Qi.OFF_CANVAS_PX:e.angleDegToRadiusPx(t)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(e,t,i){const n=oi.frameWidthPx(t,Tt.CANVAS_HEIGHT_PX)/2,s=oi.frameWidthPx(e.instrument,Tt.CANVAS_HEIGHT_PX)/2,a=Tt.CANVAS_HEIGHT_PX/2;for(const o of[...e.timeline.allKeyframes]){const l=this.fovOf(e,o.t),c=i?.get(o.t)??l,h=ws.of(t,Tt.CANVAS_HEIGHT_PX,c),d=ws.of(e.instrument,Tt.CANVAS_HEIGHT_PX,l);e.timeline.addKeyframe(o.t,o.shapes.map(u=>{const{bounds:f}=u.shape,p=f.x+f.width/2-n,v=f.y+f.height/2-a,m=Math.hypot(p,v),g=m===0?1:d.angleDegToRadiusPx(h.radiusPxToAngleDeg(m))/m,S={...f,x:s+p*g-f.width/2,y:a+v*g-f.height/2};return{...u,shape:{...u.shape,bounds:S}}}))}this.toBounds(e)}static eachKeyframe(e,t){const{timeline:i}=e;for(const n of[...i.allKeyframes]){const s=ti(e,n.t),a=this.fovOf(e,n.t),o=ws.of(e.instrument,Tt.CANVAS_HEIGHT_PX,a);i.addKeyframe(n.t,n.shapes.map(l=>({...l,shape:t(l.shape,o,s)})))}}}function p2(r){return Vi.restore(m2(r),r.provenance)}function m2(r){return Qi.toAngular(r),Qi.toAim(r),{version:1,id:r.id,time:r.event.time,endTime:r.event.endTime,durationSeconds:r.event.durationSeconds,utcOffsetHours:r.event.utcOffsetHours,timeZone:r.event.timeZone,place:r.event.place,observer:r.observer,account:r.account,sources:r.sources?.length?r.sources:void 0,sway:r.sway,vehicle:r.vehicle,description:r.event.description,tags:r.event.tags,timeline:r.timeline.toJSON(),observerTrack:r.observerTrack.toJSON(),weatherTrack:r.weatherTrack.toJSON(),soundTrack:r.soundTrack.toJSON(),weather:r.weather,decor:r.decor,milestones:r.milestones.length>0?r.milestones:void 0,references:r.references.length>0?r.references:void 0,roads:r.roads.length>0?r.roads:void 0,weatherSource:r.weatherSource,instrument:r.instrumentId,exposureSeconds:r.exposureSeconds,iso:r.iso,lightPollution:r.lightPollution,interpretation:r.interpretation}}function g2(r){const{recording:e,provenance:t}=Vi.strip(r),i=v2(e);return i.provenance=t,i}function v2(r){const e=[],t=new Zc({eventType:"sighting",time:r.time,endTime:r.endTime,durationSeconds:r.durationSeconds,utcOffsetHours:r.utcOffsetHours,timeZone:r.timeZone,place:r.place,description:r.description,tags:r.tags},Kc.fromJSON(r.timeline,e),r.observerTrack?zo.fromJSON(r.observerTrack):new zo,r.weatherTrack?Bo.fromJSON(r.weatherTrack):new Bo,r.soundTrack?Ho.fromJSON(r.soundTrack):new Ho,r.observer&&{id:r.observer.id,title:r.observer.title,lastName:r.observer.lastName,firstNames:r.observer.firstNames},r.id,r.weather,r.decor??[],r.weatherSource,r.instrument,r.exposureSeconds??r.observerTrack?.keyframes.map(i=>i.pose.exposureSeconds).find(i=>i!==void 0),Do(r.milestones??[]),r.references??[],r.roads??[]);return t.account=r.account,t.sources=r.sources,t.sway=r.sway,t.iso=r.iso,t.lightPollution=r.lightPollution,t.vehicle=r.vehicle,t.interpretation=r.interpretation,t.loadIssues=e,Qi.toBounds(t),Qi.toPosition(t),t}class Ur{static EN={"unknown-key":"{path}: unknown key, ignored","wrong-type":"{path}: expected {expected}, found {found}","not-in-list":"{path}: {found} is not one of {expected}",defaulted:"{path}: missing, {expected} used",unplaced:"{path}: no aim (and no bounds), drawn at the middle of the view",unsized:"{path}: no angular size (and no bounds), drawn one pixel wide","pixels-over-angles":"{path}: bounds restated without aim or angular, so the shape follows the pixels"};static text(e,t=Ur.EN){return t[e.kind].replace("{path}",e.path).replace("{expected}",e.expected??"").replace("{found}",e.found??"")}static warn(e,t){if(e.length===0)return;const i=e.map(n=>` ${Ur.text(n)}`);console.warn(`UFO@home: ${e.length} problem(s) in ${t??"this recording"}:
1929
1941
  ${i.join(`
1930
- `)}`)}}class Tn{constructor(e){this.format=e}issues(e){const t=[];return this.object(e,this.format,"",t),t}object(e,t,i,n){if(!Tn.isObject(e)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:Tn.typeOf(e)});return}for(const[s,a]of Object.entries(e)){const o=i?`${i}.${s}`:s,l=t[s];l?this.field(a,l,o,n):n.push({kind:"unknown-key",path:o})}}field(e,t,i,n){if(Tn.isStated(e)){this.field(e.value,t,i,n);return}if(!(t.loose||e===void 0||e===null))switch(t.type){case"enum":(typeof e!="string"||!t.values?.includes(e))&&n.push({kind:"not-in-list",path:i,expected:(t.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(e)});return;case"object":t.fields?this.object(e,t.fields,i,n):Tn.isObject(e)||n.push({kind:"wrong-type",path:i,expected:"object",found:Tn.typeOf(e)});return;case"array":Array.isArray(e)?t.fields&&e.forEach((s,a)=>{const o=Tn.isStated(s)?s.value:s;this.object(o,t.fields,`${i}.${a}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:Tn.typeOf(e)});return;default:typeof e!==t.type&&n.push({kind:"wrong-type",path:i,expected:t.type,found:Tn.typeOf(e)})}}static isObject(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}static isStated(e){return Tn.isObject(e)&&"value"in e&&Object.keys(e).every(t=>t==="value"||t==="basis"||t==="rationale")}static typeOf(e){return Array.isArray(e)?"array":e===null?"null":typeof e}}class Ln{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(e,t){const i=Number.isFinite(t)?Math.max(0,t):0,n=Math.max(0,e-i*1e3),s=Math.max(0,e-n);return{fromMs:n,toMs:e,ms:s,seconds:s/1e3}}static instants(e,t,i,n,s){if(!(n>0))return 1;const a=s>0?Ln.travelDegOver(e,t,i,i+n*1e3)/s/Ln.PIXELS_PER_INSTANT:0,o=Ln.flashesOver(e,n)*Ln.INSTANTS_PER_FLASH,l=Math.ceil(Math.max(a,o));return l<2?1:Math.min(Ln.MAX_INSTANTS,l)}static travelDegOver(e,t,i,n){let s=0;for(const a of e){if(!a.track||a.track.length<2)continue;const o=Ln.directionAt(a,t,i),l=Ln.directionAt(a,t,n),c=Math.min(1,Math.max(-1,o.x*l.x+o.y*l.y+o.z*l.z));s=Math.max(s,Math.acos(c)*180/Math.PI)}return s}static flashesOver(e,t){let i=0;for(const n of e)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*t}static directionAt(e,t,i){const n=Fr(e,i),s=n.eastM,a=n.altitudeM-t,o=n.northM,l=Math.hypot(s,a,o);return l===0?{x:0,y:1,z:0}:{x:s/l,y:a/l,z:o/l}}}function u0(r,e){for(const t of r){const i=t.toLowerCase().split("-")[0];if(e.includes(i))return i}return"en"}class zr{static preferencesFor(e){const t=navigator.languages??[],i=this.declaredFor(e);return i?[i,...t]:t}static declaredFor(e){for(let t=e;t;){const i=t.closest("[lang]")?.getAttribute("lang")?.trim();if(i)return i;const n=t.getRootNode();t=n instanceof ShadowRoot?n.host:void 0}}}class Nn{constructor(e){this.preferences=e}read(e){if(e===void 0||typeof e=="string")return e===""?void 0:e;for(const i of this.preferences){const n=e[i]??e[Nn.base(i)];if(n)return n}const t=new Set(this.preferences.map(i=>Nn.base(i)));for(const[i,n]of Object.entries(e))if(n&&t.has(Nn.base(i)))return n;return Object.values(e).find(i=>i)??void 0}write(e,t,i){const n=t?.trim()?t.trim():void 0;if(e===void 0||typeof e=="string")return n;const s={...e},a=Object.keys(s).find(o=>o===i)??Object.keys(s).find(o=>Nn.base(o)===Nn.base(i))??i;return n===void 0?delete s[a]:s[a]=n,Object.keys(s).length===0?void 0:s}static base(e){return e.toLowerCase().split("-")[0]}}const f0=["en","fr","es","it"],M2={en:()=>gi(()=>Promise.resolve().then(()=>_2),void 0,import.meta.url).then(r=>r.ufoMessages_en),fr:()=>gi(()=>import("./UfoMessages_fr-BnjRvJ7U.js"),[],import.meta.url).then(r=>r.ufoMessages_fr),es:()=>gi(()=>import("./UfoMessages_es-Cm0EH1RY.js"),[],import.meta.url).then(r=>r.ufoMessages_es),it:()=>gi(()=>import("./UfoMessages_it-BsE5MTYw.js"),[],import.meta.url).then(r=>r.ufoMessages_it)};function y2(r){return M2[r]()}const x2={en:()=>gi(()=>Promise.resolve().then(()=>CA),void 0,import.meta.url).then(r=>r.sightingMessages_en),fr:()=>gi(()=>import("./SightingMessages_fr-Bi3UGi2K.js"),[],import.meta.url).then(r=>r.sightingMessages_fr),es:()=>gi(()=>import("./SightingMessages_es-CuXkfshc.js"),[],import.meta.url).then(r=>r.sightingMessages_es),it:()=>gi(()=>import("./SightingMessages_it-DbQmrjtT.js"),[],import.meta.url).then(r=>r.sightingMessages_it)};function b2(r){return x2[r]()}function S2(r){switch(r){case"fr":return gi(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(e=>e.tagNames_fr);case"es":return gi(()=>import("./TagNames_es-BfnMpc3D.js"),[],import.meta.url).then(e=>e.tagNames_es);case"it":return gi(()=>import("./TagNames_it-n6E4EGYO.js"),[],import.meta.url).then(e=>e.tagNames_it);default:return Promise.resolve({})}}function Dg(r){switch(r){case"fr":return gi(()=>import("./SceneNames_fr-BJltNyw-.js"),[],import.meta.url).then(e=>e.sceneNames_fr);case"es":return gi(()=>import("./SceneNames_es-B6UgSlXt.js"),[],import.meta.url).then(e=>e.sceneNames_es);case"it":return gi(()=>import("./SceneNames_it-CQKtZ4O0.js"),[],import.meta.url).then(e=>e.sceneNames_it);default:return Promise.resolve(void 0)}}const Ig={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",referenceOpacity:"Picture opacity",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Ur.EN},_2=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:Ig},Symbol.toStringTag,{value:"Module"})),Pg=Math.PI/180,w2=180/Math.PI,E2=256,Lg=19,A2=1.25;function Og(r,e){return 156543.03392*Math.cos(r*Pg)/2**e}function Ng(r,e){return Og(r,e)*E2}function T2(r,e){let t=0;for(;t<Lg&&Ng(r,t+1)>=e;)t++;return t}function kg(r,e){return Ng(r,e)}function R2(r,e){const t=e*A2;let i=0;for(;i<Lg&&Og(r,i)>t;)i++;return i}function cc(r){const e=r*Pg;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}function Fg(r,e,t){const i=2**t;return{x:(r+180)/360*i,y:cc(e)*i}}function Ug(r,e,t){const i=cc(r.north),n=cc(r.south);return{x:(e-r.west)/(r.east-r.west),y:(cc(t)-i)/(n-i)}}function C2(r,e,t){const{x:i,y:n}=Fg(r,e,t);return{x:Math.floor(i),y:Math.floor(n),z:t}}function D2(r){const e=2**r.z,t=r.x/e*360-180,i=(r.x+1)/e*360-180,n=kf(r.y,e);return{south:kf(r.y+1,e),north:n,west:t,east:i}}function kf(r,e){const t=r/e;return Math.atan(Math.sinh(Math.PI*(1-2*t)))*w2}function zg(r,e,t,i){const n=C2(r,e,t),s=Math.floor(i/2),a=[];for(let c=-s;c<=s;c++)for(let h=-s;h<=s;h++)a.push({x:n.x+h,y:n.y+c,z:t});const o=a.map(D2),l={south:Math.min(...o.map(c=>c.south)),north:Math.max(...o.map(c=>c.north)),west:Math.min(...o.map(c=>c.west)),east:Math.max(...o.map(c=>c.east))};return{tiles:a,bounds:l}}class ba{constructor(e){this.ctx=e}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(e,t){let i,n=1/0;for(const s of this.targets){const a=Math.hypot(s.x-e,s.y-t);a>s.radius||a>n||(i=s,n=a)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(e){const{ctx:t}=this;t.save(),this.targets=[],t.clearRect(0,0,this.width,this.height),this.paintGround(e),this.paintNight(e.nightFraction),this.paintPath(e),e.position?(this.paintCone(e,e.position),this.paintDecor(e),this.paintMarkers(e),this.paintObserver(e,e.position)):(this.paintDecor(e),this.paintMarkers(e)),this.paintNorth(),this.paintFooter(e.bounds,e.attribution),t.restore()}toCanvas(e,t,i){const n=Ug(e,i,t);return{x:n.x*this.width,y:n.y*this.height}}paintGround(e){const{ctx:t}=this;t.fillStyle="#1d2321",t.fillRect(0,0,this.width,this.height);const i=e.imagery;if(!i)return;const n=this.toCanvas(e.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(e.bounds,i.bounds.south,i.bounds.east);t.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(e=0){if(e<=0)return;const{ctx:t}=this;t.save(),t.fillStyle=`rgba(6, 12, 30, ${Math.min(e,1)*.78})`,t.fillRect(0,0,this.width,this.height),t.restore()}paintDecor(e){const{ctx:t}=this;for(const i of e.decor){const n=this.toCanvas(e.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),t.beginPath(),t.rect(n.x-3.5,n.y-3.5,7,7),t.fillStyle="rgba(120, 220, 255, 0.85)",t.fill(),t.lineWidth=1.5,t.strokeStyle="rgba(0, 0, 0, 0.7)",t.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),t.lineWidth=3,t.strokeStyle="rgba(0, 0, 0, 0.6)",t.stroke(),t.lineWidth=1.5,t.strokeStyle="rgba(120, 220, 255, 0.9)",t.stroke()}}paintPath(e){if(!e.path.moved)return;const{ctx:t}=this,i=e.path.points.map(n=>this.toCanvas(e.bounds,n.lat,n.lng));t.beginPath(),t.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))t.lineTo(n.x,n.y);t.lineJoin="round",t.lineCap="round",t.strokeStyle="rgba(0, 0, 0, 0.65)",t.lineWidth=5,t.stroke(),t.strokeStyle="rgba(255, 255, 255, 0.9)",t.lineWidth=2,t.stroke()}paintCone(e,t){const{headingDeg:i,coneHalfAngleDeg:n}=e;if(i===void 0||n===void 0)return;const{ctx:s}=this,a=this.toCanvas(e.bounds,t.lat,t.lng),o=Math.hypot(this.width,this.height),l=(i-90)*Math.PI/180,c=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(a.x,a.y),s.arc(a.x,a.y,o,l-c,l+c),s.closePath();const h=s.createRadialGradient(a.x,a.y,0,a.x,a.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(e){const{ctx:t}=this;t.textAlign="center",t.textBaseline="middle",t.font="bold 10px sans-serif";for(const i of[...e.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(e.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:ba.MARKER_RADIUS_PX}),t.beginPath(),t.arc(n.x,n.y,ba.MARKER_RADIUS_PX,0,Math.PI*2),t.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",t.fill(),t.lineWidth=2,t.strokeStyle="rgba(255, 255, 255, 0.9)",t.stroke(),t.fillStyle=i.current?"#1d2321":"#fff",t.fillText(i.label,n.x,n.y)}}paintObserver(e,t){const{ctx:i}=this,n=this.toCanvas(e.bounds,t.lat,t.lng);e.observerLabel&&this.targets.push({kind:"observer",label:e.observerLabel,lat:t.lat,lng:t.lng,x:n.x,y:n.y,radius:8});const s=e.markers.some(a=>{if(!a.current)return!1;const o=ri(a.lat,a.lng,t.lat,t.lng);return Math.hypot(o.x,o.z)<=ba.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?ba.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:e}=this,t=this.width-14,i=16;e.beginPath(),e.moveTo(t,i-9),e.lineTo(t-4.5,i+5),e.lineTo(t,i+2),e.lineTo(t+4.5,i+5),e.closePath(),e.fillStyle="rgba(255, 255, 255, 0.92)",e.strokeStyle="rgba(0, 0, 0, 0.6)",e.lineWidth=1,e.fill(),e.stroke(),e.font="bold 9px sans-serif",e.textAlign="center",e.textBaseline="top",e.strokeText("N",t,i+6),e.fillText("N",t,i+6)}paintFooter(e,t){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=t?this.wrap(t,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const a=(e.south+e.north)/2,l=Math.abs(ri(a,e.east,a,e.west).x)/this.width,c=ba.SCALE_STEPS_M.find(f=>f/l<=this.width/3);if(c===void 0)return;const h=c/l,d=8,u=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(d,u),i.lineTo(d+h,u),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(c>=1e3?`${c/1e3} km`:`${c} m`,d,u-3)}paintOutlinedText(e,t,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(e,t,i),n.fillStyle="#fff",n.fillText(e,t,i)}wrap(e,t){const i=[];let n="";for(const s of e.split(" ")){const a=n?`${n} ${s}`:s;n&&this.ctx.measureText(a).width>t?(i.push(n),n=s):n=a}return n&&i.push(n),i}}class Yt{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(e,t,i){const n=Math.min(Yt.MAX_ZOOM,Math.max(Yt.MIN_ZOOM,this.zoom*i)),s=this.centerX+(e-.5)/this.zoom,a=this.centerY+(t-.5)/this.zoom;this.centerX=s-(e-.5)/n,this.centerY=a-(t-.5)/n,this.zoom=n}panBy(e,t){this.centerX-=e/this.zoom,this.centerY-=t/this.zoom}refit(e,t){if(!this.changed)return;const i=this.boundsWithin(e),n=Yt.mercatorY01(t.north),s=Yt.mercatorY01(t.south),a=Yt.mercatorY01(i.north),o=Yt.mercatorY01(i.south);this.zoom=(t.east-t.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-t.west)/(t.east-t.west),this.centerY=((a+o)/2-n)/(s-n)}keepInView(e,t,i){if(!this.changed)return!1;const n=this.boundsWithin(e),s=Yt.mercatorY01(n.north),a=Yt.mercatorY01(n.south),o=(t.lng-n.west)/(n.east-n.west),l=(Yt.mercatorY01(t.lat)-s)/(a-s);return o>=i&&o<=1-i&&l>=i&&l<=1-i?!1:(this.panBy(.5-o,.5-l),!0)}boundsWithin(e){if(!this.changed)return e;const t=.5/this.zoom,i=Yt.mercatorY01(e.north),n=Yt.mercatorY01(e.south),s=e.east-e.west;return{west:e.west+(this.centerX-t)*s,east:e.west+(this.centerX+t)*s,north:Yt.latitudeAt(i+(this.centerY-t)*(n-i)),south:Yt.latitudeAt(i+(this.centerY+t)*(n-i))}}static expand(e,t){const i=e.east-e.west,n=e.north-e.south;return{west:e.west-i*t,east:e.east+i*t,south:e.south-n*t,north:e.north+n*t}}static pointAt(e,t,i){const n=Yt.mercatorY01(e.north),s=Yt.mercatorY01(e.south);return{lat:Yt.latitudeAt(n+i*(s-n)),lng:e.west+t*(e.east-e.west)}}static mercatorY01(e){const t=e*Math.PI/180;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}static latitudeAt(e){return Math.atan(Math.sinh(Math.PI*(1-2*e)))*180/Math.PI}}const mn=256,Ff=3,I2=32768;class P2{fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(e,t){const i=(e.south+e.north)/2,n=(e.west+e.east)/2,s=Math.abs(ri(i,e.east,i,e.west).x),a=Math.abs(ri(e.north,n,e.south,n).z),o=T2(i,Math.max(s,a)),{tiles:l}=zg(n,i,o,Ff),c=Ff*mn,h=new Float32Array(c*c),d=l[0];await Promise.all(l.map(f=>this.decodeTileInto(f,d,h,c)));const u=new Float32Array(t.width*t.height);for(let f=0;f<t.height;f++){const p=e.north+(e.south-e.north)*(f/(t.height-1));for(let v=0;v<t.width;v++){const m=e.west+(e.east-e.west)*(v/(t.width-1));u[f*t.width+v]=this.sampleAt(p,m,o,d,h,c)}}return{heights:u,width:t.width,height:t.height,bounds:e}}async decodeTileInto(e,t,i,n){const s=this.tileUrlTemplate.replace("{z}",String(e.z)).replace("{x}",String(e.x)).replace("{y}",String(e.y)),a=await this.fetchImpl(s);if(!a.ok)throw new Error(`Elevation tile fetch failed (${a.status}): ${s}`);const o=await createImageBitmap(await a.blob()),l=document.createElement("canvas");l.width=mn,l.height=mn;const c=l.getContext("2d");if(!c)throw new Error("2D canvas context unavailable");c.drawImage(o,0,0);const{data:h}=c.getImageData(0,0,mn,mn),d=(e.x-t.x)*mn,u=(e.y-t.y)*mn;for(let f=0;f<mn;f++)for(let p=0;p<mn;p++){const v=(f*mn+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-I2,g=d+p,S=u+f;i[S*n+g]=m}}sampleAt(e,t,i,n,s,a){const{x:o,y:l}=Fg(t,e,i),c=(o-n.x)*mn,h=(l-n.y)*mn,d=Math.max(0,Math.min(a-1,Math.floor(c))),u=Math.max(0,Math.min(a-1,Math.floor(h))),f=Math.min(a-1,d+1),p=Math.min(a-1,u+1),v=c-d,m=h-u,g=s[u*a+d],S=s[u*a+f],x=s[p*a+d],M=s[p*a+f],_=g+(S-g)*v,w=x+(M-x)*v;return _+(w-_)*m}}const hc=256,L2=5;async function O2(r,e,t,i){const n=(r.south+r.north)/2,s=(r.west+r.east)/2,a=Math.abs(ri(n,r.east,n,r.west).x),o=Math.abs(ri(r.north,s,r.south,s).z),l=Math.max(a,o),{zoom:c,gridSize:h}=N2(n,l,Math.max(e.width,e.height)),{tiles:d,bounds:u}=zg(s,n,c,h),f=h*hc,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=d[0];await Promise.all(d.map(async M=>{const _=t(M),w=await i(_);if(!w.ok)throw new Error(`Imagery tile fetch failed (${w.status}): ${_}`);const T=await createImageBitmap(await w.blob());v.drawImage(T,(M.x-m.x)*hc,(M.y-m.y)*hc)}));const g=Math.min(Math.max(e.width,e.height),f);if(g===f)return{source:p,width:f,height:f,bounds:u};const S=document.createElement("canvas");S.width=g,S.height=g;const x=S.getContext("2d");if(!x)throw new Error("2D canvas context unavailable");return x.drawImage(p,0,0,f,f,0,0,g,g),{source:S,width:g,height:g,bounds:u}}function N2(r,e,t){let i=R2(r,e/Math.max(1,t)),n=Uf(r,i,e);for(;n>L2&&i>0;)i--,n=Uf(r,i,e);return{zoom:i,gridSize:n,mPerPixel:kg(r,i)/hc}}function Uf(r,e,t){const i=Math.ceil(t/2/kg(r,e));return Math.max(3,2*i+1)}class k2{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(e,t){return O2(e,t,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class Rn{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.endpoints=e.endpoints??Rn.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(e){const t=`${e.south},${e.west},${e.north},${e.east}`,i=`[out:json][timeout:30];way["highway"~"^(${Rn.DRIVABLE.join("|")})$"](${t});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(e){const t=[];for(const i of e.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||t.push({id:`osm-${i.id??t.length}`,name:s.name,surface:Rn.surfaceOf(s),widthM:Rn.widthOf(s),points:n.map(a=>({lat:a.lat,lng:a.lon}))})}return t}queued(e){const t=Rn.queue.then(e,e);return Rn.queue=t.catch(()=>{}),t}async ask(e){let t;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(e)}`);if(s.ok)return await s.json();if(t=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){t=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,Rn.RETRY_MS))}throw t??new Error("No Overpass instance answered")}static widthOf(e){const t=Number.parseFloat(e.width??e.est_width??"");if(Number.isFinite(t)&&t>0)return t;const i=Number.parseInt(e.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:Rn.WIDTH_M[e.highway]??Rn.DEFAULT_WIDTH_M}static surfaceOf(e){const t=e.surface;return t==="dirt"||t==="earth"||t==="mud"?"dirt":t==="gravel"||t==="fine_gravel"||t==="compacted"||t==="ground"||t==="sand"||t==="unpaved"?"gravel":t?"paved":e.highway==="track"?"gravel":"paved"}}const mh="https://ufoathome.org/roads/index.json";class p0{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??p0.defaultIndexUrls(),this.fallback=e.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(e){const t=await this.held(e);if(t)return t;if(!this.fallback)return[];const i=await this.fallback.getRoads(e);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(e){let t;try{t=await this.load()}catch{return}const i=t.find(({entry:n})=>n.north>=e.north&&n.south<=e.south&&n.east>=e.east&&n.west<=e.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){return this.index??=this.fetchFirstAvailable(),this.index}async fetchFirstAvailable(){for(const e of this.indexUrls)try{const t=await this.fetchImpl(e);if(!t.ok)continue;const i=await t.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:e}))}catch{}return[]}static defaultIndexUrls(){const e=`?v=${encodeURIComponent("0.80.0")}`,t=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(t&&t!==mh?[t,mh]:[mh]).map(i=>i+e)}}function F2(){return{elevation:new P2,imagery:Bg(),roads:U2()}}function Bg(){return new k2}function U2(){return new p0({fallback:new Rn})}const z2=new Set,As="show-observer-map",Ts="hide-milestones";class ft extends HTMLElement{static get observedAttributes(){return["src",As,Ts]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;referenceOpacityInput;referencesShownState=!0;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new Yt;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=Zc.create();issues=[];issueCheck=0;sightingAudio=new f2;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=Ig;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const e=this.controlsRow,t=e.classList.contains("more-open"),i=()=>e.scrollWidth>e.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,e.classList.remove("narrow","more-open","nomoments","compact","tiny"),e.clientWidth>0&&i()){e.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;e.classList.add(s)}t&&e.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(e){this.controlsRow.classList.toggle("more-open",!e),this.updateMoreButton()}updateMoreButton(){const e=this.controlsRow.classList.contains("more-open");ft.setIcon(this.moreButton,e?$e.UNFOLDED:$e.FOLDED);const t=e?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=t,this.moreButton.setAttribute("aria-label",t),this.moreButton.setAttribute("aria-expanded",String(e))}addControl(e){this.controlsRight.insertBefore(e,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=e=>{e.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=e=>{const t=this.canvasPointFromEvent(e),i=t&&this.shapeAt(t.x,t.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-s.left+12}px`,this.tooltip.style.top=`${e.clientY-s.top+12}px`};handleObserverMapPointerMove=e=>{if(this.dragObserverMap(e))return;const t=this.observerMapTargetFrom(e);if(!t){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(e,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(e,t.label)};showObserverMapTooltip(e,t){this.tooltip.textContent=t,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-i.left+12}px`,this.tooltip.style.top=`${e.clientY-i.top+12}px`}handleObserverMapClick=e=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const t=this.observerMapTargetFrom(e);if(!t){this.observerPlacing&&this.placeObserverFrom(e);return}if(t.kind==="milestone"&&t.t!==void 0){this.player.seek(t.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:t.lat,lng:t.lng,kind:t.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(e){const t=this.observerMapCanvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return this.observerMapRenderer.hitTest((e.clientX-t.left)/t.width*this.observerMapCanvas.width,(e.clientY-t.top)/t.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=e=>{e.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,lastX:e.clientX,lastY:e.clientY,moved:!1})};handleObserverMapPointerUp=e=>{const t=this.observerMapDrag;!t||t.pointerId!==e.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),t.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(e.pointerId)&&this.observerMapCanvas.releasePointerCapture(e.pointerId)))};dragObserverMap(e){const t=this.observerMapDrag;if(!t||t.pointerId!==e.pointerId)return!1;if(!t.moved){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<ft.OBSERVER_MAP_DRAG_PX)return!1;t.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(e.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((e.clientX-t.lastX)/i.width,(e.clientY-t.lastY)/i.height),this.observerMapViewChanged()),t.lastX=e.clientX,t.lastY=e.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=e=>{e.preventDefault();const t=this.observerMapCanvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const i=e.deltaMode===0?e.deltaY:e.deltaY*40;this.zoomObserverMap((e.clientX-t.left)/t.width,(e.clientY-t.top)/t.height,Math.exp(-i*.002))};zoomObserverMap(e,t,i){this.observerMapView.zoomAt(e,t,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=Yt.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=Yt.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},ft.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(e){const t=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!t||i.width===0||i.height===0)return;const n=Yt.pointAt(t,(e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${a2}</style>${s2}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new Vo(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",t=>{t.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new ba(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",t=>{t.key!=="Enter"&&t.key!==" "||(t.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",t=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(t),this.beginTouchScrub(t)}),this.seekInput.addEventListener("pointerup",t=>{this.seekSnapArmed=!1,this.endTouchScrub(t)}),this.seekInput.addEventListener("pointercancel",t=>this.endTouchScrub(t)),this.seekInput.addEventListener("pointermove",t=>{this.nameMarkUnder(t),this.hoverSeek(t),this.touchScrub(t)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const t of["touchend","click"])this.stageElement.addEventListener(t,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",t=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}t.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",t=>{this.enableClickToPlay&&(t.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(e,t,i){e==="src"&&i&&i!==t&&this.isConnected&&this.loadFromSrc(i),e===As&&this.applyObserverMapDefault(),e===Ts&&this.setMilestonesShown(!this.hasAttribute(Ts))}async loadFromSrc(e){this.sightingData=await Co.json(e)}get sightingData(){return p2(this.currentSighting)}set sightingData(e){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=g2(e),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(e,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(e,t){const i=++this.issueCheck;let n=[];try{const{default:s}=await gi(async()=>{const{default:a}=await import("./sightingSchema-DOOSOVWK.js");return{default:a}},[],import.meta.url);n=new Tn(s).issues(e)}catch{}i===this.issueCheck&&(this.issues=[...n,...t.loadIssues],Ur.warn(this.issues,t.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(B2,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const e=this.issues.length;this.issuesBox.hidden=e===0,this.shadow.getElementById("issues-count").textContent=String(e);const t=this.messages.recordingIssues.replace("{count}",String(e));this.issuesButton.title=t,this.issuesButton.setAttribute("aria-label",t),this.shadow.getElementById("issues-title").textContent=t,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Ur.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(e){this.soundPreview=e,this.sightingAudio.resume(),this.sightingAudio.setSound(e)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(e){this.player.seek(e)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(e){e!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(e){this.toolbar.classList.toggle("hidden",!e),e?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(e){this.currentSighting.event.durationSeconds=e,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(e){const t=new Set(e);t.size===this.highlightedSourceIds.size&&[...t].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=t,this.refresh())}hasVisibleShapeAt(e,t){return this.shapeAt(e,t)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.player.seek(this.player.time)}hostControls(e){const t=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.observerMapButton];if(e)for(const i of t)e.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of t)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}toggleReferences(){this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const e=this.currentSighting.references;!this.referenceOpacityTouched&&e.length>0&&(this.referenceOpacityInput.value=String(e[0].opacity)),this.updateReferencesButton()}updateReferencesButton(){const e=this.currentSighting.references.length>0;this.referencesButton.hidden=!e,this.referenceOpacityInput.hidden=!e||!this.referencesShownState,this.referencesButton.setAttribute("aria-pressed",String(this.referencesShownState)),ft.setIcon(this.referencesButton,this.referencesShownState?$e.PICTURES_ON:$e.PICTURES_OFF);const t=this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=t,this.referencesButton.setAttribute("aria-label",t),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}dispatchReferenceView(){this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity}}))}refreshMilestoneMarks(){const e=this.player.seekableDuration,t=e>0?Do(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...t.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/e,0),1)*100}%`;const s=this.said.read(i.label)??"",a=this.said.read(i.note),o=a?`${s} — ${a}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(e,t.map(i=>i.t)),this.refreshMomentsPicker(t)}refreshMomentsPicker(e){const t=this.milestonesShown&&e.length>0;this.momentsBox.hidden=!t,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...e.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const a=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${a} — ${o}`:a,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(e){const i=(e?this.said.read(e.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=e!==void 0&&Number(n.dataset.t)===e.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=e=>{if(!this.momentsMenu.hidden){if(e instanceof KeyboardEvent){e.key==="Escape"&&this.closeMomentsMenu();return}e.composedPath().some(t=>t===this.momentsMenu||t===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(e,t){const n=[0,...this.milestonesShown&&e>0?[...new Set(t.filter(a=>a>0&&a<e))].sort((a,o)=>a-o):[],Math.max(e,0)];this.seekSegmentList=[];const s=[];for(let a=0;a<n.length-1;a++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[a+1]-n[a],1));const l=document.createElement("i");l.className="seek-hover";const c=document.createElement("i");c.className="seek-played",o.append(l,c),s.push(o),this.seekSegmentList.push({start:n[a],end:n[a+1],element:o,played:c,hover:l})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(e,t){const i=e.end-e.start,n=i>0?(t-e.start)/i:t>=e.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(e){for(const i of this.seekSegmentList)i.played.style.width=ft.fillOf(i,e);const t=this.player.seekableDuration;this.seekDot.style.left=`${t>0?Math.min(Math.max(e/t,0),1)*100:0}%`}hoverSeek(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=Math.min(Math.max((e.clientX-t.left)/t.width,0),1),s=n*i,a=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=ft.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===a))});const o=this.milestonesShown?this.sighting.milestones:[],l=o.length>0?fh(o,s):void 0,c=l?this.said.read(l.label)??"":"",h=l?this.said.read(l.note):void 0,d=h?`${c} — ${h}`:c;this.seekPreviewTitle.textContent=d,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const u=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*t.width-u/2,0),Math.max(t.width-u,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const e of this.seekSegmentList)e.hover.style.width="0",e.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(e){const t=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=t===void 0,t?.(e,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(e){if(e.pointerType!=="mouse"){this.scrubbingPointer=e.pointerId;try{this.seekInput.setPointerCapture(e.pointerId)}catch{}this.seekToPointer(e)}}touchScrub(e){e.pointerId===this.scrubbingPointer&&this.seekToPointer(e)}endTouchScrub(e){e.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(e))}seekToPointer(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=Math.min(Math.max((e.clientX-t.left)/t.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(e){const t=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(t<=0||i<=0)return;const n=ft.MARK_SNAP_PX/i*t;let s;for(const a of this.milestoneMarks.children){const o=Number(a.dataset.t);Math.abs(o-e)>n||(!s||Math.abs(o-e)<Math.abs(s.t-e))&&(s={t:o,name:a.title})}return s}snapSeekToMark(e){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(e)?.t??e):e}nameMarkUnder(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=(e.clientX-t.left)/t.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(e){const t=this.milestonesShown&&this.sighting.milestones.length>0?fh(this.sighting.milestones,e):void 0;if(this.milestoneCaption.hidden=t===void 0,this.showCurrentMoment(t),!t)return;const i=document.createElement("b");i.textContent=this.said.read(t.label)??"";const n=this.said.read(t.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(e){const t=this.exposureTimes(e),i=1/t.length;return t.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(e=this.currentTime){const t=Ln.windowEndingAt(e,this.currentSighting.exposure??0);if(t.ms<ft.SHORTEST_VISIBLE_EXPOSURE_MS)return[e];const i=Math.min(ft.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(t.ms/ft.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(t.fromMs,t.ms)/ft.EXPOSURE_STEP_PX),s=Math.min(ft.MAX_TRAVEL_STEPS,Math.max(i,n)),a=[];for(let o=0;o<s;o++)a.push(t.fromMs+t.ms*o/(s-1));return a}travelPxOver(e,t){const i=this.shapesAt(e),n=this.shapesAt(e+t);let s=0;for(const[a,o]of i){const l=n.get(a);if(!l)continue;const c=l.bounds.x+l.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=l.bounds.y+l.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(c,h))}return s}shapeAt(e,t,i){for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,e,t,i);if(s)return s}}shapesAt(e){const t=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(e,i);n&&t.set(i,n)}return t}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const e=oi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===e)return;this.canvas.width=e,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${e} / ${this.canvas.height}`)}canvasPointFromEvent(e){const t=this.canvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return{x:(e.clientX-t.left)/t.width*this.canvas.width,y:(e.clientY-t.top)/t.height*this.canvas.height}}onFrame(e,t){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:z2;this.canvasRenderer.setStarPoints(oi.starPointsOf(this.sighting.instrument));const n=(ti(this.sighting,e)?.rollDeg??0)+this.gaitAt(e).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(e),a=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,l]of o.shapes){const c=o.share,h=c===1?l:{...l,transparency:1-(1-l.transparency)*c};this.canvasRenderer.paintShape(this.shifted(h,a))}for(const[o,l]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,a)));if(this.selectionShown&&i.size>1){const o=hn.groupBoundsFor([...t].filter(([l])=>i.has(l)).map(([,l])=>l.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(l=>l.transparency<1).map(l=>this.shifted(l,a).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(e),this.paintSeekProgress(e),this.timeStartLabel.textContent=this.formatPosition(e),this.showMilestoneAt(e),this.paintObserverMap(e),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(wg(this.currentSighting,e))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:e}}))}shifted(e,t){return t.x===0&&t.y===0?e:{...e,bounds:{...e.bounds,x:e.bounds.x+t.x,y:e.bounds.y+t.y}}}createPlayer(){const e=new r2(this.currentSighting.timeline,(t,i)=>this.onFrame(t,i));return e.loop=this.loopEnabled,e.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},e}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=e=>{e.key.toLowerCase()!=="f"||e.altKey||e.ctrlKey||e.metaKey||!this.enableClickToPlay||e.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(e.preventDefault(),this.toggleFullscreen())};handleSeekKey=e=>{if(e.altKey||e.ctrlKey||e.metaKey)return;const t=e.key==="ArrowLeft"?-1:e.key==="ArrowRight"?1:0;if(t){e.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+t*ft.SEEK_KEY_STEP_MS)))}else e.key===" "&&(e.preventDefault(),this.togglePlayPause())};togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton(),this.flashPlayback())}flashPlayback(){const e=this.playbackFlash;e.innerHTML=this.player.playbackState==="playing"?$e.PLAY:$e.PAUSE,e.classList.remove("flashing"),e.offsetWidth,e.classList.add("flashing")}static icons=new WeakMap;static setIcon(e,t){ft.icons.get(e)!==t&&(ft.icons.set(e,t),e.innerHTML=t)}set captionHeld(e){this.stageElement.classList.toggle("caption-held",e)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},ft.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const e=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!e),e!==this.wasPlaying&&e&&this.hoverless&&this.revealControls(),this.wasPlaying=e,ft.setIcon(this.playPauseButton,e?$e.PAUSE:$e.PLAY);const t=this.player.seekableDuration>0;this.playPauseButton.disabled=!t;const i=t?e?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const e=this.playbackBeforeClick;e&&(this.currentTime=e.time,e.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(e=>{console.error("<rr0-ufo>: requestFullscreen() failed —",e)})}enterSimulatedFullscreen(){const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=e.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const t=e.style;t.setProperty("position","fixed"),t.setProperty("inset","0"),t.setProperty("margin","0"),t.setProperty("max-width","none"),t.setProperty("max-height","none"),t.setProperty("aspect-ratio","auto"),t.setProperty("z-index","2147483647"),t.setProperty("background","#000"),t.setProperty("width","100vw"),t.setProperty("width","100dvw"),t.setProperty("height","100vh"),t.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?e.setAttribute("style",this.styleBeforeSimulatedFullscreen):e.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const e=this.observerMapPanel.hidden;this.observerMapAsked=e,this.setObserverMapOpen(e),this.keepObserverMapClear()}observerMapAsked=!1;applyObserverMapDefault(){const e=this.getAttribute(As),t=e===null?this.observerPath?.travels===!0:e!=="false";this.setObserverMapOpen(t&&this.observerPath!==void 0)}setObserverMapOpen(e){this.observerMapPanel.hidden=!e,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(e)),this.updateObserverMapButton(),e&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const e=!this.observerMapPanel.hidden;ft.setIcon(this.observerMapButton,e?$e.MAP_ON:$e.MAP_OFF);const t=e?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=t,this.observerMapButton.setAttribute("aria-label",t);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const e=this.observerPath!==void 0;if(this.observerPath=Ar.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!e&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const t=this.observerPath.boundsAround(ft.OBSERVER_MAP_MIN_SPAN_M,ft.OBSERVER_MAP_MARGIN);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,t))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,t),this.observerMapBounds=t,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(e,t){const i=Math.abs(e.east-e.west)/20;return Math.abs(e.north-t.north)<i&&Math.abs(e.south-t.south)<i&&Math.abs(e.west-t.west)<i&&Math.abs(e.east-t.east)<i}async loadObserverMapImagery(){const e=this.observerMapViewBounds;if(!e||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(e))return;const t=this.observerMapView.changed,i=t?Yt.expand(e,ft.OBSERVER_MAP_IMAGERY_AHEAD):e,n=ft.OBSERVER_MAP_IMAGERY_PX*(t?1+2*ft.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=e.east-e.west,this.observerMapImageryLoading=!0;const s=Bg();try{const a=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=a,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(e){const t=this.observerMapImageryBounds;if(!t)return!0;const i=this.observerMapImagery?.bounds??t,n=this.observerMapView.changed?Yt.expand(e,ft.OBSERVER_MAP_IMAGERY_LOOKAHEAD):e,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,a=e.east-e.west>this.observerMapImageryViewWidth/2;return!s||!a}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(e){this.mapSceneBounds=e.map(t=>({x:t.x*this.canvas.width,y:t.y*this.canvas.height,width:t.width*this.canvas.width,height:t.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const e=this.observerMapBoxPx;if(!e)return;const t=[...this.mapShapeBounds,...this.mapSceneBounds],i=(c,h,d)=>{for(const u of t)if(!(u.x+u.width<c-d||u.x>h+d)&&!(u.y>e.bottom+d||u.y+u.height<e.top-d))return!0;return!1},n=[this.canvas.width-e.width,this.canvas.width],s=[0,e.width],a=ft.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),l=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&l&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(l||!i(n[0],n[1],a))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const e=this.observerMapPanel.clientWidth;if(e===0)return;const t=Math.round(e*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==t&&(this.observerMapCanvas.width=t,this.observerMapCanvas.height=t)}measureObserverMapBox(){const e=this.observerMapPanel.getBoundingClientRect(),t=this.canvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const i=this.canvas.width/t.width,n=this.canvas.height/t.height;this.observerMapBoxPx={width:e.width*i,top:(e.top-t.top)*n,bottom:(e.bottom-t.top)*n}}paintObserverMap(e){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const t=ti(this.currentSighting,e);t?.lat!==void 0&&t.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:t.lat,lng:t.lng},ft.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?fh(this.currentSighting.milestones,e):void 0;for(const a of this.milestonesShown?Do(this.currentSighting.milestones):[]){const o=ti(this.currentSighting,a.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(a.label)??"",note:this.said.read(a.note),t:a.t,lat:o.lat,lng:o.lng,current:a===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:t?.lat!==void 0&&t.lng!==void 0?{lat:t.lat,lng:t.lng}:void 0,headingDeg:t?.headingDeg===void 0?void 0:t.headingDeg+this.lookYawDeg,coneHalfAngleDeg:t?ws.of(i,this.canvas.height,t.fovDeg).halfWidthAngleDeg(oi.aspectOf(i)):void 0,markers:n,decor:this.observerMapDecorAt(e),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(e){this.milestonesShown=e,this.milestoneMarks.hidden=!e,this.momentsBox.hidden=!e||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Do(this.sighting.milestones).map(t=>t.t)),this.milestonesButton.setAttribute("aria-pressed",String(e)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,ft.setIcon(this.milestonesButton,this.milestonesShown?$e.MILESTONES_ON:$e.MILESTONES_OFF);const e=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=e,this.milestonesButton.setAttribute("aria-label",e)}observerMapDecorAt(e){const t=ti(this.currentSighting,0);return t?.lat===void 0||t.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Fr(i,e),{lat:s,lng:a}=_s(n.eastM,-n.northM,t.lat,t.lng);return{lat:s,lng:a,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(e){const t=e===void 0?void 0:Math.max(0,Math.min(1,-e/12));t!==this.observerMapNightFraction&&(this.observerMapNightFraction=t,this.paintObserverMap(this.currentTime))}setLookOffset(e,t){e===this.lookYawDeg&&t===this.lookPitchDeg||(this.lookYawDeg=e,this.lookPitchDeg=t,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const e=this.gaitAt(this.currentTime),t=this.lookYawDeg+e.yawDeg,i=this.lookPitchDeg+e.pitchDeg;if(t===0&&i===0)return{x:0,y:0};const n=ti(this.currentSighting,this.currentTime),s=ws.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(t),y:s.angleDegToRadiusPx(i)}}gaitAt(e){return bt.bodyAt(this.currentSighting,e,this.steadyObserver)}mutedState=!1;get muted(){return this.mutedState}set muted(e){e!==this.mutedState&&(this.mutedState=e,!e&&this.volumeState===0&&(this.volumeState=ft.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(e){this.setVolume(e)}setVolume(e){this.volumeState=Math.min(Math.max(e,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.muted=!this.mutedState}updateMuteButton(){ft.setIcon(this.muteButton,this.mutedState?$e.MUTED:$e.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=e,this.muteButton.setAttribute("aria-label",e),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const e=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;ft.setIcon(this.fullscreenButton,e?$e.EXIT_FULLSCREEN:$e.ENTER_FULLSCREEN),this.fullscreenButton.title=e?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Nn(zr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const e=u0(zr.preferencesFor(this),f0);if(e===this.messagesLanguage||e==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=e;const t=await y2(e);this.messagesLanguage===e&&this.applyMessages(t)}messagesLanguage;updateTimeLabelTitles(){const e=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,t=this.canSwitchTimeDisplay?` — ${e}`:"";this.timeStartLabel.title=this.messages.currentPosition+t,this.timeEndLabel.title=this.messages.duration+t,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(e){this.messages=e,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const e=this.currentSighting.event,t=_g(e);this.realDurationMs=t!==void 0&&t>0?t:void 0,this.realStartMs=e.time?Fd(e.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(e){if(this.realDurationMs===void 0)return ul(e);const t=this.currentSighting.timeline.duration,i=t>0&&e<=t?e/t*this.realDurationMs:e;return this.canShowClockTime?Bf(zf(this.realStartMs+i)):ul(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?ul(this.currentSighting.timeline.duration):this.canShowClockTime?Bf(zf(this.realStartMs+this.realDurationMs)):ul(this.realDurationMs)}}function zf(r){const e=new Date(r);return{hour:e.getUTCHours(),minute:e.getUTCMinutes(),second:e.getUTCSeconds()}}function Bf(r){if(r.hour===void 0)return"0:00";const e=t=>String(t).padStart(2,"0");return r.second?`${e(r.hour)}:${e(r.minute??0)}:${e(r.second)}`:`${e(r.hour)}:${e(r.minute??0)}`}function ul(r){const e=Math.round(r/1e3),t=Math.floor(e/60),i=e%60;return`${t}:${String(i).padStart(2,"0")}`}const zd="rr0-ufo";function Hg(){customElements.get(zd)||customElements.define(zd,ft)}const B2="recordingissues";/**
1942
+ `)}`)}}class Tn{constructor(e){this.format=e}issues(e){const t=[];return this.object(e,this.format,"",t),t}object(e,t,i,n){if(!Tn.isObject(e)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:Tn.typeOf(e)});return}for(const[s,a]of Object.entries(e)){const o=i?`${i}.${s}`:s,l=t[s];l?this.field(a,l,o,n):n.push({kind:"unknown-key",path:o})}}field(e,t,i,n){if(Tn.isStated(e)){this.field(e.value,t,i,n);return}if(!(t.loose||e===void 0||e===null))switch(t.type){case"enum":(typeof e!="string"||!t.values?.includes(e))&&n.push({kind:"not-in-list",path:i,expected:(t.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(e)});return;case"object":t.fields?this.object(e,t.fields,i,n):Tn.isObject(e)||n.push({kind:"wrong-type",path:i,expected:"object",found:Tn.typeOf(e)});return;case"array":Array.isArray(e)?t.fields&&e.forEach((s,a)=>{const o=Tn.isStated(s)?s.value:s;this.object(o,t.fields,`${i}.${a}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:Tn.typeOf(e)});return;default:typeof e!==t.type&&n.push({kind:"wrong-type",path:i,expected:t.type,found:Tn.typeOf(e)})}}static isObject(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}static isStated(e){return Tn.isObject(e)&&"value"in e&&Object.keys(e).every(t=>t==="value"||t==="basis"||t==="rationale")}static typeOf(e){return Array.isArray(e)?"array":e===null?"null":typeof e}}class Ln{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(e,t){const i=Number.isFinite(t)?Math.max(0,t):0,n=Math.max(0,e-i*1e3),s=Math.max(0,e-n);return{fromMs:n,toMs:e,ms:s,seconds:s/1e3}}static instants(e,t,i,n,s){if(!(n>0))return 1;const a=s>0?Ln.travelDegOver(e,t,i,i+n*1e3)/s/Ln.PIXELS_PER_INSTANT:0,o=Ln.flashesOver(e,n)*Ln.INSTANTS_PER_FLASH,l=Math.ceil(Math.max(a,o));return l<2?1:Math.min(Ln.MAX_INSTANTS,l)}static travelDegOver(e,t,i,n){let s=0;for(const a of e){if(!a.track||a.track.length<2)continue;const o=Ln.directionAt(a,t,i),l=Ln.directionAt(a,t,n),c=Math.min(1,Math.max(-1,o.x*l.x+o.y*l.y+o.z*l.z));s=Math.max(s,Math.acos(c)*180/Math.PI)}return s}static flashesOver(e,t){let i=0;for(const n of e)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*t}static directionAt(e,t,i){const n=Fr(e,i),s=n.eastM,a=n.altitudeM-t,o=n.northM,l=Math.hypot(s,a,o);return l===0?{x:0,y:1,z:0}:{x:s/l,y:a/l,z:o/l}}}function u0(r,e){for(const t of r){const i=t.toLowerCase().split("-")[0];if(e.includes(i))return i}return"en"}class zr{static preferencesFor(e){const t=navigator.languages??[],i=this.declaredFor(e);return i?[i,...t]:t}static declaredFor(e){for(let t=e;t;){const i=t.closest("[lang]")?.getAttribute("lang")?.trim();if(i)return i;const n=t.getRootNode();t=n instanceof ShadowRoot?n.host:void 0}}}class Nn{constructor(e){this.preferences=e}read(e){if(e===void 0||typeof e=="string")return e===""?void 0:e;for(const i of this.preferences){const n=e[i]??e[Nn.base(i)];if(n)return n}const t=new Set(this.preferences.map(i=>Nn.base(i)));for(const[i,n]of Object.entries(e))if(n&&t.has(Nn.base(i)))return n;return Object.values(e).find(i=>i)??void 0}write(e,t,i){const n=t?.trim()?t.trim():void 0;if(e===void 0||typeof e=="string")return n;const s={...e},a=Object.keys(s).find(o=>o===i)??Object.keys(s).find(o=>Nn.base(o)===Nn.base(i))??i;return n===void 0?delete s[a]:s[a]=n,Object.keys(s).length===0?void 0:s}static base(e){return e.toLowerCase().split("-")[0]}}const f0=["en","fr","es","it"],M2={en:()=>gi(()=>Promise.resolve().then(()=>_2),void 0,import.meta.url).then(r=>r.ufoMessages_en),fr:()=>gi(()=>import("./UfoMessages_fr-BnjRvJ7U.js"),[],import.meta.url).then(r=>r.ufoMessages_fr),es:()=>gi(()=>import("./UfoMessages_es-Cm0EH1RY.js"),[],import.meta.url).then(r=>r.ufoMessages_es),it:()=>gi(()=>import("./UfoMessages_it-BsE5MTYw.js"),[],import.meta.url).then(r=>r.ufoMessages_it)};function y2(r){return M2[r]()}const x2={en:()=>gi(()=>Promise.resolve().then(()=>CA),void 0,import.meta.url).then(r=>r.sightingMessages_en),fr:()=>gi(()=>import("./SightingMessages_fr-Bi3UGi2K.js"),[],import.meta.url).then(r=>r.sightingMessages_fr),es:()=>gi(()=>import("./SightingMessages_es-CuXkfshc.js"),[],import.meta.url).then(r=>r.sightingMessages_es),it:()=>gi(()=>import("./SightingMessages_it-DbQmrjtT.js"),[],import.meta.url).then(r=>r.sightingMessages_it)};function b2(r){return x2[r]()}function S2(r){switch(r){case"fr":return gi(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(e=>e.tagNames_fr);case"es":return gi(()=>import("./TagNames_es-BfnMpc3D.js"),[],import.meta.url).then(e=>e.tagNames_es);case"it":return gi(()=>import("./TagNames_it-n6E4EGYO.js"),[],import.meta.url).then(e=>e.tagNames_it);default:return Promise.resolve({})}}function Dg(r){switch(r){case"fr":return gi(()=>import("./SceneNames_fr-BbDQV822.js"),[],import.meta.url).then(e=>e.sceneNames_fr);case"es":return gi(()=>import("./SceneNames_es-D17SooUd.js"),[],import.meta.url).then(e=>e.sceneNames_es);case"it":return gi(()=>import("./SceneNames_it-DLcaIKpK.js"),[],import.meta.url).then(e=>e.sceneNames_it);default:return Promise.resolve(void 0)}}const Ig={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",referenceOpacity:"Picture opacity",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Ur.EN},_2=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:Ig},Symbol.toStringTag,{value:"Module"})),Pg=Math.PI/180,w2=180/Math.PI,E2=256,Lg=19,A2=1.25;function Og(r,e){return 156543.03392*Math.cos(r*Pg)/2**e}function Ng(r,e){return Og(r,e)*E2}function T2(r,e){let t=0;for(;t<Lg&&Ng(r,t+1)>=e;)t++;return t}function kg(r,e){return Ng(r,e)}function R2(r,e){const t=e*A2;let i=0;for(;i<Lg&&Og(r,i)>t;)i++;return i}function cc(r){const e=r*Pg;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}function Fg(r,e,t){const i=2**t;return{x:(r+180)/360*i,y:cc(e)*i}}function Ug(r,e,t){const i=cc(r.north),n=cc(r.south);return{x:(e-r.west)/(r.east-r.west),y:(cc(t)-i)/(n-i)}}function C2(r,e,t){const{x:i,y:n}=Fg(r,e,t);return{x:Math.floor(i),y:Math.floor(n),z:t}}function D2(r){const e=2**r.z,t=r.x/e*360-180,i=(r.x+1)/e*360-180,n=kf(r.y,e);return{south:kf(r.y+1,e),north:n,west:t,east:i}}function kf(r,e){const t=r/e;return Math.atan(Math.sinh(Math.PI*(1-2*t)))*w2}function zg(r,e,t,i){const n=C2(r,e,t),s=Math.floor(i/2),a=[];for(let c=-s;c<=s;c++)for(let h=-s;h<=s;h++)a.push({x:n.x+h,y:n.y+c,z:t});const o=a.map(D2),l={south:Math.min(...o.map(c=>c.south)),north:Math.max(...o.map(c=>c.north)),west:Math.min(...o.map(c=>c.west)),east:Math.max(...o.map(c=>c.east))};return{tiles:a,bounds:l}}class ba{constructor(e){this.ctx=e}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(e,t){let i,n=1/0;for(const s of this.targets){const a=Math.hypot(s.x-e,s.y-t);a>s.radius||a>n||(i=s,n=a)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(e){const{ctx:t}=this;t.save(),this.targets=[],t.clearRect(0,0,this.width,this.height),this.paintGround(e),this.paintNight(e.nightFraction),this.paintPath(e),e.position?(this.paintCone(e,e.position),this.paintDecor(e),this.paintMarkers(e),this.paintObserver(e,e.position)):(this.paintDecor(e),this.paintMarkers(e)),this.paintNorth(),this.paintFooter(e.bounds,e.attribution),t.restore()}toCanvas(e,t,i){const n=Ug(e,i,t);return{x:n.x*this.width,y:n.y*this.height}}paintGround(e){const{ctx:t}=this;t.fillStyle="#1d2321",t.fillRect(0,0,this.width,this.height);const i=e.imagery;if(!i)return;const n=this.toCanvas(e.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(e.bounds,i.bounds.south,i.bounds.east);t.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(e=0){if(e<=0)return;const{ctx:t}=this;t.save(),t.fillStyle=`rgba(6, 12, 30, ${Math.min(e,1)*.78})`,t.fillRect(0,0,this.width,this.height),t.restore()}paintDecor(e){const{ctx:t}=this;for(const i of e.decor){const n=this.toCanvas(e.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),t.beginPath(),t.rect(n.x-3.5,n.y-3.5,7,7),t.fillStyle="rgba(120, 220, 255, 0.85)",t.fill(),t.lineWidth=1.5,t.strokeStyle="rgba(0, 0, 0, 0.7)",t.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),t.lineWidth=3,t.strokeStyle="rgba(0, 0, 0, 0.6)",t.stroke(),t.lineWidth=1.5,t.strokeStyle="rgba(120, 220, 255, 0.9)",t.stroke()}}paintPath(e){if(!e.path.moved)return;const{ctx:t}=this,i=e.path.points.map(n=>this.toCanvas(e.bounds,n.lat,n.lng));t.beginPath(),t.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))t.lineTo(n.x,n.y);t.lineJoin="round",t.lineCap="round",t.strokeStyle="rgba(0, 0, 0, 0.65)",t.lineWidth=5,t.stroke(),t.strokeStyle="rgba(255, 255, 255, 0.9)",t.lineWidth=2,t.stroke()}paintCone(e,t){const{headingDeg:i,coneHalfAngleDeg:n}=e;if(i===void 0||n===void 0)return;const{ctx:s}=this,a=this.toCanvas(e.bounds,t.lat,t.lng),o=Math.hypot(this.width,this.height),l=(i-90)*Math.PI/180,c=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(a.x,a.y),s.arc(a.x,a.y,o,l-c,l+c),s.closePath();const h=s.createRadialGradient(a.x,a.y,0,a.x,a.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(e){const{ctx:t}=this;t.textAlign="center",t.textBaseline="middle",t.font="bold 10px sans-serif";for(const i of[...e.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(e.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:ba.MARKER_RADIUS_PX}),t.beginPath(),t.arc(n.x,n.y,ba.MARKER_RADIUS_PX,0,Math.PI*2),t.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",t.fill(),t.lineWidth=2,t.strokeStyle="rgba(255, 255, 255, 0.9)",t.stroke(),t.fillStyle=i.current?"#1d2321":"#fff",t.fillText(i.label,n.x,n.y)}}paintObserver(e,t){const{ctx:i}=this,n=this.toCanvas(e.bounds,t.lat,t.lng);e.observerLabel&&this.targets.push({kind:"observer",label:e.observerLabel,lat:t.lat,lng:t.lng,x:n.x,y:n.y,radius:8});const s=e.markers.some(a=>{if(!a.current)return!1;const o=ri(a.lat,a.lng,t.lat,t.lng);return Math.hypot(o.x,o.z)<=ba.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?ba.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:e}=this,t=this.width-14,i=16;e.beginPath(),e.moveTo(t,i-9),e.lineTo(t-4.5,i+5),e.lineTo(t,i+2),e.lineTo(t+4.5,i+5),e.closePath(),e.fillStyle="rgba(255, 255, 255, 0.92)",e.strokeStyle="rgba(0, 0, 0, 0.6)",e.lineWidth=1,e.fill(),e.stroke(),e.font="bold 9px sans-serif",e.textAlign="center",e.textBaseline="top",e.strokeText("N",t,i+6),e.fillText("N",t,i+6)}paintFooter(e,t){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=t?this.wrap(t,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const a=(e.south+e.north)/2,l=Math.abs(ri(a,e.east,a,e.west).x)/this.width,c=ba.SCALE_STEPS_M.find(f=>f/l<=this.width/3);if(c===void 0)return;const h=c/l,d=8,u=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(d,u),i.lineTo(d+h,u),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(c>=1e3?`${c/1e3} km`:`${c} m`,d,u-3)}paintOutlinedText(e,t,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(e,t,i),n.fillStyle="#fff",n.fillText(e,t,i)}wrap(e,t){const i=[];let n="";for(const s of e.split(" ")){const a=n?`${n} ${s}`:s;n&&this.ctx.measureText(a).width>t?(i.push(n),n=s):n=a}return n&&i.push(n),i}}class Yt{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(e,t,i){const n=Math.min(Yt.MAX_ZOOM,Math.max(Yt.MIN_ZOOM,this.zoom*i)),s=this.centerX+(e-.5)/this.zoom,a=this.centerY+(t-.5)/this.zoom;this.centerX=s-(e-.5)/n,this.centerY=a-(t-.5)/n,this.zoom=n}panBy(e,t){this.centerX-=e/this.zoom,this.centerY-=t/this.zoom}refit(e,t){if(!this.changed)return;const i=this.boundsWithin(e),n=Yt.mercatorY01(t.north),s=Yt.mercatorY01(t.south),a=Yt.mercatorY01(i.north),o=Yt.mercatorY01(i.south);this.zoom=(t.east-t.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-t.west)/(t.east-t.west),this.centerY=((a+o)/2-n)/(s-n)}keepInView(e,t,i){if(!this.changed)return!1;const n=this.boundsWithin(e),s=Yt.mercatorY01(n.north),a=Yt.mercatorY01(n.south),o=(t.lng-n.west)/(n.east-n.west),l=(Yt.mercatorY01(t.lat)-s)/(a-s);return o>=i&&o<=1-i&&l>=i&&l<=1-i?!1:(this.panBy(.5-o,.5-l),!0)}boundsWithin(e){if(!this.changed)return e;const t=.5/this.zoom,i=Yt.mercatorY01(e.north),n=Yt.mercatorY01(e.south),s=e.east-e.west;return{west:e.west+(this.centerX-t)*s,east:e.west+(this.centerX+t)*s,north:Yt.latitudeAt(i+(this.centerY-t)*(n-i)),south:Yt.latitudeAt(i+(this.centerY+t)*(n-i))}}static expand(e,t){const i=e.east-e.west,n=e.north-e.south;return{west:e.west-i*t,east:e.east+i*t,south:e.south-n*t,north:e.north+n*t}}static pointAt(e,t,i){const n=Yt.mercatorY01(e.north),s=Yt.mercatorY01(e.south);return{lat:Yt.latitudeAt(n+i*(s-n)),lng:e.west+t*(e.east-e.west)}}static mercatorY01(e){const t=e*Math.PI/180;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}static latitudeAt(e){return Math.atan(Math.sinh(Math.PI*(1-2*e)))*180/Math.PI}}const mn=256,Ff=3,I2=32768;class P2{fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(e,t){const i=(e.south+e.north)/2,n=(e.west+e.east)/2,s=Math.abs(ri(i,e.east,i,e.west).x),a=Math.abs(ri(e.north,n,e.south,n).z),o=T2(i,Math.max(s,a)),{tiles:l}=zg(n,i,o,Ff),c=Ff*mn,h=new Float32Array(c*c),d=l[0];await Promise.all(l.map(f=>this.decodeTileInto(f,d,h,c)));const u=new Float32Array(t.width*t.height);for(let f=0;f<t.height;f++){const p=e.north+(e.south-e.north)*(f/(t.height-1));for(let v=0;v<t.width;v++){const m=e.west+(e.east-e.west)*(v/(t.width-1));u[f*t.width+v]=this.sampleAt(p,m,o,d,h,c)}}return{heights:u,width:t.width,height:t.height,bounds:e}}async decodeTileInto(e,t,i,n){const s=this.tileUrlTemplate.replace("{z}",String(e.z)).replace("{x}",String(e.x)).replace("{y}",String(e.y)),a=await this.fetchImpl(s);if(!a.ok)throw new Error(`Elevation tile fetch failed (${a.status}): ${s}`);const o=await createImageBitmap(await a.blob()),l=document.createElement("canvas");l.width=mn,l.height=mn;const c=l.getContext("2d");if(!c)throw new Error("2D canvas context unavailable");c.drawImage(o,0,0);const{data:h}=c.getImageData(0,0,mn,mn),d=(e.x-t.x)*mn,u=(e.y-t.y)*mn;for(let f=0;f<mn;f++)for(let p=0;p<mn;p++){const v=(f*mn+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-I2,g=d+p,S=u+f;i[S*n+g]=m}}sampleAt(e,t,i,n,s,a){const{x:o,y:l}=Fg(t,e,i),c=(o-n.x)*mn,h=(l-n.y)*mn,d=Math.max(0,Math.min(a-1,Math.floor(c))),u=Math.max(0,Math.min(a-1,Math.floor(h))),f=Math.min(a-1,d+1),p=Math.min(a-1,u+1),v=c-d,m=h-u,g=s[u*a+d],S=s[u*a+f],x=s[p*a+d],M=s[p*a+f],_=g+(S-g)*v,w=x+(M-x)*v;return _+(w-_)*m}}const hc=256,L2=5;async function O2(r,e,t,i){const n=(r.south+r.north)/2,s=(r.west+r.east)/2,a=Math.abs(ri(n,r.east,n,r.west).x),o=Math.abs(ri(r.north,s,r.south,s).z),l=Math.max(a,o),{zoom:c,gridSize:h}=N2(n,l,Math.max(e.width,e.height)),{tiles:d,bounds:u}=zg(s,n,c,h),f=h*hc,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=d[0];await Promise.all(d.map(async M=>{const _=t(M),w=await i(_);if(!w.ok)throw new Error(`Imagery tile fetch failed (${w.status}): ${_}`);const T=await createImageBitmap(await w.blob());v.drawImage(T,(M.x-m.x)*hc,(M.y-m.y)*hc)}));const g=Math.min(Math.max(e.width,e.height),f);if(g===f)return{source:p,width:f,height:f,bounds:u};const S=document.createElement("canvas");S.width=g,S.height=g;const x=S.getContext("2d");if(!x)throw new Error("2D canvas context unavailable");return x.drawImage(p,0,0,f,f,0,0,g,g),{source:S,width:g,height:g,bounds:u}}function N2(r,e,t){let i=R2(r,e/Math.max(1,t)),n=Uf(r,i,e);for(;n>L2&&i>0;)i--,n=Uf(r,i,e);return{zoom:i,gridSize:n,mPerPixel:kg(r,i)/hc}}function Uf(r,e,t){const i=Math.ceil(t/2/kg(r,e));return Math.max(3,2*i+1)}class k2{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(e,t){return O2(e,t,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class Rn{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.endpoints=e.endpoints??Rn.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(e){const t=`${e.south},${e.west},${e.north},${e.east}`,i=`[out:json][timeout:30];way["highway"~"^(${Rn.DRIVABLE.join("|")})$"](${t});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(e){const t=[];for(const i of e.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||t.push({id:`osm-${i.id??t.length}`,name:s.name,surface:Rn.surfaceOf(s),widthM:Rn.widthOf(s),points:n.map(a=>({lat:a.lat,lng:a.lon}))})}return t}queued(e){const t=Rn.queue.then(e,e);return Rn.queue=t.catch(()=>{}),t}async ask(e){let t;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(e)}`);if(s.ok)return await s.json();if(t=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){t=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,Rn.RETRY_MS))}throw t??new Error("No Overpass instance answered")}static widthOf(e){const t=Number.parseFloat(e.width??e.est_width??"");if(Number.isFinite(t)&&t>0)return t;const i=Number.parseInt(e.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:Rn.WIDTH_M[e.highway]??Rn.DEFAULT_WIDTH_M}static surfaceOf(e){const t=e.surface;return t==="dirt"||t==="earth"||t==="mud"?"dirt":t==="gravel"||t==="fine_gravel"||t==="compacted"||t==="ground"||t==="sand"||t==="unpaved"?"gravel":t?"paved":e.highway==="track"?"gravel":"paved"}}const mh="https://ufoathome.org/roads/index.json";class p0{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.indexUrls=e.indexUrls??p0.defaultIndexUrls(),this.fallback=e.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(e){const t=await this.held(e);if(t)return t;if(!this.fallback)return[];const i=await this.fallback.getRoads(e);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(e){let t;try{t=await this.load()}catch{return}const i=t.find(({entry:n})=>n.north>=e.north&&n.south<=e.south&&n.east>=e.east&&n.west<=e.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){return this.index??=this.fetchFirstAvailable(),this.index}async fetchFirstAvailable(){for(const e of this.indexUrls)try{const t=await this.fetchImpl(e);if(!t.ok)continue;const i=await t.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:e}))}catch{}return[]}static defaultIndexUrls(){const e=`?v=${encodeURIComponent("0.80.1")}`,t=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(t&&t!==mh?[t,mh]:[mh]).map(i=>i+e)}}function F2(){return{elevation:new P2,imagery:Bg(),roads:U2()}}function Bg(){return new k2}function U2(){return new p0({fallback:new Rn})}const z2=new Set,As="show-observer-map",Ts="hide-milestones";class ft extends HTMLElement{static get observedAttributes(){return["src",As,Ts]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;referenceOpacityInput;referencesShownState=!0;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new Yt;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=Zc.create();issues=[];issueCheck=0;sightingAudio=new f2;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=Ig;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const e=this.controlsRow,t=e.classList.contains("more-open"),i=()=>e.scrollWidth>e.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,e.classList.remove("narrow","more-open","nomoments","compact","tiny"),e.clientWidth>0&&i()){e.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;e.classList.add(s)}t&&e.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(e){this.controlsRow.classList.toggle("more-open",!e),this.updateMoreButton()}updateMoreButton(){const e=this.controlsRow.classList.contains("more-open");ft.setIcon(this.moreButton,e?$e.UNFOLDED:$e.FOLDED);const t=e?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=t,this.moreButton.setAttribute("aria-label",t),this.moreButton.setAttribute("aria-expanded",String(e))}addControl(e){this.controlsRight.insertBefore(e,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=e=>{e.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=e=>{const t=this.canvasPointFromEvent(e),i=t&&this.shapeAt(t.x,t.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-s.left+12}px`,this.tooltip.style.top=`${e.clientY-s.top+12}px`};handleObserverMapPointerMove=e=>{if(this.dragObserverMap(e))return;const t=this.observerMapTargetFrom(e);if(!t){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(e,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(e,t.label)};showObserverMapTooltip(e,t){this.tooltip.textContent=t,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-i.left+12}px`,this.tooltip.style.top=`${e.clientY-i.top+12}px`}handleObserverMapClick=e=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const t=this.observerMapTargetFrom(e);if(!t){this.observerPlacing&&this.placeObserverFrom(e);return}if(t.kind==="milestone"&&t.t!==void 0){this.player.seek(t.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:t.lat,lng:t.lng,kind:t.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(e){const t=this.observerMapCanvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return this.observerMapRenderer.hitTest((e.clientX-t.left)/t.width*this.observerMapCanvas.width,(e.clientY-t.top)/t.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=e=>{e.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,lastX:e.clientX,lastY:e.clientY,moved:!1})};handleObserverMapPointerUp=e=>{const t=this.observerMapDrag;!t||t.pointerId!==e.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),t.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(e.pointerId)&&this.observerMapCanvas.releasePointerCapture(e.pointerId)))};dragObserverMap(e){const t=this.observerMapDrag;if(!t||t.pointerId!==e.pointerId)return!1;if(!t.moved){if(Math.hypot(e.clientX-t.startX,e.clientY-t.startY)<ft.OBSERVER_MAP_DRAG_PX)return!1;t.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(e.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((e.clientX-t.lastX)/i.width,(e.clientY-t.lastY)/i.height),this.observerMapViewChanged()),t.lastX=e.clientX,t.lastY=e.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=e=>{e.preventDefault();const t=this.observerMapCanvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const i=e.deltaMode===0?e.deltaY:e.deltaY*40;this.zoomObserverMap((e.clientX-t.left)/t.width,(e.clientY-t.top)/t.height,Math.exp(-i*.002))};zoomObserverMap(e,t,i){this.observerMapView.zoomAt(e,t,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=Yt.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=Yt.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},ft.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(e){const t=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!t||i.width===0||i.height===0)return;const n=Yt.pointAt(t,(e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${a2}</style>${s2}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new Vo(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",t=>{t.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new ba(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",t=>{t.key!=="Enter"&&t.key!==" "||(t.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",t=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(t),this.beginTouchScrub(t)}),this.seekInput.addEventListener("pointerup",t=>{this.seekSnapArmed=!1,this.endTouchScrub(t)}),this.seekInput.addEventListener("pointercancel",t=>this.endTouchScrub(t)),this.seekInput.addEventListener("pointermove",t=>{this.nameMarkUnder(t),this.hoverSeek(t),this.touchScrub(t)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const t of["touchend","click"])this.stageElement.addEventListener(t,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",t=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}t.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",t=>{this.enableClickToPlay&&(t.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(e,t,i){e==="src"&&i&&i!==t&&this.isConnected&&this.loadFromSrc(i),e===As&&this.applyObserverMapDefault(),e===Ts&&this.setMilestonesShown(!this.hasAttribute(Ts))}async loadFromSrc(e){this.sightingData=await Co.json(e)}get sightingData(){return p2(this.currentSighting)}set sightingData(e){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=g2(e),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(e,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(e,t){const i=++this.issueCheck;let n=[];try{const{default:s}=await gi(async()=>{const{default:a}=await import("./sightingSchema-DOOSOVWK.js");return{default:a}},[],import.meta.url);n=new Tn(s).issues(e)}catch{}i===this.issueCheck&&(this.issues=[...n,...t.loadIssues],Ur.warn(this.issues,t.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(B2,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const e=this.issues.length;this.issuesBox.hidden=e===0,this.shadow.getElementById("issues-count").textContent=String(e);const t=this.messages.recordingIssues.replace("{count}",String(e));this.issuesButton.title=t,this.issuesButton.setAttribute("aria-label",t),this.shadow.getElementById("issues-title").textContent=t,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Ur.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(e){this.soundPreview=e,this.sightingAudio.resume(),this.sightingAudio.setSound(e)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(e){this.player.seek(e)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(e){e!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(e){this.toolbar.classList.toggle("hidden",!e),e?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(e){this.currentSighting.event.durationSeconds=e,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(e){const t=new Set(e);t.size===this.highlightedSourceIds.size&&[...t].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=t,this.refresh())}hasVisibleShapeAt(e,t){return this.shapeAt(e,t)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.player.seek(this.player.time)}hostControls(e){const t=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.observerMapButton];if(e)for(const i of t)e.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of t)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}toggleReferences(){this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const e=this.currentSighting.references;!this.referenceOpacityTouched&&e.length>0&&(this.referenceOpacityInput.value=String(e[0].opacity)),this.updateReferencesButton()}updateReferencesButton(){const e=this.currentSighting.references.length>0;this.referencesButton.hidden=!e,this.referenceOpacityInput.hidden=!e||!this.referencesShownState,this.referencesButton.setAttribute("aria-pressed",String(this.referencesShownState)),ft.setIcon(this.referencesButton,this.referencesShownState?$e.PICTURES_ON:$e.PICTURES_OFF);const t=this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=t,this.referencesButton.setAttribute("aria-label",t),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}dispatchReferenceView(){this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity}}))}refreshMilestoneMarks(){const e=this.player.seekableDuration,t=e>0?Do(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...t.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/e,0),1)*100}%`;const s=this.said.read(i.label)??"",a=this.said.read(i.note),o=a?`${s} — ${a}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(e,t.map(i=>i.t)),this.refreshMomentsPicker(t)}refreshMomentsPicker(e){const t=this.milestonesShown&&e.length>0;this.momentsBox.hidden=!t,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...e.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const a=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${a} — ${o}`:a,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(e){const i=(e?this.said.read(e.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=e!==void 0&&Number(n.dataset.t)===e.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=e=>{if(!this.momentsMenu.hidden){if(e instanceof KeyboardEvent){e.key==="Escape"&&this.closeMomentsMenu();return}e.composedPath().some(t=>t===this.momentsMenu||t===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(e,t){const n=[0,...this.milestonesShown&&e>0?[...new Set(t.filter(a=>a>0&&a<e))].sort((a,o)=>a-o):[],Math.max(e,0)];this.seekSegmentList=[];const s=[];for(let a=0;a<n.length-1;a++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[a+1]-n[a],1));const l=document.createElement("i");l.className="seek-hover";const c=document.createElement("i");c.className="seek-played",o.append(l,c),s.push(o),this.seekSegmentList.push({start:n[a],end:n[a+1],element:o,played:c,hover:l})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(e,t){const i=e.end-e.start,n=i>0?(t-e.start)/i:t>=e.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(e){for(const i of this.seekSegmentList)i.played.style.width=ft.fillOf(i,e);const t=this.player.seekableDuration;this.seekDot.style.left=`${t>0?Math.min(Math.max(e/t,0),1)*100:0}%`}hoverSeek(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=Math.min(Math.max((e.clientX-t.left)/t.width,0),1),s=n*i,a=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=ft.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===a))});const o=this.milestonesShown?this.sighting.milestones:[],l=o.length>0?fh(o,s):void 0,c=l?this.said.read(l.label)??"":"",h=l?this.said.read(l.note):void 0,d=h?`${c} — ${h}`:c;this.seekPreviewTitle.textContent=d,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const u=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*t.width-u/2,0),Math.max(t.width-u,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const e of this.seekSegmentList)e.hover.style.width="0",e.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(e){const t=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=t===void 0,t?.(e,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(e){if(e.pointerType!=="mouse"){this.scrubbingPointer=e.pointerId;try{this.seekInput.setPointerCapture(e.pointerId)}catch{}this.seekToPointer(e)}}touchScrub(e){e.pointerId===this.scrubbingPointer&&this.seekToPointer(e)}endTouchScrub(e){e.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(e))}seekToPointer(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=Math.min(Math.max((e.clientX-t.left)/t.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(e){const t=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(t<=0||i<=0)return;const n=ft.MARK_SNAP_PX/i*t;let s;for(const a of this.milestoneMarks.children){const o=Number(a.dataset.t);Math.abs(o-e)>n||(!s||Math.abs(o-e)<Math.abs(s.t-e))&&(s={t:o,name:a.title})}return s}snapSeekToMark(e){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(e)?.t??e):e}nameMarkUnder(e){const t=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(t.width<=0||i<=0)return;const n=(e.clientX-t.left)/t.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(e){const t=this.milestonesShown&&this.sighting.milestones.length>0?fh(this.sighting.milestones,e):void 0;if(this.milestoneCaption.hidden=t===void 0,this.showCurrentMoment(t),!t)return;const i=document.createElement("b");i.textContent=this.said.read(t.label)??"";const n=this.said.read(t.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(e){const t=this.exposureTimes(e),i=1/t.length;return t.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(e=this.currentTime){const t=Ln.windowEndingAt(e,this.currentSighting.exposure??0);if(t.ms<ft.SHORTEST_VISIBLE_EXPOSURE_MS)return[e];const i=Math.min(ft.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(t.ms/ft.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(t.fromMs,t.ms)/ft.EXPOSURE_STEP_PX),s=Math.min(ft.MAX_TRAVEL_STEPS,Math.max(i,n)),a=[];for(let o=0;o<s;o++)a.push(t.fromMs+t.ms*o/(s-1));return a}travelPxOver(e,t){const i=this.shapesAt(e),n=this.shapesAt(e+t);let s=0;for(const[a,o]of i){const l=n.get(a);if(!l)continue;const c=l.bounds.x+l.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=l.bounds.y+l.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(c,h))}return s}shapeAt(e,t,i){for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,e,t,i);if(s)return s}}shapesAt(e){const t=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(e,i);n&&t.set(i,n)}return t}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const e=oi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===e)return;this.canvas.width=e,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${e} / ${this.canvas.height}`)}canvasPointFromEvent(e){const t=this.canvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return{x:(e.clientX-t.left)/t.width*this.canvas.width,y:(e.clientY-t.top)/t.height*this.canvas.height}}onFrame(e,t){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:z2;this.canvasRenderer.setStarPoints(oi.starPointsOf(this.sighting.instrument));const n=(ti(this.sighting,e)?.rollDeg??0)+this.gaitAt(e).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(e),a=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,l]of o.shapes){const c=o.share,h=c===1?l:{...l,transparency:1-(1-l.transparency)*c};this.canvasRenderer.paintShape(this.shifted(h,a))}for(const[o,l]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,a)));if(this.selectionShown&&i.size>1){const o=hn.groupBoundsFor([...t].filter(([l])=>i.has(l)).map(([,l])=>l.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(l=>l.transparency<1).map(l=>this.shifted(l,a).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(e),this.paintSeekProgress(e),this.timeStartLabel.textContent=this.formatPosition(e),this.showMilestoneAt(e),this.paintObserverMap(e),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(wg(this.currentSighting,e))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:e}}))}shifted(e,t){return t.x===0&&t.y===0?e:{...e,bounds:{...e.bounds,x:e.bounds.x+t.x,y:e.bounds.y+t.y}}}createPlayer(){const e=new r2(this.currentSighting.timeline,(t,i)=>this.onFrame(t,i));return e.loop=this.loopEnabled,e.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},e}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=e=>{e.key.toLowerCase()!=="f"||e.altKey||e.ctrlKey||e.metaKey||!this.enableClickToPlay||e.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(e.preventDefault(),this.toggleFullscreen())};handleSeekKey=e=>{if(e.altKey||e.ctrlKey||e.metaKey)return;const t=e.key==="ArrowLeft"?-1:e.key==="ArrowRight"?1:0;if(t){e.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+t*ft.SEEK_KEY_STEP_MS)))}else e.key===" "&&(e.preventDefault(),this.togglePlayPause())};togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton(),this.flashPlayback())}flashPlayback(){const e=this.playbackFlash;e.innerHTML=this.player.playbackState==="playing"?$e.PLAY:$e.PAUSE,e.classList.remove("flashing"),e.offsetWidth,e.classList.add("flashing")}static icons=new WeakMap;static setIcon(e,t){ft.icons.get(e)!==t&&(ft.icons.set(e,t),e.innerHTML=t)}set captionHeld(e){this.stageElement.classList.toggle("caption-held",e)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},ft.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const e=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!e),e!==this.wasPlaying&&e&&this.hoverless&&this.revealControls(),this.wasPlaying=e,ft.setIcon(this.playPauseButton,e?$e.PAUSE:$e.PLAY);const t=this.player.seekableDuration>0;this.playPauseButton.disabled=!t;const i=t?e?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const e=this.playbackBeforeClick;e&&(this.currentTime=e.time,e.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(e=>{console.error("<rr0-ufo>: requestFullscreen() failed —",e)})}enterSimulatedFullscreen(){const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=e.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const t=e.style;t.setProperty("position","fixed"),t.setProperty("inset","0"),t.setProperty("margin","0"),t.setProperty("max-width","none"),t.setProperty("max-height","none"),t.setProperty("aspect-ratio","auto"),t.setProperty("z-index","2147483647"),t.setProperty("background","#000"),t.setProperty("width","100vw"),t.setProperty("width","100dvw"),t.setProperty("height","100vh"),t.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?e.setAttribute("style",this.styleBeforeSimulatedFullscreen):e.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const e=this.observerMapPanel.hidden;this.observerMapAsked=e,this.setObserverMapOpen(e),this.keepObserverMapClear()}observerMapAsked=!1;applyObserverMapDefault(){const e=this.getAttribute(As),t=e===null?this.observerPath?.travels===!0:e!=="false";this.setObserverMapOpen(t&&this.observerPath!==void 0)}setObserverMapOpen(e){this.observerMapPanel.hidden=!e,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(e)),this.updateObserverMapButton(),e&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const e=!this.observerMapPanel.hidden;ft.setIcon(this.observerMapButton,e?$e.MAP_ON:$e.MAP_OFF);const t=e?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=t,this.observerMapButton.setAttribute("aria-label",t);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const e=this.observerPath!==void 0;if(this.observerPath=Ar.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!e&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const t=this.observerPath.boundsAround(ft.OBSERVER_MAP_MIN_SPAN_M,ft.OBSERVER_MAP_MARGIN);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,t))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,t),this.observerMapBounds=t,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(e,t){const i=Math.abs(e.east-e.west)/20;return Math.abs(e.north-t.north)<i&&Math.abs(e.south-t.south)<i&&Math.abs(e.west-t.west)<i&&Math.abs(e.east-t.east)<i}async loadObserverMapImagery(){const e=this.observerMapViewBounds;if(!e||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(e))return;const t=this.observerMapView.changed,i=t?Yt.expand(e,ft.OBSERVER_MAP_IMAGERY_AHEAD):e,n=ft.OBSERVER_MAP_IMAGERY_PX*(t?1+2*ft.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=e.east-e.west,this.observerMapImageryLoading=!0;const s=Bg();try{const a=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=a,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(e){const t=this.observerMapImageryBounds;if(!t)return!0;const i=this.observerMapImagery?.bounds??t,n=this.observerMapView.changed?Yt.expand(e,ft.OBSERVER_MAP_IMAGERY_LOOKAHEAD):e,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,a=e.east-e.west>this.observerMapImageryViewWidth/2;return!s||!a}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(e){this.mapSceneBounds=e.map(t=>({x:t.x*this.canvas.width,y:t.y*this.canvas.height,width:t.width*this.canvas.width,height:t.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const e=this.observerMapBoxPx;if(!e)return;const t=[...this.mapShapeBounds,...this.mapSceneBounds],i=(c,h,d)=>{for(const u of t)if(!(u.x+u.width<c-d||u.x>h+d)&&!(u.y>e.bottom+d||u.y+u.height<e.top-d))return!0;return!1},n=[this.canvas.width-e.width,this.canvas.width],s=[0,e.width],a=ft.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),l=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&l&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(l||!i(n[0],n[1],a))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const e=this.observerMapPanel.clientWidth;if(e===0)return;const t=Math.round(e*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==t&&(this.observerMapCanvas.width=t,this.observerMapCanvas.height=t)}measureObserverMapBox(){const e=this.observerMapPanel.getBoundingClientRect(),t=this.canvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const i=this.canvas.width/t.width,n=this.canvas.height/t.height;this.observerMapBoxPx={width:e.width*i,top:(e.top-t.top)*n,bottom:(e.bottom-t.top)*n}}paintObserverMap(e){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const t=ti(this.currentSighting,e);t?.lat!==void 0&&t.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:t.lat,lng:t.lng},ft.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?fh(this.currentSighting.milestones,e):void 0;for(const a of this.milestonesShown?Do(this.currentSighting.milestones):[]){const o=ti(this.currentSighting,a.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(a.label)??"",note:this.said.read(a.note),t:a.t,lat:o.lat,lng:o.lng,current:a===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:t?.lat!==void 0&&t.lng!==void 0?{lat:t.lat,lng:t.lng}:void 0,headingDeg:t?.headingDeg===void 0?void 0:t.headingDeg+this.lookYawDeg,coneHalfAngleDeg:t?ws.of(i,this.canvas.height,t.fovDeg).halfWidthAngleDeg(oi.aspectOf(i)):void 0,markers:n,decor:this.observerMapDecorAt(e),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(e){this.milestonesShown=e,this.milestoneMarks.hidden=!e,this.momentsBox.hidden=!e||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Do(this.sighting.milestones).map(t=>t.t)),this.milestonesButton.setAttribute("aria-pressed",String(e)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,ft.setIcon(this.milestonesButton,this.milestonesShown?$e.MILESTONES_ON:$e.MILESTONES_OFF);const e=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=e,this.milestonesButton.setAttribute("aria-label",e)}observerMapDecorAt(e){const t=ti(this.currentSighting,0);return t?.lat===void 0||t.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Fr(i,e),{lat:s,lng:a}=_s(n.eastM,-n.northM,t.lat,t.lng);return{lat:s,lng:a,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(e){const t=e===void 0?void 0:Math.max(0,Math.min(1,-e/12));t!==this.observerMapNightFraction&&(this.observerMapNightFraction=t,this.paintObserverMap(this.currentTime))}setLookOffset(e,t){e===this.lookYawDeg&&t===this.lookPitchDeg||(this.lookYawDeg=e,this.lookPitchDeg=t,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const e=this.gaitAt(this.currentTime),t=this.lookYawDeg+e.yawDeg,i=this.lookPitchDeg+e.pitchDeg;if(t===0&&i===0)return{x:0,y:0};const n=ti(this.currentSighting,this.currentTime),s=ws.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(t),y:s.angleDegToRadiusPx(i)}}gaitAt(e){return bt.bodyAt(this.currentSighting,e,this.steadyObserver)}mutedState=!1;get muted(){return this.mutedState}set muted(e){e!==this.mutedState&&(this.mutedState=e,!e&&this.volumeState===0&&(this.volumeState=ft.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(e){this.setVolume(e)}setVolume(e){this.volumeState=Math.min(Math.max(e,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.muted=!this.mutedState}updateMuteButton(){ft.setIcon(this.muteButton,this.mutedState?$e.MUTED:$e.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=e,this.muteButton.setAttribute("aria-label",e),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const e=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;ft.setIcon(this.fullscreenButton,e?$e.EXIT_FULLSCREEN:$e.ENTER_FULLSCREEN),this.fullscreenButton.title=e?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Nn(zr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const e=u0(zr.preferencesFor(this),f0);if(e===this.messagesLanguage||e==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=e;const t=await y2(e);this.messagesLanguage===e&&this.applyMessages(t)}messagesLanguage;updateTimeLabelTitles(){const e=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,t=this.canSwitchTimeDisplay?` — ${e}`:"";this.timeStartLabel.title=this.messages.currentPosition+t,this.timeEndLabel.title=this.messages.duration+t,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(e){this.messages=e,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const e=this.currentSighting.event,t=_g(e);this.realDurationMs=t!==void 0&&t>0?t:void 0,this.realStartMs=e.time?Fd(e.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(e){if(this.realDurationMs===void 0)return ul(e);const t=this.currentSighting.timeline.duration,i=t>0&&e<=t?e/t*this.realDurationMs:e;return this.canShowClockTime?Bf(zf(this.realStartMs+i)):ul(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?ul(this.currentSighting.timeline.duration):this.canShowClockTime?Bf(zf(this.realStartMs+this.realDurationMs)):ul(this.realDurationMs)}}function zf(r){const e=new Date(r);return{hour:e.getUTCHours(),minute:e.getUTCMinutes(),second:e.getUTCSeconds()}}function Bf(r){if(r.hour===void 0)return"0:00";const e=t=>String(t).padStart(2,"0");return r.second?`${e(r.hour)}:${e(r.minute??0)}:${e(r.second)}`:`${e(r.hour)}:${e(r.minute??0)}`}function ul(r){const e=Math.round(r/1e3),t=Math.floor(e/60),i=e%60;return`${t}:${String(i).padStart(2,"0")}`}const zd="rr0-ufo";function Hg(){customElements.get(zd)||customElements.define(zd,ft)}const B2="recordingissues";/**
1931
1943
  * @license
1932
1944
  * Copyright 2010-2026 Three.js Authors
1933
1945
  * SPDX-License-Identifier: MIT
@@ -7777,7 +7789,7 @@ void main()
7777
7789
  if (ice <= 0.0) discard;
7778
7790
  gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
7779
7791
  }
7780
- `,transparent:!0,blending:ki,depthWrite:!1,side:Vt,fog:!1}),this.object=new Ce(new ci(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]=zn.toHalfFloat(t[n]),this.texels[i+1]=zn.toHalfFloat(t[n+1]),this.texels[i+2]=zn.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 bi{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=bi.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(bi.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=bi.MAX_CONCURRENT*bi.SEGMENTS*bi.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new lt;t.setAttribute("position",new it(this.positions,3)),t.setAttribute("color",new it(this.colors,3)),t.setDrawRange(0,0),this.object=new Ce(t,new Sn({vertexColors:!0,transparent:!0,blending:ki,depthWrite:!1,fog:!1,side:en})),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=ka.aliveAt(this.meteors,e).slice(0,bi.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const l=ui(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),S=x=>bi.RADIUS*((bi.MIN_HALF_WIDTH_DEG+bi.BRIGHT_HALF_WIDTH_DEG*s.brightness*x)*Math.PI/180);for(let x=1;x<bi.POINTS;x++){const M=(x-1)/bi.SEGMENTS,_=x/bi.SEGMENTS;n=this.pushRibbon(n,g(M),g(_),S(M),S(_),m(M),m(_))}}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=ui(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<bi.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,S)=>g===0?S: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=Ae.relativeOfResponse(Math.max(0,Math.min(1,i)));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,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)*bi.RADIUS,y:(e.y*s+t.y*a)*bi.RADIUS,z:(e.z*s+t.z*a)*bi.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()}}class Ot{constructor(e,t={}){this.size=e,this.span=Math.min(e.lengthM,Math.max(0,t.spanM??e.lengthM)),this.bank=(e.lengthM-this.span)/2,this.deck=Math.min(e.heightM,t.deckThicknessM??Ot.DEFAULT_DECK_THICKNESS_M),this.railHeight=t.railing?.heightM??Ot.DEFAULT_RAILING_HEIGHT_M,this.postSpacing=Math.max(.3,t.railing?.postSpacingM??Ot.DEFAULT_POST_SPACING_M),this.rails=Math.max(0,Math.round(t.railing?.rails??Ot.DEFAULT_RAILS))}static DEFAULT_DECK_THICKNESS_M=1.2;static DEFAULT_RAILING_HEIGHT_M=1.05;static DEFAULT_POST_SPACING_M=1.5;static DEFAULT_RAILS=2;static BANK_SLOPE=1.5;static ABUTMENT_THICKNESS_M=1;static POST_SIDE_M=.08;static RAIL_HEIGHT_M=.08;static RAIL_DEPTH_M=.06;static BANK_STATIONS=12;static NATURAL_SIZE=Object.freeze({widthM:9,lengthM:40,heightM:6.5});span;bank;deck;railHeight;postSpacing;rails;roadAt(e){const t=Math.abs(e)-this.span/2;return t<=0?this.size.heightM:this.bank<=0?0:Math.max(0,this.size.heightM*(1-t/this.bank))}build(){const{widthM:e,heightM:t}=this.size,i=this.span/2,n=[];if(this.span>0){n.push(Ot.box(e,this.deck,this.span,0,t-this.deck/2,0));for(const l of[-1,1]){const c=t-this.deck;c>0&&this.bank>0&&n.push(Ot.box(e+1,c,Ot.ABUTMENT_THICKNESS_M,0,c/2,l*(i-Ot.ABUTMENT_THICKNESS_M/2)))}}const s=[];this.span>0&&s.push(Ot.box(e,.04,this.span,0,t+.02,0));const a=[];for(const l of[-1,1])this.bank<=0||(a.push(this.embankment(l)),s.push(this.bankRoad(l)));const o=[];for(const l of[-1,1])o.push(...this.railing(l*(e/2-Ot.POST_SIDE_M)));return{concrete:Ot.merge(n),road:Ot.merge(s),earth:Ot.merge(a),railing:Ot.merge(o)}}embankment(e){const t=this.size.widthM/2,i=this.stations(e),n=[],s=(c,h,d,u)=>{n.push(c.x,c.y,c.z,h.x,h.y,h.z,d.x,d.y,d.z,c.x,c.y,c.z,d.x,d.y,d.z,u.x,u.y,u.z)},a=c=>{const h=this.roadAt(c),d=t+Ot.BANK_SLOPE*h;return{leftFoot:new R(-d,0,c),leftTop:new R(-t,h,c),rightTop:new R(t,h,c),rightFoot:new R(d,0,c)}};for(let c=1;c<i.length;c++){const h=a(i[c-1]),d=a(i[c]),u=e>0,f=(p,v,m,g)=>u?s(p,v,m,g):s(g,m,v,p);f(h.leftFoot,h.leftTop,d.leftTop,d.leftFoot),f(h.leftTop,h.rightTop,d.rightTop,d.leftTop),f(h.rightTop,h.rightFoot,d.rightFoot,d.rightTop)}const o=a(i[0]);e>0?s(o.leftFoot,o.rightFoot,o.rightTop,o.leftTop):s(o.leftTop,o.rightTop,o.rightFoot,o.leftFoot);const l=new lt;return l.setAttribute("position",new ut(n,3)),l.computeVertexNormals(),l}bankRoad(e){const t=this.size.widthM/2,i=this.stations(e),n=[];for(let a=1;a<i.length;a++){const o=i[a-1],l=i[a],c=this.roadAt(o)+.02,h=this.roadAt(l)+.02,d=e>0?[[-t,c,o],[t,c,o],[t,h,l],[-t,h,l]]:[[-t,h,l],[t,h,l],[t,c,o],[-t,c,o]];for(const u of[0,2,1,0,3,2])n.push(...d[u])}const s=new lt;return s.setAttribute("position",new ut(n,3)),s.computeVertexNormals(),s}stations(e){const t=[];for(let i=0;i<=Ot.BANK_STATIONS;i++)t.push(e*(this.span/2+this.bank*i/Ot.BANK_STATIONS));return t}railing(e){const t=this.size.lengthM/2,i=Math.max(1,Math.round(this.size.lengthM/this.postSpacing)),n=[];for(let o=0;o<=i;o++)n.push(-t+this.size.lengthM*o/i);const s=[],a=Ot.POST_SIDE_M;for(const o of n)s.push(Ot.box(a,this.railHeight,a,e,this.roadAt(o)+this.railHeight/2,o));for(let o=1;o<=this.rails;o++){const l=this.railHeight*o/this.rails-Ot.RAIL_HEIGHT_M/2;for(let c=1;c<n.length;c++){const h=new R(e,this.roadAt(n[c-1])+l,n[c-1]),d=new R(e,this.roadAt(n[c])+l,n[c]);s.push(Ot.beam(h,d))}}return s}static box(e,t,i,n,s,a){return new Yi(e,t,i).translate(n,s,a)}static beam(e,t){const i=new R().subVectors(t,e),n=new Yi(Ot.RAIL_DEPTH_M,Ot.RAIL_HEIGHT_M,i.length()),s=new tn().setFromUnitVectors(new R(0,0,1),i.clone().normalize()),a=new R().addVectors(e,t).multiplyScalar(.5);return n.applyMatrix4(new Je().compose(a,s,new R(1,1,1)))}static merge(e){const t=e.map(l=>l.getIndex()?l.toNonIndexed():l),i=t.reduce((l,c)=>l+c.getAttribute("position").count,0),n=new Float32Array(i*3),s=new Float32Array(i*3);let a=0;for(const l of t){const c=l.getAttribute("position"),h=l.getAttribute("normal");n.set(c.array,a*3),h&&s.set(h.array,a*3),a+=c.count}const o=new lt;o.setAttribute("position",new ut(n,3)),o.setAttribute("normal",new ut(s,3));for(const l of e)l.dispose();for(const l of t)l.dispose();return o}}const od=Math.PI/180;function Ft(r,e,t,i,n=!1){const s=n?new Sn({color:new se(...t)}):new Yr({color:new se(...t)}),a=new Ce(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const ld=.25,B5=.002,H5=100,G5=1500,V5=.25,W5=1e3,X5=.15;function Y5(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 q5=[.32,.32,.3],tv=[1,.85,.5],$5=[.25,.25,.25],iv=[1,.97,.85],K5=[.55,.68,.72],Qn=.03,es=.05,nv={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 Hi(r,e){return r?.[e]}function ts(r,e,t,i,n,s,a,o){if(o===void 0)return;const l=new Yr({color:new se(...K5),transparent:!0,opacity:o/100}),c=new Ce(new Yi(e,t,i),l);c.position.set(n,s,a),r.add(c)}const yn=.05,cd=[.6,.58,.53],wm=[.5,.5,.48];function wr(r,e,t,i,n,s,a,o){const l=new Yr({color:new se(...o),side:Vt}),c=new Ce(new Yi(e,t,i),l);c.position.set(n,s,a),r.add(c)}function Z5(r,e,t,i,n,s,a,o,l){const c=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?wr(r,p,v,yn,m,o+g,a,l):wr(r,yn,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 sv(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?wr(r,v,d,yn,0,h,m,cd):wr(r,yn,d,v,m,h,0,cd):Z5(r,p,v,d,f,s,m,h,cd)};u(a,!0,e*2,-t+yn),u(o,!0,e*2,t-yn),u(l,!1,t*2,-e+yn),u(c,!1,t*2,e-yn),wr(r,e*2,yn,t*2,0,i+yn,0,wm),wr(r,e*2,yn,t*2,0,n-yn,0,wm)}function s0(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:-is};case"front-right":return{x:e-i,z:-is};case"behind-left":return{x:-(e-i),z:is};case"behind-right":return{x:e-i,z:is}}}function av(r,e,t,i,n,s,a){const o=o0();o.scale.setScalar(i),o.rotation.y=nv[e];const{x:l,z:c}=s0(e,n,s,a);o.position.set(l,t,c),r.add(o)}const a0=6,r0=6,Js=3,po=1.4,mo=Js*.5,rv=1.2,ov=.35,J5=.75,j5=1.6;function Em(r,e,t,i){const n=new It,s=Math.max(1,r+1),a=s*Js;Ft(n,new Yi(a0,a,r0),[.55,.54,.5],a/2);const o=a0/2,l=r0/2;for(let c=0;c<s;c++){const h=c*Js+Js/2;ts(n,po,mo,es,0,h,-l-Qn,Hi(e,"front")),ts(n,po,mo,es,0,h,l+Qn,Hi(e,"behind")),ts(n,es,mo,po,-o-Qn,h,0,Hi(e,"left")),ts(n,es,mo,po,o+Qn,h,0,Hi(e,"right"))}if(t){const c=Math.min(Math.max(i??0,0),s-1);av(n,t,c*Js,.72,o,l,rv);const h=d=>Hi(e,d)!==void 0?[{main:po,center:0}]:[];sv(n,o,l,c*Js,(c+1)*Js,mo,h("front"),h("behind"),h("left"),h("right"))}return n}function Am(){const r=new It,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 ci(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),Ft(r,a,[.26,.28,.17],s)}return r}function Q5(r){const e=new It,t=new Ot(fi.sizeOf(r),r.bridge).build();Ft(e,t.concrete,[.6,.6,.58],0);const i=Ft(e,t.road,[.2,.2,.21],0),n=Ft(e,t.earth,[.3,.36,.22],0);for(const s of[i,n])s.material.side=en;return Ft(e,t.railing,[.5,.52,.55],0),e}function Tm(){const r=new It;return Ft(r,new cs(.15,.22,2,8),[.32,.22,.14],1),Ft(r,new Xr(1.4,3,8),[.16,.32,.14],3.5),r}const Rm=.275,eE=.35,tE=.9,iE=34,nE=8,sE=1.4;function Cm(){const r=new It,e=new ci(Rm,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,eE/Rm,1);const t=fi.repeatOnGrid(e,iE,tE,nE,sE),i=Ft(r,t,[.26,.28,.22],0);return i.castShadow=!0,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Dm(){const r=new It,e=new ci(1,7,3,0,Math.PI*2,0,Math.PI/2);return Ft(r,e,[.38,.36,.32],0),r}function Im(r){const e=new It;return Ft(e,new cs(.05,.08,5,8),[.28,.28,.3],2.5),Ft(e,new ci(.25,12,8),r?tv:q5,5.1,!0),e}const aE=[.08,.08,.08],qs=.8,Mr=1,Kn=1.7,hd=.6,ga=.4,Jl=1.2,mr=.7,is=.5,rE=Kn;function Pm(r,e,t){const i=new It;Ft(i,new Yi(1.8,1.4,4.2),[.45,.14,.14],.7),Ft(i,new Yi(qs*2,hd,Mr*2),[.4,.12,.12],Kn);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Ft(i,new cs(.4,.4,.3,12),aE,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?iv:$5;for(const s of[-.7,.7])Ft(i,new ci(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(ts(i,Jl,ga,es,0,Kn,-Mr-Qn,Hi(e,"front")),ts(i,Jl,ga,es,0,Kn,Mr+Qn,Hi(e,"behind")),ts(i,es,ga,mr,-qs-Qn,Kn,-is,Hi(e,"front-left")),ts(i,es,ga,mr,-qs-Qn,Kn,is,Hi(e,"behind-left")),ts(i,es,ga,mr,qs+Qn,Kn,-is,Hi(e,"front-right")),ts(i,es,ga,mr,qs+Qn,Kn,is,Hi(e,"behind-right")),t){av(i,t,J5,.5,qs,Mr,ov);const s=(l,c)=>{const h=[];return Hi(e,l)!==void 0&&h.push({main:mr,center:-is}),Hi(e,c)!==void 0&&h.push({main:mr,center:is}),h},a=Hi(e,"front")!==void 0?[{main:Jl,center:0}]:[],o=Hi(e,"behind")!==void 0?[{main:Jl,center:0}]:[];sv(i,qs,Mr,Kn-hd/2,Kn+hd/2,ga,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Lm=new Map;function Om(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 dd(r,e){return e>1e-6?r/e:1}const lv=[.95,.9,.82],Nm=[.72,.74,.78];function km(){const r=new It;Ft(r,new cs(.25,.3,1.5,10),Nm,.75),Ft(r,new ci(.26,10,8),Nm,1.74);const e=Ft(r,new Xr(.07,.16,8),lv,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function o0(){const r=new It;Ft(r,new cs(.25,.3,1.5,10),[.3,.3,.35],.75),Ft(r,new ci(.22,10,8),[.62,.52,.46],1.72);const e=Ft(r,new Xr(.07,.16,8),lv,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const oE=17,Fm=18.5,ud=[.16,.16,.18];function Um(){const r=new It,e=Ft(r,new cs(1.8,1.8,Fm*2,10),ud,0);e.rotation.x=Math.PI/2,Ft(r,new Yi(oE*2,.5,4.5),ud,0);const t=Ft(r,new Yi(.4,5.5,4),ud,3);return t.position.z=-Fm+2,r}class fi{static GROWS_FROM_GROUND=new Set(["tree","shrub","crop","mound"]);static groundUnderFootprint(e,t,i,n,s,a=0){const o=fi.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)),d=fi.GROWS_FROM_GROUND.has(e.kind);let u=d?1/0:-1/0;for(let f=0;f<c;f++){const p=(f/(c-1)-.5)*o.lengthM;for(let v=0;v<h;v++){const m=(v/(h-1)-.5)*o.widthM,g=t+Math.sin(l)*p+Math.cos(l)*m,S=i-Math.cos(l)*p+Math.sin(l)*m;u=d?Math.min(u,s(g,S)):Math.max(u,s(g,S))}}return Number.isFinite(u)?u:s(t,i)}static occupantView(e){const t=e.observerSide;if(!t)throw new Error("occupantView requires object.observerSide to be set");const{x:i,z:n}=e.kind==="vehicle"?s0(t,qs,Mr,ov):s0(t,a0/2,r0/2,rv),s=e.kind==="vehicle"?rE:(e.occupiedFloor??0)*Js+j5,a=(e.headingDeg??0)-nv[t]/od,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(fi.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 S=0;S<n;S++)for(let x=0;x<t;x++,m++){const M=v+S*s,_=p+x*i;for(let w=0;w<c;w++){const T=(m*c+w)*3;d[T]=a.getX(w)+M,d[T+1]=a.getY(w),d[T+2]=a.getZ(w)+_,u[T]=o.getX(w),u[T+1]=o.getY(w),u[T+2]=o.getZ(w)}for(let w=0;w<l.count;w++)f[m*l.count+w]=l.getX(w)+m*c}const g=new lt;return g.setAttribute("position",new ut(d,3)),g.setAttribute("normal",new ut(u,3)),g.setIndex(new D0(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new R;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 Je().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"?Em(e.floors??vf,e.windows,e.observerSide,e.occupiedFloor):e.kind==="tree"?Tm():e.kind==="shrub"?Am():e.kind==="bridge"?Q5(e):e.kind==="crop"?Cm():e.kind==="mound"?Dm():e.kind==="streetlight"?Im(t):e.kind==="vehicle"?Pm(t,e.windows,e.observerSide):e.kind==="aircraft"?Um():e.kind==="entity"?km():o0();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new It;return i.name=fi.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*od),this.addLights(s,e.lights),s}static scaleFor(e){const t=e.sizeM;if(!t||e.kind==="bridge")return new R(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new R(t.widthM===void 0?1:dd(t.widthM,i.widthM),t.heightM===void 0?1:dd(t.heightM,i.heightM),t.lengthM===void 0?1:dd(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??vf)+1):0;if(e==="bridge")return Ot.NATURAL_SIZE;const n=`${e}:${i}`,s=Lm.get(n);if(s)return s;const a=e==="building"?Em(i-1,void 0,void 0,void 0):e==="tree"?Tm():e==="shrub"?Am():e==="crop"?Cm():e==="mound"?Dm():e==="streetlight"?Im(!1):e==="vehicle"?Pm(!1,void 0,void 0):e==="aircraft"?Um():e==="entity"?km():o0(),o=new Xi().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),Lm.set(n,l),l}static usesModel(e){return e.model!==void 0&&!(e.observerSide!==void 0&&Eg(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new It;a.name=fi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*od,i.updateMatrixWorld(!0);const o=new Xi().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=Om(t.sizeM,l)??Om(n.depictedSizeM,l)??1;i.scale.multiplyScalar(c);const h=o.getCenter(new R).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 Ce&&(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 addLights(e,t){for(const i of t??[]){const n=Y5(i.color),s=Ft(e,new ci(ld,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,a=1,o=B5){if(!t||t.length===0)return;const l=new Map(t.map(u=>[u.id,u])),c=Math.max(1,n*o/ld),h=ld*c,d=a/(Math.PI*h*h);for(const u of e.children){if(!(u instanceof Ce))continue;const f=u.userData.lightId;if(!f)continue;const p=l.get(f);if(!p)continue;const v=s>0?Tg(p,i,i+s):Vv(p,i)?1:0;u.visible=v>0;const m=u.material,g=u.userData.lightColor;if(g){const S=v*H5*(p.intensity??1)*d;m.color.setRGB(g[0]*S,g[1]*S,g[2]*S)}u.scale.setScalar(c)}}static setLit(e,t,i,n=1){const[s,a,o]=t==="streetlight"?[G5,V5,tv]:[W5,X5,iv],l=i?s*n/(Math.PI*a*a):0,c=[o[0]*l,o[1]*l,o[2]*l];e.traverse(h=>{const d=h.userData;!(h instanceof Ce)||!d.emissive||d.lightId||h.material.color.setRGB(...c)})}static dispose(e){e.traverse(t=>{if(!(t instanceof Ce))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const fd="https://ufoathome.org/models/index.json";class lE{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??cE()}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 cE(){const r=`?v=${encodeURIComponent("0.80.0")}`,e=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(e&&e!==fd?[e,fd]:[fd]).map(t=>t+r)}const hE=[{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 lE}];async function zm(r){const{GLTFLoader:e}=await gi(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(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const cv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class dn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(e,t){this.mesh=new Ce(new qi(2,2),new ct({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:dn.VERTEX,fragmentShader:dn.FRAGMENT,transparent:!0,depthWrite:!1,blending:ki,toneMapped:!1})),this.mesh.name=e,this.mesh.frustumCulled=!1,this.mesh.renderOrder=t,this.mesh.visible=!1}shine(e,t,i){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.material.uniforms.uRadius.value=t,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(e,t,i,n){const s=Math.max(e,n*dn.MIN_ANGLE_RAD),a=dn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(dn.MAX_SHARE,t/a)}}static conserving(e){return Math.sqrt(e/(dn.MAX_SHARE*dn.FILL*Math.PI))}static VERTEX=`
7792
+ `,transparent:!0,blending:ki,depthWrite:!1,side:Vt,fog:!1}),this.object=new Ce(new ci(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]=zn.toHalfFloat(t[n]),this.texels[i+1]=zn.toHalfFloat(t[n+1]),this.texels[i+2]=zn.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 bi{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=bi.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(bi.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=bi.MAX_CONCURRENT*bi.SEGMENTS*bi.VERTICES_PER_SEGMENT;this.positions=new Float32Array(e*3),this.colors=new Float32Array(e*3);const t=new lt;t.setAttribute("position",new it(this.positions,3)),t.setAttribute("color",new it(this.colors,3)),t.setDrawRange(0,0),this.object=new Ce(t,new Sn({vertexColors:!0,transparent:!0,blending:ki,depthWrite:!1,fog:!1,side:en})),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=ka.aliveAt(this.meteors,e).slice(0,bi.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:a}of i){const o=this.radiantOf(s);if(!o)continue;const l=ui(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),S=x=>bi.RADIUS*((bi.MIN_HALF_WIDTH_DEG+bi.BRIGHT_HALF_WIDTH_DEG*s.brightness*x)*Math.PI/180);for(let x=1;x<bi.POINTS;x++){const M=(x-1)/bi.SEGMENTS,_=x/bi.SEGMENTS;n=this.pushRibbon(n,g(M),g(_),S(M),S(_),m(M),m(_))}}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=ui(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<bi.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,S)=>g===0?S: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=Ae.relativeOfResponse(Math.max(0,Math.min(1,i)));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,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)*bi.RADIUS,y:(e.y*s+t.y*a)*bi.RADIUS,z:(e.z*s+t.z*a)*bi.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()}}class Ot{constructor(e,t={}){this.size=e,this.span=Math.min(e.lengthM,Math.max(0,t.spanM??e.lengthM)),this.bank=(e.lengthM-this.span)/2,this.deck=Math.min(e.heightM,t.deckThicknessM??Ot.DEFAULT_DECK_THICKNESS_M),this.railHeight=t.railing?.heightM??Ot.DEFAULT_RAILING_HEIGHT_M,this.postSpacing=Math.max(.3,t.railing?.postSpacingM??Ot.DEFAULT_POST_SPACING_M),this.rails=Math.max(0,Math.round(t.railing?.rails??Ot.DEFAULT_RAILS))}static DEFAULT_DECK_THICKNESS_M=1.2;static DEFAULT_RAILING_HEIGHT_M=1.05;static DEFAULT_POST_SPACING_M=1.5;static DEFAULT_RAILS=2;static BANK_SLOPE=1.5;static ABUTMENT_THICKNESS_M=1;static POST_SIDE_M=.08;static RAIL_HEIGHT_M=.08;static RAIL_DEPTH_M=.06;static BANK_STATIONS=12;static NATURAL_SIZE=Object.freeze({widthM:9,lengthM:40,heightM:6.5});span;bank;deck;railHeight;postSpacing;rails;roadAt(e){const t=Math.abs(e)-this.span/2;return t<=0?this.size.heightM:this.bank<=0?0:Math.max(0,this.size.heightM*(1-t/this.bank))}build(){const{widthM:e,heightM:t}=this.size,i=this.span/2,n=[];if(this.span>0){n.push(Ot.box(e,this.deck,this.span,0,t-this.deck/2,0));for(const l of[-1,1]){const c=t-this.deck;c>0&&this.bank>0&&n.push(Ot.box(e+1,c,Ot.ABUTMENT_THICKNESS_M,0,c/2,l*(i-Ot.ABUTMENT_THICKNESS_M/2)))}}const s=[];this.span>0&&s.push(Ot.box(e,.04,this.span,0,t+.02,0));const a=[];for(const l of[-1,1])this.bank<=0||(a.push(this.embankment(l)),s.push(this.bankRoad(l)));const o=[];for(const l of[-1,1])o.push(...this.railing(l*(e/2-Ot.POST_SIDE_M)));return{concrete:Ot.merge(n),road:Ot.merge(s),earth:Ot.merge(a),railing:Ot.merge(o)}}embankment(e){const t=this.size.widthM/2,i=this.stations(e),n=[],s=(c,h,d,u)=>{n.push(c.x,c.y,c.z,h.x,h.y,h.z,d.x,d.y,d.z,c.x,c.y,c.z,d.x,d.y,d.z,u.x,u.y,u.z)},a=c=>{const h=this.roadAt(c),d=t+Ot.BANK_SLOPE*h;return{leftFoot:new R(-d,0,c),leftTop:new R(-t,h,c),rightTop:new R(t,h,c),rightFoot:new R(d,0,c)}};for(let c=1;c<i.length;c++){const h=a(i[c-1]),d=a(i[c]),u=e>0,f=(p,v,m,g)=>u?s(p,v,m,g):s(g,m,v,p);f(h.leftFoot,h.leftTop,d.leftTop,d.leftFoot),f(h.leftTop,h.rightTop,d.rightTop,d.leftTop),f(h.rightTop,h.rightFoot,d.rightFoot,d.rightTop)}const o=a(i[0]);e>0?s(o.leftFoot,o.rightFoot,o.rightTop,o.leftTop):s(o.leftTop,o.rightTop,o.rightFoot,o.leftFoot);const l=new lt;return l.setAttribute("position",new ut(n,3)),l.computeVertexNormals(),l}bankRoad(e){const t=this.size.widthM/2,i=this.stations(e),n=[];for(let a=1;a<i.length;a++){const o=i[a-1],l=i[a],c=this.roadAt(o)+.02,h=this.roadAt(l)+.02,d=e>0?[[-t,c,o],[t,c,o],[t,h,l],[-t,h,l]]:[[-t,h,l],[t,h,l],[t,c,o],[-t,c,o]];for(const u of[0,2,1,0,3,2])n.push(...d[u])}const s=new lt;return s.setAttribute("position",new ut(n,3)),s.computeVertexNormals(),s}stations(e){const t=[];for(let i=0;i<=Ot.BANK_STATIONS;i++)t.push(e*(this.span/2+this.bank*i/Ot.BANK_STATIONS));return t}railing(e){const t=this.size.lengthM/2,i=Math.max(1,Math.round(this.size.lengthM/this.postSpacing)),n=[];for(let o=0;o<=i;o++)n.push(-t+this.size.lengthM*o/i);const s=[],a=Ot.POST_SIDE_M;for(const o of n)s.push(Ot.box(a,this.railHeight,a,e,this.roadAt(o)+this.railHeight/2,o));for(let o=1;o<=this.rails;o++){const l=this.railHeight*o/this.rails-Ot.RAIL_HEIGHT_M/2;for(let c=1;c<n.length;c++){const h=new R(e,this.roadAt(n[c-1])+l,n[c-1]),d=new R(e,this.roadAt(n[c])+l,n[c]);s.push(Ot.beam(h,d))}}return s}static box(e,t,i,n,s,a){return new Yi(e,t,i).translate(n,s,a)}static beam(e,t){const i=new R().subVectors(t,e),n=new Yi(Ot.RAIL_DEPTH_M,Ot.RAIL_HEIGHT_M,i.length()),s=new tn().setFromUnitVectors(new R(0,0,1),i.clone().normalize()),a=new R().addVectors(e,t).multiplyScalar(.5);return n.applyMatrix4(new Je().compose(a,s,new R(1,1,1)))}static merge(e){const t=e.map(l=>l.getIndex()?l.toNonIndexed():l),i=t.reduce((l,c)=>l+c.getAttribute("position").count,0),n=new Float32Array(i*3),s=new Float32Array(i*3);let a=0;for(const l of t){const c=l.getAttribute("position"),h=l.getAttribute("normal");n.set(c.array,a*3),h&&s.set(h.array,a*3),a+=c.count}const o=new lt;o.setAttribute("position",new ut(n,3)),o.setAttribute("normal",new ut(s,3));for(const l of e)l.dispose();for(const l of t)l.dispose();return o}}const od=Math.PI/180;function Ft(r,e,t,i,n=!1){const s=n?new Sn({color:new se(...t)}):new Yr({color:new se(...t)}),a=new Ce(e,s);return a.position.y=i,a.userData={emissive:n},a.castShadow=!n,a.receiveShadow=!n,r.add(a),a}const ld=.25,B5=.002,H5=100,G5=1500,V5=.25,W5=1e3,X5=.15;function Y5(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 q5=[.32,.32,.3],tv=[1,.85,.5],$5=[.25,.25,.25],iv=[1,.97,.85],K5=[.55,.68,.72],Qn=.03,es=.05,nv={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 Hi(r,e){return r?.[e]}function ts(r,e,t,i,n,s,a,o){if(o===void 0)return;const l=new Yr({color:new se(...K5),transparent:!0,opacity:o/100}),c=new Ce(new Yi(e,t,i),l);c.position.set(n,s,a),r.add(c)}const yn=.05,cd=[.6,.58,.53],wm=[.5,.5,.48];function wr(r,e,t,i,n,s,a,o){const l=new Yr({color:new se(...o),side:Vt}),c=new Ce(new Yi(e,t,i),l);c.position.set(n,s,a),r.add(c)}function Z5(r,e,t,i,n,s,a,o,l){const c=(i-s)/2,h=(p,v,m,g)=>{p<=0||(e?wr(r,p,v,yn,m,o+g,a,l):wr(r,yn,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 sv(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?wr(r,v,d,yn,0,h,m,cd):wr(r,yn,d,v,m,h,0,cd):Z5(r,p,v,d,f,s,m,h,cd)};u(a,!0,e*2,-t+yn),u(o,!0,e*2,t-yn),u(l,!1,t*2,-e+yn),u(c,!1,t*2,e-yn),wr(r,e*2,yn,t*2,0,i+yn,0,wm),wr(r,e*2,yn,t*2,0,n-yn,0,wm)}function s0(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:-is};case"front-right":return{x:e-i,z:-is};case"behind-left":return{x:-(e-i),z:is};case"behind-right":return{x:e-i,z:is}}}function av(r,e,t,i,n,s,a){const o=o0();o.scale.setScalar(i),o.rotation.y=nv[e];const{x:l,z:c}=s0(e,n,s,a);o.position.set(l,t,c),r.add(o)}const a0=6,r0=6,Js=3,po=1.4,mo=Js*.5,rv=1.2,ov=.35,J5=.75,j5=1.6;function Em(r,e,t,i){const n=new It,s=Math.max(1,r+1),a=s*Js;Ft(n,new Yi(a0,a,r0),[.55,.54,.5],a/2);const o=a0/2,l=r0/2;for(let c=0;c<s;c++){const h=c*Js+Js/2;ts(n,po,mo,es,0,h,-l-Qn,Hi(e,"front")),ts(n,po,mo,es,0,h,l+Qn,Hi(e,"behind")),ts(n,es,mo,po,-o-Qn,h,0,Hi(e,"left")),ts(n,es,mo,po,o+Qn,h,0,Hi(e,"right"))}if(t){const c=Math.min(Math.max(i??0,0),s-1);av(n,t,c*Js,.72,o,l,rv);const h=d=>Hi(e,d)!==void 0?[{main:po,center:0}]:[];sv(n,o,l,c*Js,(c+1)*Js,mo,h("front"),h("behind"),h("left"),h("right"))}return n}function Am(){const r=new It,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 ci(n,10,7);a.scale(1,.85,1),a.translate(t,0,i),Ft(r,a,[.26,.28,.17],s)}return r}function Q5(r){const e=new It,t=new Ot(fi.sizeOf(r),r.bridge).build();Ft(e,t.concrete,[.6,.6,.58],0);const i=Ft(e,t.road,[.2,.2,.21],0),n=Ft(e,t.earth,[.3,.36,.22],0);for(const s of[i,n])s.material.side=en;return Ft(e,t.railing,[.5,.52,.55],0),e}function Tm(){const r=new It;return Ft(r,new cs(.15,.22,2,8),[.32,.22,.14],1),Ft(r,new Xr(1.4,3,8),[.16,.32,.14],3.5),r}const Rm=.275,eE=.35,tE=.9,iE=34,nE=8,sE=1.4;function Cm(){const r=new It,e=new ci(Rm,7,3,0,Math.PI*2,0,Math.PI/2);e.scale(1,eE/Rm,1);const t=fi.repeatOnGrid(e,iE,tE,nE,sE),i=Ft(r,t,[.26,.28,.22],0);return i.castShadow=!0,i.userData.cropBasePositions=t.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=e.getAttribute("position").count,e.dispose(),r}function Dm(){const r=new It,e=new ci(1,7,3,0,Math.PI*2,0,Math.PI/2);return Ft(r,e,[.38,.36,.32],0),r}function Im(r){const e=new It;return Ft(e,new cs(.05,.08,5,8),[.28,.28,.3],2.5),Ft(e,new ci(.25,12,8),r?tv:q5,5.1,!0),e}const aE=[.08,.08,.08],qs=.8,Mr=1,Kn=1.7,hd=.6,ga=.4,Jl=1.2,mr=.7,is=.5,rE=Kn;function Pm(r,e,t){const i=new It;Ft(i,new Yi(1.8,1.4,4.2),[.45,.14,.14],.7),Ft(i,new Yi(qs*2,hd,Mr*2),[.4,.12,.12],Kn);for(const s of[-1.4,1.4])for(const a of[-.95,.95]){const o=Ft(i,new cs(.4,.4,.3,12),aE,.4);o.rotation.z=Math.PI/2,o.position.x=a,o.position.z=s}const n=r?iv:$5;for(const s of[-.7,.7])Ft(i,new ci(.15,8,6),n,.7,!0).position.set(s,.7,-2.1);if(ts(i,Jl,ga,es,0,Kn,-Mr-Qn,Hi(e,"front")),ts(i,Jl,ga,es,0,Kn,Mr+Qn,Hi(e,"behind")),ts(i,es,ga,mr,-qs-Qn,Kn,-is,Hi(e,"front-left")),ts(i,es,ga,mr,-qs-Qn,Kn,is,Hi(e,"behind-left")),ts(i,es,ga,mr,qs+Qn,Kn,-is,Hi(e,"front-right")),ts(i,es,ga,mr,qs+Qn,Kn,is,Hi(e,"behind-right")),t){av(i,t,J5,.5,qs,Mr,ov);const s=(l,c)=>{const h=[];return Hi(e,l)!==void 0&&h.push({main:mr,center:-is}),Hi(e,c)!==void 0&&h.push({main:mr,center:is}),h},a=Hi(e,"front")!==void 0?[{main:Jl,center:0}]:[],o=Hi(e,"behind")!==void 0?[{main:Jl,center:0}]:[];sv(i,qs,Mr,Kn-hd/2,Kn+hd/2,ga,a,o,s("front-left","behind-left"),s("front-right","behind-right"))}return i}const Lm=new Map;function Om(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 dd(r,e){return e>1e-6?r/e:1}const lv=[.95,.9,.82],Nm=[.72,.74,.78];function km(){const r=new It;Ft(r,new cs(.25,.3,1.5,10),Nm,.75),Ft(r,new ci(.26,10,8),Nm,1.74);const e=Ft(r,new Xr(.07,.16,8),lv,1.74);return e.rotation.x=-Math.PI/2,e.position.z=-.22,r}function o0(){const r=new It;Ft(r,new cs(.25,.3,1.5,10),[.3,.3,.35],.75),Ft(r,new ci(.22,10,8),[.62,.52,.46],1.72);const e=Ft(r,new Xr(.07,.16,8),lv,1.72);return e.rotation.x=-Math.PI/2,e.position.z=-.2,r}const oE=17,Fm=18.5,ud=[.16,.16,.18];function Um(){const r=new It,e=Ft(r,new cs(1.8,1.8,Fm*2,10),ud,0);e.rotation.x=Math.PI/2,Ft(r,new Yi(oE*2,.5,4.5),ud,0);const t=Ft(r,new Yi(.4,5.5,4),ud,3);return t.position.z=-Fm+2,r}class fi{static GROWS_FROM_GROUND=new Set(["tree","shrub","crop","mound"]);static groundUnderFootprint(e,t,i,n,s,a=0){const o=fi.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)),d=fi.GROWS_FROM_GROUND.has(e.kind);let u=d?1/0:-1/0;for(let f=0;f<c;f++){const p=(f/(c-1)-.5)*o.lengthM;for(let v=0;v<h;v++){const m=(v/(h-1)-.5)*o.widthM,g=t+Math.sin(l)*p+Math.cos(l)*m,S=i-Math.cos(l)*p+Math.sin(l)*m;u=d?Math.min(u,s(g,S)):Math.max(u,s(g,S))}}return Number.isFinite(u)?u:s(t,i)}static occupantView(e){const t=e.observerSide;if(!t)throw new Error("occupantView requires object.observerSide to be set");const{x:i,z:n}=e.kind==="vehicle"?s0(t,qs,Mr,ov):s0(t,a0/2,r0/2,rv),s=e.kind==="vehicle"?rE:(e.occupiedFloor??0)*Js+j5,a=(e.headingDeg??0)-nv[t]/od,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(fi.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 S=0;S<n;S++)for(let x=0;x<t;x++,m++){const M=v+S*s,_=p+x*i;for(let w=0;w<c;w++){const T=(m*c+w)*3;d[T]=a.getX(w)+M,d[T+1]=a.getY(w),d[T+2]=a.getZ(w)+_,u[T]=o.getX(w),u[T+1]=o.getY(w),u[T+2]=o.getZ(w)}for(let w=0;w<l.count;w++)f[m*l.count+w]=l.getX(w)+m*c}const g=new lt;return g.setAttribute("position",new ut(d,3)),g.setAttribute("normal",new ut(u,3)),g.setIndex(new D0(f,1)),g}static fitCropToGround(e,t){e.updateMatrixWorld(!0);const i=new R;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 Je().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"?Em(e.floors??vf,e.windows,e.observerSide,e.occupiedFloor):e.kind==="tree"?Tm():e.kind==="shrub"?Am():e.kind==="bridge"?Q5(e):e.kind==="crop"?Cm():e.kind==="mound"?Dm():e.kind==="streetlight"?Im(t):e.kind==="vehicle"?Pm(t,e.windows,e.observerSide):e.kind==="aircraft"?Um():e.kind==="entity"?km():o0();e.color&&this.paint(i,e.color);const n=this.scaleFor(e),s=new It;return i.name=fi.BODY_NAME,i.scale.copy(n),s.add(i),e.headingDeg!==void 0&&(s.rotation.y=-e.headingDeg*od),this.addLights(s,e.lights),s}static scaleFor(e){const t=e.sizeM;if(!t||e.kind==="bridge")return new R(1,1,1);const i=this.naturalSize(e.kind,e.floors);return new R(t.widthM===void 0?1:dd(t.widthM,i.widthM),t.heightM===void 0?1:dd(t.heightM,i.heightM),t.lengthM===void 0?1:dd(t.lengthM,i.lengthM))}static naturalSize(e,t){const i=e==="building"?Math.max(1,(t??vf)+1):0;if(e==="bridge")return Ot.NATURAL_SIZE;const n=`${e}:${i}`,s=Lm.get(n);if(s)return s;const a=e==="building"?Em(i-1,void 0,void 0,void 0):e==="tree"?Tm():e==="shrub"?Am():e==="crop"?Cm():e==="mound"?Dm():e==="streetlight"?Im(!1):e==="vehicle"?Pm(!1,void 0,void 0):e==="aircraft"?Um():e==="entity"?km():o0(),o=new Xi().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),Lm.set(n,l),l}static usesModel(e){return e.model!==void 0&&!(e.observerSide!==void 0&&Eg(e.kind))}static applyModel(e,t,i,n={}){const s=this.bodyOf(e),a=new It;a.name=fi.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*od,i.updateMatrixWorld(!0);const o=new Xi().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=Om(t.sizeM,l)??Om(n.depictedSizeM,l)??1;i.scale.multiplyScalar(c);const h=o.getCenter(new R).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 Ce&&(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 addLights(e,t){for(const i of t??[]){const n=Y5(i.color),s=Ft(e,new ci(ld,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,a=1,o=B5){if(!t||t.length===0)return;const l=new Map(t.map(u=>[u.id,u])),c=Math.max(1,n*o/ld),h=ld*c,d=a/(Math.PI*h*h);for(const u of e.children){if(!(u instanceof Ce))continue;const f=u.userData.lightId;if(!f)continue;const p=l.get(f);if(!p)continue;const v=s>0?Tg(p,i,i+s):Vv(p,i)?1:0;u.visible=v>0;const m=u.material,g=u.userData.lightColor;if(g){const S=v*H5*(p.intensity??1)*d;m.color.setRGB(g[0]*S,g[1]*S,g[2]*S)}u.scale.setScalar(c)}}static setLit(e,t,i,n=1){const[s,a,o]=t==="streetlight"?[G5,V5,tv]:[W5,X5,iv],l=i?s*n/(Math.PI*a*a):0,c=[o[0]*l,o[1]*l,o[2]*l];e.traverse(h=>{const d=h.userData;!(h instanceof Ce)||!d.emissive||d.lightId||h.material.color.setRGB(...c)})}static dispose(e){e.traverse(t=>{if(!(t instanceof Ce))return;t.geometry.dispose();const i=t.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const fd="https://ufoathome.org/models/index.json";class lE{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??cE()}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 cE(){const r=`?v=${encodeURIComponent("0.80.1")}`,e=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(e&&e!==fd?[e,fd]:[fd]).map(t=>t+r)}const hE=[{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 lE}];async function zm(r){const{GLTFLoader:e}=await gi(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(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${r}: ${s instanceof Error?s.message:String(s)}`)))})}const cv=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class dn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(e,t){this.mesh=new Ce(new qi(2,2),new ct({uniforms:{uColor:{value:new se(0,0,0)},uRadius:{value:1}},vertexShader:dn.VERTEX,fragmentShader:dn.FRAGMENT,transparent:!0,depthWrite:!1,blending:ki,toneMapped:!1})),this.mesh.name=e,this.mesh.frustumCulled=!1,this.mesh.renderOrder=t,this.mesh.visible=!1}shine(e,t,i){this.mesh.visible=!0,this.mesh.position.set(e.x,e.y,e.z),this.mesh.material.uniforms.uRadius.value=t,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(e,t,i,n){const s=Math.max(e,n*dn.MIN_ANGLE_RAD),a=dn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(dn.MAX_SHARE,t/a)}}static conserving(e){return Math.sqrt(e/(dn.MAX_SHARE*dn.FILL*Math.PI))}static VERTEX=`
7781
7793
  uniform float uRadius;
7782
7794
  varying vec2 vOffset;
7783
7795
  void main() {
@@ -8406,6 +8418,6 @@ void main() {
8406
8418
  gl_FragColor = vec4(color, tex.a * uOpacity * (1.0 - blur * 0.5));
8407
8419
  }
8408
8420
  `;function pg(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="#010101",l="#f4f1e2";i.fillStyle=o,i.beginPath(),i.arc(s,a,n,0,Math.PI*2),i.fill();const c=Er(r.illuminatedFraction,0,1),h=r.phaseFraction<.5,d=n*Math.abs(1-2*c),u=c<.5;return i.save(),i.beginPath(),i.arc(s,a,n,0,Math.PI*2),i.clip(),i.fillStyle=l,i.beginPath(),h?(i.arc(s,a,n,-Math.PI/2,Math.PI/2,!1),i.ellipse(s,a,d,n,0,Math.PI/2,-Math.PI/2,u)):(i.arc(s,a,n,Math.PI/2,-Math.PI/2,!1),i.ellipse(s,a,d,n,0,-Math.PI/2,Math.PI/2,u)),i.fill(),i.restore(),new Os(t)}function rA(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 Os(e)}function Td(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}}class Xc{constructor(e,t){this.source=e,this.create=t}scene;wanted;pumping=!1;disposed=!1;static PATIENCE_FRAMES=600;static SCENE_WIDTH_PX=320;paint(e,t){this.disposed||(this.wanted={t:e,canvas:t},this.pumping||this.pump())}recordingChanged(e){this.scene&&(this.scene.sightingData=e)}dispose(){this.disposed=!0,this.scene?.remove(),this.scene=void 0}ensureScene(){if(this.scene)return this.scene;const e=this.create();return e.setAttribute("max-pixel-ratio","1"),Object.assign(e.style,{position:"fixed",left:"-10000px",top:"0",width:`${Xc.SCENE_WIDTH_PX}px`,visibility:"hidden",pointerEvents:"none"}),document.body.appendChild(e),e.documentUrl=this.source.documentUrl,e.accountInTheRound=this.source.accountInTheRound,e.sightingData=this.source.sightingData,this.scene=e,e}async pump(){this.pumping=!0;try{for(;this.wanted&&!this.disposed;){const{t:e,canvas:t}=this.wanted;this.wanted=void 0;const i=this.ensureScene();i.interpretation!==this.source.interpretation&&(i.interpretation=this.source.interpretation),i.compareAccount!==this.source.compareAccount&&(i.compareAccount=this.source.compareAccount),i.showAt(e);for(let n=0;n<Xc.PATIENCE_FRAMES&&!this.wanted&&!this.disposed&&(await new Promise(s=>requestAnimationFrame(()=>s())),!this.wanted);n++)if(i.snapshotTo(t)){t.dataset.ready="true";break}}}finally{this.pumping=!1}}}const Rd=7.5,Cd=9;class Zn{static cache=new Map;static load(e){let t=Zn.cache.get(e);return t||(t=fetch(e).then(i=>i.arrayBuffer()).then(i=>Zn.parse(i)),Zn.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 Zn.load(e[0].url);const n=i.map(a=>a.url).join(`
8409
- `);let s=Zn.cache.get(n);return s||(s=Promise.all(i.map(a=>Zn.load(a.url))).then(a=>a.reduce((o,l)=>Zn.concat(o,l))),Zn.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)}}}class Yc{constructor(e){this.names=e}body(e,t){return this.names?.bodies[e]??t}star(e){return this.names?.stars[e.name]??e.name}comet(e){return this.names?.comets[e.id]??e.name}nova(e){return this.names?.novae[e.id]??e.name}satelliteClass(e){return this.names?.satelliteClasses[e.id]??e.name}shower(e){return this.names?.showers[e.id]??e.name}lightRig(e){return this.names?.lightRigs[e.id]??e.name}instrument(e){return this.names?.instruments[e.id]??e.name}decorKind(e,t){return this.names?.decorKinds[e]??t}point(e){return Na.point(e,this.names?.compassPoints)}towards(e){return Na.towards(e,this.names)}}const oA=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,lA=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,cA=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,hA=20,dA=1;class uA{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};level=1;master;output(e){return this.master||(this.master=e.createGain(),this.master.gain.value=this.level,this.master.connect(e.destination)),this.master}setLevel(e){this.level=e,this.master&&(this.master.gain.value=e)}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}}Oa.unlock(this.context)}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(oA,this.ambientVolume).then(o=>this.applyIfCurrent(o,a,()=>this.ambientToken,l=>{this.ambientSource=l?.source,this.ambientGain=l?.gain,l&&(l.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(i/hA,1);const s=i>dA;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(lA,this.windVolume).then(o=>this.applyIfCurrent(o,a,()=>this.windToken,l=>{this.windSource=l?.source,this.windGain=l?.gain,l&&(l.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(cA,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear()}applyIfCurrent(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(this.output(i)),s.start(),{source:s,gain:a}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(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(this.output(i)),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 ys{constructor(e){this.elements=e;const{eccentricity:t,perihelionAu:i}=e,[n,s]=this.perifocalAxes(),a=Math.sqrt(ys.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*ys.stumpffC(n),o=t-i*i*i/Math.sqrt(ys.SUN_GM_AU3_PER_DAY2)*ys.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(ys.SUN_GM_AU3_PER_DAY2)*Math.abs(e),n=o=>{const l=this.inverseSemiMajorAxis*o*o,c=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*c)*o*o*o*ys.stumpffS(l)+c*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let a=0;for(let o=0;o<ys.MAX_ITERATIONS&&s-a>1e-13*Math.max(1,s);o++){const l=(a+s)/2;n(l)<i?a=l:s=l}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),l=Math.cos(i),c=Math.sin(i);return[{x:n*a-s*o*l,y:s*a+n*o*l,z:o*c},{x:-n*o-s*a*l,y:-s*o+n*a*l,z:a*c}]}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 uv=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672960498922706,perihelionAu:.5872100477652511,inclinationDeg:162.218798367122,ascendingNodeDeg:58.56208298700436,argumentOfPerihelionDeg:111.7366940639061,perihelionJd:2.4187816784171113e6},peakMagnitude:0,peakOn:"1910-05-20",absoluteMagnitude:4.72,activityExponent:4,tailLengthDeg:100,tailLengthAu:.1638,note:"Passed 0.15 au from Earth on 20 May 1910, and the Earth crossed the outer tail the day before — the apparition that produced a genuine public panic."},{id:"brooks-1911",designation:"C/1911 O1",name:"Comet Brooks",orbit:{eccentricity:.9876404970138669,perihelionAu:.4898172916113738,inclinationDeg:33.34043866978714,ascendingNodeDeg:293.7022074981857,argumentOfPerihelionDeg:153.5578007321686,perihelionJd:2.4193378856140426e6},peakMagnitude:2,peakOn:"1911-10-25",absoluteMagnitude:5.59,activityExponent:4},{id:"skjellerup-maristany-1927",designation:"C/1927 X1",name:"Comet Skjellerup-Maristany",orbit:{eccentricity:.999839726885059,perihelionAu:.1761569619628186,inclinationDeg:85.1125991950808,ascendingNodeDeg:78.24360172472711,argumentOfPerihelionDeg:47.15877857390136,perihelionJd:2.4252326808989984e6},peakMagnitude:-6,peakOn:"1927-12-15",absoluteMagnitude:1.19,activityExponent:4,note:"One of the few comets of the century seen in full daylight."},{id:"de-kock-paraskevopoulos-1941",designation:"C/1941 B2",name:"Comet de Kock-Paraskevopoulos",orbit:{eccentricity:.9991026715181549,perihelionAu:.7900329662827822,inclinationDeg:168.2039226531089,ascendingNodeDeg:43.10609347214336,argumentOfPerihelionDeg:268.6990344196369,perihelionJd:2430022157765061e-9},peakMagnitude:2,peakOn:"1941-02-05",absoluteMagnitude:5.01,activityExponent:4},{id:"southern-1947",designation:"C/1947 X1",name:"the Southern Comet",orbit:{eccentricity:.9998424430916737,perihelionAu:.1100045955093761,inclinationDeg:138.5113919632757,ascendingNodeDeg:337.3114969669252,argumentOfPerihelionDeg:196.1820121395961,perihelionJd:2.4325220864727003e6},peakMagnitude:-3,peakOn:"1947-12-08",absoluteMagnitude:3.01,activityExponent:4,note:"A bright southern-hemisphere comet of December 1947, the month the American sighting wave of that year was still being argued over."},{id:"eclipse-1948",designation:"C/1948 V1",name:"the Eclipse Comet",orbit:{eccentricity:.9999130678247334,perihelionAu:.1354437057263306,inclinationDeg:23.11668597152911,ascendingNodeDeg:211.0454985994762,argumentOfPerihelionDeg:107.2474157073104,perihelionJd:2.4328519265329437e6},peakMagnitude:-2,peakOn:"1948-11-01",absoluteMagnitude:4.79,activityExponent:4,note:"Found during the total solar eclipse of 1 November 1948, which is how a comet that bright had gone unnoticed: it had been hidden in the Sun's glare."},{id:"arend-roland-1957",designation:"C/1956 R1",name:"Comet Arend-Roland",orbit:{eccentricity:1.0002570255357,perihelionAu:.3160532361485914,inclinationDeg:119.9440863251822,ascendingNodeDeg:215.8548157717755,argumentOfPerihelionDeg:308.775920364167,perihelionJd:2.4359365327396123e6},peakMagnitude:.5,peakOn:"1957-04-25",absoluteMagnitude:3.96,activityExponent:4,note:"Showed a spike pointing back TOWARD the Sun in late April 1957 — a real anti-tail, and much reported at the time."},{id:"mrkos-1957",designation:"C/1957 P1",name:"Comet Mrkos",orbit:{eccentricity:.9993521583504134,perihelionAu:.3549238508212375,inclinationDeg:93.9433042053929,ascendingNodeDeg:68.32441518619923,argumentOfPerihelionDeg:40.31823675802871,perihelionJd:243605193752228e-8},peakMagnitude:1,peakOn:"1957-08-05",absoluteMagnitude:5.07,activityExponent:4,note:"The second bright naked-eye comet of 1957, four months after Arend-Roland."},{id:"seki-lines-1962",designation:"C/1962 C1",name:"Comet Seki-Lines",orbit:{eccentricity:1.000003791331562,perihelionAu:.03139689112215131,inclinationDeg:65.01487186102287,ascendingNodeDeg:304.6776602796538,argumentOfPerihelionDeg:11.47295326312573,perihelionJd:2437756163010178e-9},peakMagnitude:-2.5,peakOn:"1962-04-01",absoluteMagnitude:9.3,activityExponent:4},{id:"ikeya-seki-1965",designation:"C/1965 S1",name:"Comet Ikeya-Seki",orbit:{eccentricity:.9999141178248997,perihelionAu:.007785966366889336,inclinationDeg:141.8642315267051,ascendingNodeDeg:346.9951764632611,argumentOfPerihelionDeg:69.04909813996062,perihelionJd:2.4390546837018197e6},peakMagnitude:-10,peakOn:"1965-10-21",alsoRecordedMagnitude:2,alsoRecordedOn:"1965-10-30",absoluteMagnitude:5.26,activityExponent:4.002,tailLengthDeg:25,tailLengthAu:.5048,note:"A sungrazer that passed 450 000 km above the Sun's surface and was seen beside it in broad daylight — the brightest comet of the twentieth century. It then stood in the dawn sky for a fortnight with a tail some 25 degrees long, which is the second magnitude recorded here."},{id:"bennett-1970",designation:"C/1969 Y1",name:"Comet Bennett",orbit:{eccentricity:.9962979048768408,perihelionAu:.5376209981502136,inclinationDeg:90.03975717147327,ascendingNodeDeg:224.6576652531314,argumentOfPerihelionDeg:354.1494209173161,perihelionJd:2.4406655455270996e6},peakMagnitude:0,peakOn:"1970-03-26",absoluteMagnitude:3.36,activityExponent:4},{id:"white-ortiz-bolelli-1970",designation:"C/1970 K1",name:"Comet White-Ortiz-Bolelli",orbit:{eccentricity:.9999488875801225,perihelionAu:.00884411465256722,inclinationDeg:138.9520738221631,ascendingNodeDeg:336.8194095816687,argumentOfPerihelionDeg:61.10224765396615,perihelionJd:2.4407209807728203e6},peakMagnitude:1,peakOn:"1970-05-22",absoluteMagnitude:4.35,activityExponent:4},{id:"kohoutek-1973",designation:"C/1973 E1",name:"Comet Kohoutek",orbit:{eccentricity:1.000007152175185,perihelionAu:.1424250377812859,inclinationDeg:14.30414984159355,ascendingNodeDeg:258.4893339663974,argumentOfPerihelionDeg:37.79772760699667,perihelionJd:2442044930687027e-9},peakMagnitude:0,peakOn:"1974-01-05",absoluteMagnitude:4.89,activityExponent:4,note:"Announced in advance as the comet of the century and remembered for disappointing: it was an ordinary naked-eye object, not the spectacle the press had promised."},{id:"west-1976",designation:"C/1975 V1",name:"Comet West",orbit:{eccentricity:1.000017859625611,perihelionAu:.1966006188461085,inclinationDeg:43.07319920579427,ascendingNodeDeg:118.9189245655447,argumentOfPerihelionDeg:358.4315101259072,perihelionJd:2442833721841768e-9},peakMagnitude:-3,peakOn:"1976-02-25",absoluteMagnitude:4.41,activityExponent:4,tailLengthDeg:30,tailLengthAu:.4325,note:"Broke into four pieces at perihelion. Barely reported at the time — the press had been burned by Kohoutek two years earlier."},{id:"iras-araki-alcock-1983",designation:"C/1983 H1",name:"Comet IRAS-Araki-Alcock",orbit:{eccentricity:.9898409731606003,perihelionAu:.9913412593828502,inclinationDeg:73.25000846947029,ascendingNodeDeg:49.10235754476374,argumentOfPerihelionDeg:192.8506176754439,perihelionJd:2.4454757545235856e6},peakMagnitude:1.7,peakOn:"1983-05-11",absoluteMagnitude:9.04,activityExponent:4,note:"Passed 0.031 au from Earth on 11 May 1983, one of the closest cometary approaches on record: it crossed a quarter of the sky in a night, which no other comet in this list did."},{id:"halley-1986",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672792271749998,perihelionAu:.5871034488173393,inclinationDeg:162.2422242700916,ascendingNodeDeg:58.85993640671803,argumentOfPerihelionDeg:111.8655480539208,perihelionJd:2.4464709589610207e6},peakMagnitude:2.1,peakOn:"1986-03-10",absoluteMagnitude:2.71,activityExponent:4,note:"The worst-placed return in two thousand years — famous, expected, and for most observers a faint smudge."},{id:"hyakutake-1996",designation:"C/1996 B2",name:"Comet Hyakutake",orbit:{eccentricity:.9997295133739305,perihelionAu:.2302272039470452,inclinationDeg:124.923592343765,ascendingNodeDeg:188.0454295899424,argumentOfPerihelionDeg:130.1724036582639,perihelionJd:2.4502048946148166e6},peakMagnitude:0,peakOn:"1996-03-25",absoluteMagnitude:4.75,activityExponent:4,tailLengthDeg:80,tailLengthAu:1,note:"Passed 0.10 au from Earth in March 1996, five weeks BEFORE perihelion, with a tail measured at some 80 degrees — the longest of the modern era."},{id:"hale-bopp-1997",designation:"C/1995 O1",name:"Comet Hale-Bopp",orbit:{eccentricity:.9951314746156615,perihelionAu:.9141695067003724,inclinationDeg:89.43017155012492,ascendingNodeDeg:282.470602866853,argumentOfPerihelionDeg:130.5872524854533,perihelionJd:2450539633099368e-9},peakMagnitude:-.8,peakOn:"1997-04-01",absoluteMagnitude:-1.06,activityExponent:4,tailLengthDeg:20,tailLengthAu:.9938,note:"Visible to the naked eye for about eighteen months, longer than any comet on record."},{id:"mcnaught-2007",designation:"C/2006 P1",name:"Comet McNaught",orbit:{eccentricity:1.00001811603225,perihelionAu:.1707325614080681,inclinationDeg:77.83726446452654,ascendingNodeDeg:267.4149080498975,argumentOfPerihelionDeg:155.9756130642756,perihelionJd:2454113298753579e-9},peakMagnitude:-5.5,peakOn:"2007-01-13",absoluteMagnitude:2.53,activityExponent:4,tailLengthDeg:35,tailLengthAu:.5009,note:"The brightest comet since Ikeya-Seki, seen in daylight beside the Sun in January 2007."},{id:"lovejoy-2011",designation:"C/2011 W3",name:"Comet Lovejoy",orbit:{eccentricity:.999915056276912,perihelionAu:.005553783989325053,inclinationDeg:134.3558712062691,ascendingNodeDeg:326.3693517957772,argumentOfPerihelionDeg:53.50991655176601,perihelionJd:2455911511809431e-9},peakMagnitude:-3,peakOn:"2011-12-16",alsoRecordedMagnitude:1.5,alsoRecordedOn:"2011-12-22",absoluteMagnitude:3.51,activityExponent:1.194,note:"A sungrazer that was expected to be destroyed at perihelion and came out the other side, to stand in the southern dawn sky for the rest of December — which is the second magnitude recorded here."},{id:"panstarrs-2013",designation:"C/2011 L4",name:"Comet PANSTARRS",orbit:{eccentricity:1.000032542889696,perihelionAu:.301544229714915,inclinationDeg:84.2081978367921,ascendingNodeDeg:65.66588626213694,argumentOfPerihelionDeg:333.6516444379993,perihelionJd:2456361669960698e-9},peakMagnitude:1,peakOn:"2013-03-10",absoluteMagnitude:5.98,activityExponent:4},{id:"neowise-2020",designation:"C/2020 F3",name:"Comet NEOWISE",orbit:{eccentricity:.9991782081129224,perihelionAu:.2946512466331692,inclinationDeg:128.9375043020912,ascendingNodeDeg:61.01042991771634,argumentOfPerihelionDeg:37.2786526292898,perihelionJd:2.4590341788972816e6},peakMagnitude:.9,peakOn:"2020-07-08",absoluteMagnitude:5.79,activityExponent:4,tailLengthDeg:10,tailLengthAu:.1808,note:"The first comet since Hale-Bopp that ordinary observers in the northern hemisphere saw without being told where to look."},{id:"tsuchinshan-atlas-2024",designation:"C/2023 A3",name:"Comet Tsuchinshan-ATLAS",orbit:{eccentricity:1.000020192843226,perihelionAu:.3914228969475176,inclinationDeg:139.1105462619479,ascendingNodeDeg:21.55945689078845,argumentOfPerihelionDeg:308.4913086299446,perihelionJd:2460581242087108e-9},peakMagnitude:0,peakOn:"2024-10-14",absoluteMagnitude:3.97,activityExponent:4,tailLengthDeg:20,tailLengthAu:.1902,note:"Briefly reported far brighter around 9 October 2024, when it stood almost between the observer and the Sun and forward-scattered the light through its own dust — a geometry this catalog's brightness model does not attempt, so what is stored is the ordinary evening-sky peak a few days later."}];class fA{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 uv.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=$t(t),s=this.earthPositionAt(n),a=this.apparentPositionOf(e,2451545+n.tt,s),o=this.subtract(a,s),l=this.length(a),c=this.length(o),h=this.tailEndAt(e,a,s,l,n,t,i),d=this.horizontalOf(o,n,t,i);return{apparition:e,position:d,...h,heliocentricDistanceAu:l,earthDistanceAu:c,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(e,l,c)}}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 l=1+e.tailLengthAu/n,c=this.subtract({x:t.x*l,y:t.y*l,z:t.z*l},i),h=this.subtract(t,i);return{tailEnd:this.horizontalOf(c,s,a,o),tailLengthDeg:this.angleBetween(h,c)}}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=Nr(c5(),new kt(e.x,e.y,e.z,t)),a=Nr(j1(t),s),o=Gw(t,new K0(n.lat,n.lng,n.elevationM)),l=new kt(a.x-o.x,a.y-o.y,a.z-o.z,t),c=J0(l);return j0(c.ra,c.dec,i,n)}static earthPositionAt(e){return Nr(l5(),sa(we.Earth,e))}static julianDayOf(e){return 2451545+$t(e).tt}static orbitOf(e){const t=this.orbits.get(e.id);if(t)return t;const i=new ys(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 Dd=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class mg{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(e){const t=this.julianDayOf(e);return Dd.filter(i=>this.magnitudeAt(i,t)!==void 0)}static appearancesAt(e,t){const i=this.julianDayOf(e),n=[];for(const s of Dd){const a=this.magnitudeAt(s,i);a!==void 0&&n.push({outburst:s,position:On.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 Dd.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],[l,c]=i[s]??i[0];if(l===a)return o;const h=Math.min(1,Math.max(0,(n-a)/(l-a)));return o+h*(c-o)}static julianDayOf(e){return e.getTime()/864e5+this.UNIX_EPOCH_JD}}const pA=[{id:"quadrantids",code:"QUA",name:"Quadrantids",radiantRaHours:15.33,radiantDecDeg:49.7,start:{month:12,day:28},peak:{month:1,day:3},end:{month:1,day:12},peakZhr:110,velocityKmS:41,populationIndex:2.1},{id:"lyrids",code:"LYR",name:"April Lyrids",radiantRaHours:18.13,radiantDecDeg:33.3,start:{month:4,day:16},peak:{month:4,day:22},end:{month:4,day:25},peakZhr:18,velocityKmS:49,populationIndex:2.1},{id:"eta-aquariids",code:"ETA",name:"eta Aquariids",radiantRaHours:22.53,radiantDecDeg:-1,start:{month:4,day:19},peak:{month:5,day:6},end:{month:5,day:28},peakZhr:50,velocityKmS:66,populationIndex:2.4},{id:"alpha-capricornids",code:"CAP",name:"alpha Capricornids",radiantRaHours:20.47,radiantDecDeg:-9.2,start:{month:7,day:3},peak:{month:7,day:30},end:{month:8,day:15},peakZhr:5,velocityKmS:23,populationIndex:2.5},{id:"southern-delta-aquariids",code:"SDA",name:"Southern delta Aquariids",radiantRaHours:22.67,radiantDecDeg:-16.4,start:{month:7,day:12},peak:{month:7,day:30},end:{month:8,day:23},peakZhr:25,velocityKmS:41,populationIndex:3.2},{id:"perseids",code:"PER",name:"Perseids",radiantRaHours:3.22,radiantDecDeg:58,start:{month:7,day:17},peak:{month:8,day:12},end:{month:8,day:24},peakZhr:100,velocityKmS:59,populationIndex:2.2},{id:"southern-taurids",code:"STA",name:"Southern Taurids",radiantRaHours:3.47,radiantDecDeg:13,start:{month:9,day:10},peak:{month:10,day:10},end:{month:11,day:20},peakZhr:5,velocityKmS:27,populationIndex:2.3},{id:"draconids",code:"DRA",name:"October Draconids",radiantRaHours:17.47,radiantDecDeg:54,start:{month:10,day:6},peak:{month:10,day:8},end:{month:10,day:10},peakZhr:10,velocityKmS:20,populationIndex:2.6},{id:"orionids",code:"ORI",name:"Orionids",radiantRaHours:6.35,radiantDecDeg:15.6,start:{month:10,day:2},peak:{month:10,day:21},end:{month:11,day:7},peakZhr:20,velocityKmS:66,populationIndex:2.5},{id:"northern-taurids",code:"NTA",name:"Northern Taurids",radiantRaHours:3.87,radiantDecDeg:22,start:{month:10,day:20},peak:{month:11,day:12},end:{month:12,day:10},peakZhr:5,velocityKmS:29,populationIndex:2.3},{id:"leonids",code:"LEO",name:"Leonids",radiantRaHours:10.13,radiantDecDeg:21.6,start:{month:11,day:6},peak:{month:11,day:17},end:{month:11,day:30},peakZhr:15,velocityKmS:71,populationIndex:2.5},{id:"geminids",code:"GEM",name:"Geminids",radiantRaHours:7.47,radiantDecDeg:32.3,start:{month:12,day:4},peak:{month:12,day:14},end:{month:12,day:17},peakZhr:150,velocityKmS:35,populationIndex:2.6},{id:"ursids",code:"URS",name:"Ursids",radiantRaHours:14.47,radiantDecDeg:75.3,start:{month:12,day:17},peak:{month:12,day:22},end:{month:12,day:26},peakZhr:10,velocityKmS:33,populationIndex:3}],qc=6.5;class Id{static activeAt(e){return pA.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),l=this.wrappedDelta(s,n),c=this.wrappedDelta(a,s);return o<0?o<-l?0:1+o/l:o>0?o>c?0:1-o/c:1}static observedRatePerHour(e,t,i,n=qc){if(t<=0)return 0;const s=qc-n;return e*Math.sin(t*Math.PI/180)/Math.pow(i,s)}static radiantPosition(e,t,i){return On.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 ei{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(e,t){const i=$t(e),n=new oh(0,Bw(e).elon-90,1),s=Nr(d5(i),Z0(n,i)),a=J0(s);return j0(a.ra,a.dec,e,t)}static observedRatePerHour(e,t=qc){const i=ei.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(e*Math.PI/180)),n=qc-t;return(ei.QUIET_RATE_PER_HOUR+i)/Math.pow(ei.POPULATION_INDEX,n)}static schedule(e){const t=new hh(e.seed^1542469173);return ka.schedule(e).map(i=>{const n=ei.toCartesian({altitudeDeg:Math.asin(t.next())*180/Math.PI,azimuthDeg:t.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,a=ei.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:ei.toHorizontal(o),bearingDeg:ei.bearingFrom(o,n)}})}static turnAround(e,t){const[i,n]=ei.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]=ei.basisAround(e),s=e.x*t.x+e.y*t.y+e.z*t.z,a=ei.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=ei.normalise(ei.cross(e,t));return[i,ei.normalise(ei.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=ei.toCartesian(e.radiant??{altitudeDeg:90,azimuthDeg:0}),i=ei.turnAround(t,e.bearingDeg),n=e.fromRadiantDeg*Math.PI/180;return ei.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 gg="https://ufoathome.org/tle/index.json";class Ii{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??Ii.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(gg)||e.push(gg),e}static FIRST_SNAPSHOT="2021-02-22";async covers(e){const t=Date.parse(`${Ii.FIRST_SNAPSHOT}T00:00:00Z`)-Ii.MAX_ELEMENT_AGE_DAYS*Ii.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)-Ii.MAX_ELEMENT_AGE_DAYS*Ii.DAY_MS&&e.getTime()<=Date.parse(n.to)+Ii.MAX_ELEMENT_AGE_DAYS*Ii.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 l=await this.kindAt(o,e,i,n);s.push(...l),a.push(this.coverageOf(o,e,i,l.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*Ii.DAY_MS,o=Math.floor(s/a),l=s-o*a<a/2?o-1:o+1,c=new Set(i.kinds[e].bins),h=[o,l].map(v=>new Date(v*a).toISOString().slice(0,10)).filter(v=>c.has(v));if(h.length===0)return[];const[d,...u]=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 u)for(const m of Ii.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)/Ii.DAY_MS;if(m>Ii.MAX_ELEMENT_AGE_DAYS)continue;const g=d[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(),l=Ii.MAX_ELEMENT_AGE_DAYS*Ii.DAY_MS,c=n?"covered":o<Date.parse(s)-l?"before":o>Date.parse(a)+l?"after":"gap";return{kind:e,status:c,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 mA{lowerM;upperM;add(e,t){if(!(e<=0)){if(t.behindM!==void 0){const i=Tt.sizeMAt(t.behindM,e);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(t.inFrontM!==void 0){const i=Tt.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:Tt.distanceMAt(this.lowerM,e),maxM:this.upperM===void 0?void 0:Tt.distanceMAt(this.upperM,e)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ua{static DEG_PER_SECOND=360/86164.0905;static degOver(e){return Math.max(0,e)*Ua.DEG_PER_SECOND}static instants(e,t){if(!(t>0))return 1;const i=Ua.degOver(e)/t;return i<1?1:Math.min(Ua.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class Bi{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 Ua.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 Bi.EYE;const s=t.focalLengthMm??e.frame?.focalLengthMm??Bi.UNKNOWN_CAMERA_FOCAL_MM,a=s/n,o=Bi.resolutionArcsec(e,s,a);return{apertureMm:a,exposureSeconds:Math.min(i,Bi.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(e,t,i){const s=(e.detailUm??Bi.UNKNOWN_CAMERA_DETAIL_UM)/1e3/t*Bi.ARCSEC_PER_RADIAN,a=1.22*Bi.WAVELENGTH_M/(i/1e3)*Bi.ARCSEC_PER_RADIAN;return Math.max(s,a)}static trailLimitedSeconds(e){return e/Bi.skyDriftArcsecPerSecond}static gainOverEye(e,t={}){const i=Bi.graspOf(e,t),n=Bi.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:oi.focalLengthMmFor(e,t.fieldOfViewDeg);return Bi.gainOverEye(e,{fNumber:t.fNumber,focalLengthMm:i,exposureSeconds:t.exposureSeconds})}}const vg=111320,xo=Math.PI/180,gA=1.02,vA=1;class Uo{static of(e,t){const i=Uo.sightings(e,t);if(i.length<2)return;const n=Uo.baseline(i);if(!n)return;const{near:s,far:a,closedM:o}=n,l=Math.tan(a.widthDeg/2*xo)===0?0:Math.tan(s.widthDeg/2*xo)/Math.tan(a.widthDeg/2*xo);if(l<gA)return;const c=o/(l-1),h=Tt.sizeMAt(c,s.widthDeg),d=i.map(u=>({t:u.t,m:Tt.distanceMAt(h,u.widthDeg)}));return{widthM:h,distanceM:d,nearestM:Math.min(...d.map(u=>u.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=ti(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=Uo.closedAlongSight(i,n),[a,o,l]=s>=0?[n,i,s]:[i,n,-s];l<vA||a.widthDeg<=o.widthDeg||(!t||l>t.closedM)&&(t={near:a,far:o,closedM:l})}return t}static closedAlongSight(e,t){const i=(t.lat-e.lat)*vg,n=(t.lng-e.lng)*vg*Math.cos(e.lat*xo),s=(e.sightAzimuthDeg??0)*xo;return i*Math.cos(s)+n*Math.sin(s)}}class zi{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:zi.atLeastNearest(e.statedM),basis:"stated"};if(e.hypothesisM!==void 0&&e.hypothesisM>0)return{distanceM:zi.atLeastNearest(e.hypothesisM),basis:"hypothesis"};if(e.derivedM!==void 0&&e.derivedM>0)return{distanceM:zi.atLeastNearest(e.derivedM),basis:"derived"};const t=zi.largest(e.range?.minM,e.crossing?.behindM),i=zi.smallest(e.range?.maxM,e.crossing?.inFrontM),n=t===void 0?void 0:t*zi.MARGIN,s=i===void 0?void 0:i/zi.MARGIN;return n!==void 0&&s!==void 0?{distanceM:zi.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:zi.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<zi.CONVENTIONAL_M?{distanceM:zi.atLeastNearest(s),basis:"bounded"}:{distanceM:zi.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(e){return Math.max(zi.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 Pd=Math.PI/180;class et{constructor(e,t,i){this.body=e,this.ground=t;const n=[...e.track].sort((s,a)=>s.t-a.t);this.keys=this.place(n,i);for(const s of n)et.collect(this.motionKeys,s.t,s.motions),et.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(e,t,i){for(const[n,s]of Object.entries(i??{})){const a=e.get(n)??[];a.push({t,value:s}),e.set(n,a)}}motionsAt(e){return et.channelsAt(this.motionKeys,e,0)}lightsAt(e){return this.lightKeys.size>0?et.channelsAt(this.lightKeys,e,void 0):void 0}static channelsAt(e,t,i){const n={};for(const[s,a]of e){let o=a.length-1;for(;o>=0&&a[o].t>t;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const l=a[o],c=a[Math.min(o+1,a.length-1)],h=c===l||c.t===l.t?0:Math.min(1,(t-l.t)/(c.t-l.t));n[s]=et.lerp(l.value,c.value,h)}return n}static eyeOf(e,t,i){const n=ti(e,0),s=ti(e,t),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?ri(s.lat,s.lng,n.lat,n.lng):void 0,l=o?o.x:0,c=o?-o.z:0;return{eastM:l,northM:c,upM:i.heightAt(l,c)+et.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(e,t,i,n){const s=et.directionOf(t,i),a=c=>e.upM+s.upM*c-n.heightAt(e.eastM+s.eastM*c,e.northM+s.northM*c);let o=0,l=0;for(;l<et.MAX_RANGE_M;){if(l=o+Math.max(.5,o*.01),a(l)<=0){for(let c=0;c<30;c++){const h=(o+l)/2;a(h)<=0?l=h:o=h}return l}o=l}}static directionOf(e,t){const i=e*Pd,n=t*Pd;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=et.lerp(n.eastM,s.eastM,a),l=et.lerp(n.northM,s.northM,a),c={widthM:et.lerp(n.sizeM.widthM,s.sizeM.widthM,a),lengthM:et.lerp(n.sizeM.lengthM,s.sizeM.lengthM,a),heightM:et.lerp(n.sizeM.heightM,s.sizeM.heightM,a)},h={headingDeg:et.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,a),pitchDeg:et.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,a),rollDeg:et.lerp(n.attitude.rollDeg,s.attitude.rollDeg,a)};let d;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const u=et.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,a);d=this.groundUnderFootprint(o,l,c,h.headingDeg)+u+c.heightM/2}else d=et.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:l,upM:d,sizeM:c,attitude:h,appearance:{color:(a<1?n:s).appearance.color,albedo:et.lerp(n.appearance.albedo,s.appearance.albedo,a),luminanceCdM2:et.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,a)},flame:et.flameBetween(n.flame,s.flame,a),motions:this.motionsAt(e),lights:this.lightsAt(e),throwsFlame:this.body.track.some(u=>u.flame!==void 0&&u.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:et.lerp(n.lengthM,s.lengthM,i),widthM:et.lerp(n.widthM,s.widthM,i),luminanceCdM2:et.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*Pd,a={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let l=this.ground.heightAt(e,t);for(const[c,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const d=c*i.widthM/2,u=h*i.lengthM/2;l=Math.max(l,this.ground.heightAt(e+a.eastM*d+o.eastM*u,t+a.northM*d+o.northM*u))}return l}place(e,t){const i=[];let n;for(const s of e){const a=s.sizeM??n?.sizeM??et.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},l={color:s.appearance?.color??n?.appearance.color??et.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??et.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??et.DEFAULT_APPEARANCE.luminanceCdM2},c=this.positionOf(s,t)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s)??n.vertical});if(!c)continue;const h=s.flame??n?.flame,d=s.present??n?.present??!0;n={t:s.t,...c,sizeM:a,attitude:o,appearance:l,flame:h,present:d},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?et.lineOfSightMeetsGround(i,e.azimuthDeg,e.altitudeDeg,this.ground):void 0);if(n===void 0)return;const s=et.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 gr=Math.PI/180,bo=180/Math.PI;class Qt{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=Qt.projectionOf(a,i,n?.(a));if(o)for(const l of a.explains){const c=this.timeline.getInterpolatedShapeAt(e,l);!c||c.transparency>=1||s.push({...Qt.compare(l,a.id,{aim:c.aim,angular:c.angular},o),title:c.title})}}return s}static compare(e,t,i,n){const s=[],a=i.aim?Qt.separationDeg(i.aim,n.aim):void 0;if(a!==void 0){const c=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;a>Math.max(Qt.DIRECTION_TOLERANCE_DEG,c)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,l=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!Qt.withinSize(o)&&s.push("width"),l!==void 0&&!Qt.withinSize(l)&&s.push("height"),{sourceId:e,bodyId:t,stated:i,predicted:n,separationDeg:a,widthRatio:o,heightRatio:l,disagreements:s}}static projectionOf(e,t,i){const n=i&&i.length>0?i:Qt.outlineOf(e),s=i&&i.length>0?Qt.centreOf(i):e,a=Qt.normalized({eastM:s.eastM-t.eastM,northM:s.northM-t.northM,upM:s.upM-t.upM});if(!a)return;const o=Qt.normalized({eastM:a.northM,northM:-a.eastM,upM:0})??{eastM:1,northM:0,upM:0},l=Qt.cross(o,a);let c=1/0,h=-1/0,d=1/0,u=-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=Qt.dot(p,a);if(v<=0)return;const m=Math.atan2(Qt.dot(p,o),v),g=Math.atan2(Qt.dot(p,l),v);c=Math.min(c,m),h=Math.max(h,m),d=Math.min(d,g),u=Math.max(u,g)}return{aim:{azimuthDeg:(Math.atan2(a.eastM,a.northM)*bo+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,a.upM)))*bo},angular:{widthDeg:(h-c)*bo,heightDeg:(u-d)*bo}}}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*gr,n=t.altitudeDeg*gr,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((e.azimuthDeg-t.azimuthDeg)*gr);return Math.acos(Math.max(-1,Math.min(1,s)))*bo}static withinSize(e){return e<=Qt.SIZE_TOLERANCE&&e>=1/Qt.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"&&cv.includes(a))for(let d=0;d<=Qt.RINGS;d++){const u=d/Qt.RINGS*Math.PI;for(let f=0;f<Qt.SEGMENTS;f++){const p=f/Qt.SEGMENTS*2*Math.PI;s.push([t*Math.sin(u)*Math.cos(p),i*Math.sin(u)*Math.sin(p),n*Math.cos(u)])}}else for(const d of[-t,t])for(const u of[-i,i])for(const f of[-n,n])s.push([d,u,f]);const l=e.attitude.headingDeg*gr,c=e.attitude.pitchDeg*gr,h=e.attitude.rollDeg*gr;return s.map(([d,u,f])=>{const p=d*Math.cos(h)+f*Math.sin(h),v=-d*Math.sin(h)+f*Math.cos(h),m=u*Math.cos(c)-v*Math.sin(c),g=u*Math.sin(c)+v*Math.cos(c);return{eastM:e.eastM+p*Math.cos(l)+m*Math.sin(l),northM:e.northM-p*Math.sin(l)+m*Math.cos(l),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}}Hg();const MA={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},yA="{name} — mag {mag}, {alt}° above the horizon",xA="{name} — satellite, mag {mag}, {height} km up",bA="satellites-change",fv="rr0-confrontation",SA="{name} — mag {mag}, {alt}° below the horizontal",Ld="Credits",Mg="comet:",yg="nova:",_A={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",crop:"Crop row",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},wA=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,EA=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,AA=-18,TA={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Od={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class tf extends HTMLElement{creditsButton;set ownCredits(e){this.creditsButton.hidden=!e}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",As,Ts]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new Ii;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;starCatalogDepth=0;weatherAudio=new uA;vehicleAudio=new t2;vehicleHearing=new _c;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),l=this.naming,c=l.names,h=this.sceneRenderer.pickBodyAt(a,o);if(h){this.showHoverTooltip(e,this.bodyName(h));return}const d=this.sceneRenderer.pickDecorAt(a,o),u=d?this.ufoElement.sighting.decor.find(v=>v.id===d):void 0;if(u){this.showHoverTooltip(e,this.said.read(u.title)||l.decorKind(u.kind,_A[u.kind]));return}const f=this.sceneRenderer.pickSatelliteAt(a,o);if(f){this.showHoverTooltip(e,(c?.satelliteTooltip??xA).replace("{name}",f.name).replace("{mag}",f.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(f.heightKm).toLocaleString()));return}const p=this.sceneRenderer.pickStarAt(a,o);if(p){const v=p.star.mag,m=p.altitudeDeg,g=m<0?c?.starTooltipBelow??SA:c?.starTooltip??yA;this.showHoverTooltip(e,g.replace("{name}",l.star(p.star)).replace("{mag}",v.toLocaleString(void 0,{maximumFractionDigits:Math.abs(v)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(m)))));return}this.hoverTooltip.hidden=!0};bodyName(e){const t=e.startsWith(Mg)?e.slice(Mg.length):void 0,i=t?uv.find(a=>a.id===t):void 0;if(i)return this.naming.comet(i);const n=e.startsWith(yg)?mg.byId(e.slice(yg.length)):void 0;if(n)return this.naming.nova(n);const s=MA[e];return s===void 0?e:this.naming.body(e,s)}get naming(){return this.sceneNaming}sceneNaming=new Yc;namesLanguage="en";async loadSceneNames(){const e=u0(zr.preferencesFor(this),f0);if(e===this.namesLanguage)return;this.namesLanguage=e;const t=await Dg(e);e===this.namesLanguage&&this.applySceneNaming(new Yc(t))}applySceneNaming(e){this.sceneNaming=e;const t=e.names?.credits??Ld;this.creditsButton.title=t,this.creditsButton.setAttribute("aria-label",t),e.names&&(this.loaderNote.textContent=e.names.notAVideo),this.sceneRenderer.setCompassPoints(e.names?.compassPoints)}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(),pi.thunderDelayMs(e))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(gf(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;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),this.vehicleAudio.setPaused(!t),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${n2}</style>${i2}`,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 Ut(this.sceneCanvas);const t=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.sceneRenderer.onFirstFrameHold=s=>{t.hidden=!s,this.ufoElement.captionHeld=s},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(zd),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.detail)),this.ufoElement.style.setProperty("--ufo-canvas-background","transparent"),this.ufoElement.style.setProperty("--ufo-canvas-border","none"),this.ufoElement.fullscreenTarget=this.stageElement,this.shadow.getElementById("ufo-slot").replaceWith(this.ufoElement),this.ufoElement.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&Dn.fill(n,this)}),this.creditsButton.title=Ld,this.creditsButton.setAttribute("aria-label",Ld),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,a)=>this.seekPreviewOf(a).paint(s,a),this.ufoElement.addEventListener("mutedchange",()=>this.weatherAudio.setLevel(this.ufoElement.level)),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of["pointerdown","pointerup","touchend","click","keydown"])this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Nn(zr.preferencesFor(this))}saidTexts;connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),document.addEventListener("fullscreenchange",this.handleFullscreenChange);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(),this.vehicleAudio.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,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===As||e===Ts)&&i!==t&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const e of[As,Ts]){const t=this.getAttribute(e);t===null?this.ufoElement.removeAttribute(e):this.ufoElement.setAttribute(e,t)}}setCompassForced(e){this.sceneRenderer.setCompassForced(e)}lookToward(e){const t=ti(this.ufoElement.sighting,this.lastTimeMs);if(e.kind==="observer"||t?.lat===void 0||t.lng===void 0||t.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=ri(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.precipitationAmount??1),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)}bodyScreenBox(e){return this.sceneRenderer.bodyScreenBox(e)}pickPlacedBodyAt(e,t){return this.sceneRenderer.pickPlacedBodyAt(e,t)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume()}async loadFromSrc(e){const t=Co.json(e);this.holdForNewScene(t);const i=await t;this.documentUrl=new URL(e,location.href).href,this.sightingData=i}holdForNewScene(e){this.sceneRenderer.holdForNewScene(e)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(e){this.sceneRenderer.documentUrl=e}get sightingData(){return this.ufoElement.sightingData}set sightingData(e){this.ufoElement.sightingData=e,this.seekPreview?.recordingChanged(e),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(e){const t=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(e.width/t);return e.height!==i&&(e.height=i),this.seekPreview??=new Xc(this,()=>document.createElement($c))}showAt(e){this.ufoElement.currentTime=e,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(e){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const t=e.getContext("2d");return t?(t.drawImage(this.sceneCanvas,0,0,e.width,e.height),!0):!1}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}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}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=Tt.CANVAS_HEIGHT_PX,i=oi.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:Rd,url:this.getAttribute("star-catalog-src")??wA},{magnitudeLimit:Cd,url:this.getAttribute("deep-star-catalog-src")??EA}],t=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=t>Rd?Cd:Rd;const n=await Zn.upTo(e,t);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Cd||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const e=this.ufoElement.sighting,t=Bi.gainFor(e.instrument,{fNumber:ti(e,0)?.fNumber,fieldOfViewDeg:Qi.fovOf(e,0),exposureSeconds:e.exposure});return zu(AA,t)}updateAstronomy(e){this.ensureStarsDeepEnough(),this.applySceneAt(e);const t=Ln.windowEndingAt(e,this.exposureSeconds()),i=t.seconds,n=this.degreesPerPixelAt(e),s=Ua.instants(i,n),a=Math.max(s,this.ufoElement.exposureTimes(e).length,Ln.instants(this.ufoElement.sighting.decor,ti(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:Qi.fovOf(this.ufoElement.sighting,e)/t}applySceneAt(e,t){const i=this.ufoElement.sighting;this.setWeather(gf(i,e)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),t||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,e)),this.updateMeteorShower(i,e),this.updateLightning(i,e,t!==void 0),this.sceneRenderer.setDecor(i.decor);const n=ti(i,e);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=ti(i,0),a=vr(i,0),o=Object.fromEntries(bc(vr(i,e)).map(x=>[x.id,Ef(e,i.weatherTrack,a,s,n,x.id)]));this.sceneRenderer.setCloudOffset(Ef(e,i.weatherTrack,a,s,n),o),this.sceneRenderer.setObserverPose(n??Od),this.sceneRenderer.setLensOptics(this.lensOpticsAt(e)),this.sceneRenderer.setInstrumentGain(Bi.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:Qi.fovOf(i,e),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(bt.bodyAt(i,e,this.ufoElement.steadyObserver)),this.sceneRenderer.updateDecorAnchoring(ti(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.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.pushPhenomenaAt(e);const l=n?.lat??Od.lat,c=n?.lng??Od.lng,h=Ao(i.event.time??{},c,i.event.utcOffsetHours),d={lat:l,lng:c,elevationM:n?.elevationM??0};if(this.pushSatellitesAt(h,e,d),t&&!t.sky)return;if(!h){this.sceneRenderer.setAstronomy(TA);return}const u=new Date(h.getTime()+e),f=Math.max(1,Math.round(.25*this.degreesPerPixelAt(e)/Ua.DEG_PER_SECOND*1e3)),p=Math.max(1e-8,this.degreesPerPixelAt(e)*.1),v=`${Math.floor(u.getTime()/f)}|${Math.round(l/p)}|${Math.round(c/p)}|${Math.round(d.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(v===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=v;const m={...ad("Sun",u,d),magnitude:rd("Sun",u)},g={...ad("Moon",u,d),phase:f5(u),magnitude:rd("Moon",u)},S=u5.map(x=>({body:x,position:ad(x,u,d),magnitude:rd(x,u)}));this.sceneRenderer.setAstronomy({sun:m,moon:g,planets:S,comet:this.cometAt(u,d),novae:mg.appearancesAt(u,d).map(({outburst:x,position:M,magnitude:_})=>({id:x.id,position:M,magnitude:_})),stars:this.starCatalog?{catalog:this.starCatalog,date:u,observer:d}:void 0,frame:{date:u,observer:d}}),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.isConnected&&this.dispatchEvent(new CustomEvent(bA)))},s=tf.tleArchive;(async()=>{if(!await s.covers(e))return n("outside");const[a,o]=await Promise.all([s.at(e),gi(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!a)return n("unavailable");this.satellites={snapshot:a,passes:new o.SatellitePasses(a.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const 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=ti(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 l=Ao(i.event.time??{},o,i.event.utcOffsetHours);if(!l)return[];const c=Math.min(Math.max(e,0),4*36e5),h={lat:a,lng:o,elevationM:n?.elevationM??0},d=JSON.stringify([this.satellitesFor,l.getTime(),a,o,h.elevationM,c]);if(this.satellitePassesMemo?.key===d)return this.satellitePassesMemo.passes;const u=Math.max(10,Math.ceil(c/1e3/600)),f=t.passes.passesDuring(l,new Date(l.getTime()+c),h,u);return this.satellitePassesMemo={key:d,passes:f},f}cometAt(e,t){const i=fA.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,l=new Map,c=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(Pn.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)},S=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,x=S?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};c.add(p),(S||v.aim)&&c.delete(p);const M=v.angular?.widthDeg??a.pxToDeg(v.bounds.width),_=this.sizeEstimateOf(p);_.add(M,x);const w=Uo.of(t,p);l.set(p,zi.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:w&&M>0?Tt.distanceMAt(w.widthM,M):void 0,range:_.distanceRangeAt(M),crossing:x}))}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 x=l.get(m);x&&l.set(p,{distanceM:x.distanceM*.999,basis:x.basis});break}this.depths=l;const h=i.sourceIds,d=[];for(const[p,v]of o)d.push({sourceId:p,shape:v,distanceM:l.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:c.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(ti(t,e)?.rollDeg??0)+bt.bodyAt(t,e,this.ufoElement.steadyObserver).rollDeg;this.sceneRenderer.setPhenomena(d,{projection:a,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:oi.starPointsOf(t.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(e){this.interpretationShown=e,this.updateAstronomy(this.lastTimeMs)}get accountInTheRound(){return this.inTheRound}set accountInTheRound(e){this.inTheRound=e}get compareAccount(){return this.comparing}set compareAccount(e){this.comparing=e,this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(e,t,i){const n=this.sceneRenderer.bodyGround,s=et.eyeOf(this.ufoElement.sighting,i,n);return s?et.lineOfSightMeetsGround(s,e,t,n):void 0}bodyReading(e,t){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=u=>et.eyeOf(n,u,i),a=new et(e,i,s).at(t),o=s(t);if(!a||!o)return;const l=a.eastM-o.eastM,c=a.northM-o.northM,h=a.upM-o.upM,d=Math.hypot(l,c);return{azimuthDeg:(Math.atan2(l,c)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,d)*180/Math.PI,distanceM:Math.hypot(d,h),eastM:a.eastM,northM:a.northM,aboveGroundM:a.upM-a.sizeM.heightM/2-i.heightAt(a.eastM,a.northM),sizeM:a.sizeM,attitude:a.attitude,appearance:a.appearance}}directionToBody(e,t){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>et.eyeOf(n,p,i),a=new et(e,i,s),o=a.at(t)?t:e.track[0]?.t,l=o===void 0?void 0:a.at(o),c=o===void 0?void 0:s(o);if(!l||!c)return;const h=l.eastM-c.eastM,d=l.northM-c.northM,u=l.upM-c.upM,f=Math.hypot(h,d);if(!(f===0&&u===0))return{azimuthDeg:(Math.atan2(h,d)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(u,f)*180/Math.PI}}placeBodiesAt(e,t){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],a=[];const o=this.sceneRenderer.bodyGround,l=p=>et.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new et(p,o,l).at(e)).filter(p=>p!==void 0));const c=vr(n,e),h=c.windDirectionDeg*Math.PI/180,d={x:c.windSpeed*Math.sin(h),z:-c.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,e/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],d);const u=i&&this.comparing?l(e):void 0;if(u&&(a=new Qt(n.timeline).at(e,s,u,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(fv,{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&&vr(e,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(e){const t=vr(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?Ao(n,s?.lng??0,e.event.utcOffsetHours):void 0,o=(e.event.durationSeconds??0)*1e3||e.timeline.duration||2e4,l=Math.round((a?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=pi.schedule({durationMs:o,seed:l,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?Ao(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),l=ei.schedule({ratePerHour:ei.observedRatePerHour(ei.apexPosition(n,s).altitudeDeg),durationMs:a,velocityKmS:ei.TYPICAL_VELOCITY_KM_S,seed:o}),c=Id.activeAt(n).map(d=>{const u=Id.radiantPosition(d.shower,n,s);return{entry:d,position:u,rate:Id.observedRatePerHour(d.zhr,u.altitudeDeg,d.shower.populationIndex)}}).sort((d,u)=>u.rate-d.rate)[0];if(!c||c.rate<=0){this.sceneRenderer.setMeteorShower(l,0,0);return}const h=ka.schedule({ratePerHour:c.rate,durationMs:a,velocityKmS:c.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...l],c.position.altitudeDeg,c.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=ti(t,e),a=s?.fNumber??i.fNumber;if(!n||a===void 0)return;const o=oi.focalLengthMmFor(i,Qi.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 ws.of(t.instrument,Tt.CANVAS_HEIGHT_PX,Qi.fovOf(t,e))}sizeEstimateOf(e){let t=this.sizeEstimates.get(e);return t||(t=new mA,this.sizeEstimates.set(e,t)),t}}const $c="rr0-scene";function pv(){Hg(),customElements.get($c)||customElements.define($c,tf)}const RA={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",sway:"Sway at rest",swayTitle:"How much the body holding the instrument moves the view when not walking: 1 for a person standing, 0 for a tripod. Blank: 1 (0 if the account says the observer was paralysed)",lightPollution:"Night sky",lightPollutionTitle:'The zenith of a moonless night at this place, in magnitudes per square arcsecond, as a Sky Quality Meter reads it or as the World Atlas of artificial sky brightness (Falchi et al. 2016, lightpollutionmap.info, "SQM") gives it. 22 is a natural sky; a suburb is about 19, a city centre 17. Blank: a natural sky',observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Observer 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"},observerGroup:"Observer",observerId:"ID",observerTitle:"Title",observerLastName:"Last name",observerFirstNames:"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",decorBridge:"Bridge",decorCrop:"Crop row",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorObserver:"Other observer",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",goToMilestone:"Go to this moment",confirmAccept:"Delete",confirmDecline:"Cancel",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelAdvanced:"Model from an address",decorModelFromCatalogue:"From the catalogue, which the recording names it by. Change a field and it becomes this recording's own address.",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorObserverSide:"Observer location",decorObserverSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},yc={...RA,accountBy:"Account by",unnamedObserver:"Observer {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",source:"Source",basis:{stated:"stated",derived:"derived",assumed:"assumed"},accountSource:"Go to the source: {source}",credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Replay",embedEdit:"Editor",share:"Share",embedObservation:"Embed the observation",back:"Back",embedCopy:"Copy",embedCopied:"Copied",showLabels:"Show what it states",interpretation:"Interpretation",account:"Account",interpretationBy:"{title}, by {by}",confrontation:"Against the account",confrontationDirection:"{deg}° off",confrontationWidth:"width ×{ratio}",confrontationHeight:"height ×{ratio}",showComparison:"Compare with the account",hideComparison:"Stop comparing with the account",hideLabels:"Hide what it states"},CA=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:yc},Symbol.toStringTag,{value:"Module"}));pv();const xc="https://ufoathome.org",Nd="compare-account",kd="account",xg=`${xc}/edit/`;class kr extends HTMLElement{static get observedAttributes(){return["src","show-labels",As,Ts,Nd]}shadow;sceneElement;toolbarElement;accountElement;accountPrefix;observerText;observerSelect;infoButton;infoPanel;infoAppLink;editLink;accountSourceLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;shareButton;shareDialog;shareTitle;shareMain;shareEmbed;shareBack;shareClose;shareEmbedOption;shareEmbedLabel;shareLink;shareCopy;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new bf(yc,new Yc,new Nn(["en"]),new lc({}));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;labelsShown=!1;language="en";messages=yc;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${_v}</style>${Sv}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.sceneElement=document.createElement($c),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.sceneElement.ownCredits=!1,this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.accountElement=this.shadow.getElementById("account"),this.accountPrefix=this.shadow.getElementById("account-prefix"),this.observerText=this.shadow.getElementById("observer-text"),this.observerSelect=this.shadow.getElementById("observer"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.editLink=this.shadow.getElementById("edit-link"),this.accountSourceLink=this.shadow.getElementById("account-source"),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.shareButton=document.createElement("button"),this.shareButton.type="button",this.shareButton.id="share-button",this.shareButton.setAttribute("aria-haspopup","dialog"),this.shareButton.innerHTML=$e.SHARE,this.sceneElement.ufoElement.addControl(this.shareButton),this.shareDialog=this.shadow.getElementById("share-dialog"),this.shareTitle=this.shadow.getElementById("share-title"),this.shareMain=this.shadow.getElementById("share-main"),this.shareEmbed=this.shadow.getElementById("share-embed"),this.shareBack=this.shadow.getElementById("share-back"),this.shareClose=this.shadow.getElementById("share-close"),this.shareEmbedOption=this.shadow.getElementById("share-embed-option"),this.shareEmbedLabel=this.shadow.getElementById("share-embed-label"),this.shareLink=this.shadow.getElementById("share-link"),this.shareCopy=this.shadow.getElementById("share-copy"),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-account"),this.compareButton.addEventListener("click",()=>this.setComparing(!this.sceneElement.compareAccount)),this.observerSelect.addEventListener("change",()=>this.selectObserver(this.observerSelect.value)),this.interpretationSelect.addEventListener("change",()=>void this.chooseInterpretation(this.interpretationSelect.value)),this.sceneElement.addEventListener(fv,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.shareButton.addEventListener("click",()=>this.openShare()),this.shareClose.addEventListener("click",()=>this.closeShare()),this.shareBack.addEventListener("click",()=>this.showShareView("main")),this.shareEmbedOption.addEventListener("click",()=>this.showShareView("embed")),this.shareCopy.addEventListener("click",()=>void this.copyText(this.shareLink.value,this.shareLink,this.shareCopy)),this.shareDialog.addEventListener("click",t=>{t.target===this.shareDialog&&this.closeShare()});for(const t of[this.embedReplayRadio,this.embedEditRadio])t.addEventListener("change",()=>this.refreshEmbedMarkup());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.isConnected&&this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const e=++this.localeToken,t=zr.preferencesFor(this);this.preferences=t;const i=u0(t,f0),[n,s,a]=i==="en"?[yc,{},void 0]:await Promise.all([b2(i),S2(i),Dg(i)]);if(e!==this.localeToken)return;const o=i!==this.language;this.language=i,this.messages=n,this.tags=new lc(s),this.said=new Nn(t),this.summaryBuilder=new bf(this.messages,new Yc(a),this.said,this.tags),this.accountPrefix.textContent=this.messages.accountBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const l=this.entries.find(c=>c.src===this.currentSrc);l&&this.offerInterpretations(l),this.updateCompareButton(),this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.syncLabelsToggle(),this.refreshParamSummary(),o&&this.currentSrc&&this.runAssessments(),this.shareButton.title=this.messages.share,this.shareButton.setAttribute("aria-label",this.messages.share),this.shareClose.setAttribute("aria-label",this.messages.close),this.shareBack.setAttribute("aria-label",this.messages.back),this.shareCopy.textContent=this.messages.embedCopy,this.shareEmbedLabel.textContent=this.messages.embed,this.syncShareTitle(),this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateAccountLine()}preferences=[];localeToken=0;said=new Nn(["en"]);tags=new lc({});connectedCallback(){zr.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===As||e===Ts)&&this.forwardPlayerAttributes(),e===Nd&&this.setComparing(this.hasAttribute(Nd))}forwardPlayerAttributes(){for(const e of[As,Ts]){const t=this.getAttribute(e);t===null?this.sceneElement.removeAttribute(e):this.sceneElement.setAttribute(e,t)}}async loadFromSrc(e){const t=Co.json(e);this.sceneElement.holdForNewScene(t);const i=await t;if(Array.isArray(i))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(Ss.isCase(i)){const n=Ss.sightingUrls(i,new URL(e,location.href).href);if(n.length===0)throw new Error(`${e} is a case with no sighting event: no recording to show`);await this.loadObserverUrls(n,{json:i,url:new URL(e,location.href).href})}else this.setEntries([{src:e,sighting:i}],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 observerUrls(){return this.entries.map(e=>e.src)}set observerUrls(e){this.loadObserverUrls(e)}async loadObserverUrls(e,t){const i=await Promise.all(e.map(async n=>({src:n,sighting:await Co.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.observerSelect.hidden=!i,this.observerText.hidden=i,this.observerSelect.innerHTML="";for(const s of e){const a=document.createElement("option");a.value=s.src,a.textContent=this.observerDisplayName(this.plain(s).observer)??this.messages.unnamedObserver.replace("{n}",String(e.indexOf(s)+1)),this.observerSelect.appendChild(a)}const n=e.find(s=>s.src===this.currentSrc)??e[0];n?this.selectObserver(n.src):this.updateAccountLine()}editorUrl(){if(!this.currentSrc)return xg;const e=new URL(this.currentSrc,location.href);return`${xg}?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>
8410
- <${t} src="${n}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyText(e,t,i){try{await navigator.clipboard.writeText(e),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{t.select()}}async copyEmbedMarkup(){await this.copyText(this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){return this.currentSrc?`${xc}/play/?sighting=${encodeURIComponent(new URL(this.currentSrc,location.href).href)}`:`${xc}/play/`}shareView="main";openShare(){this.shareLink.value=this.playUrl(),this.refreshEmbedMarkup(),this.showShareView("main"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.shareLink.select()}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(e){this.shareView=e,this.shareMain.hidden=e!=="main",this.shareEmbed.hidden=e!=="embed",this.shareBack.hidden=e==="main",this.syncShareTitle()}syncShareTitle(){this.shareTitle.textContent=this.shareView==="embed"?this.messages.embedObservation:this.messages.share}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=(c,h,d)=>{const u=document.createElement("option");u.value=c,u.textContent=h,this.interpretationSelect.appendChild(u),this.interpretationLoaders.set(c,d)},s=e===this.entries.find(c=>c.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(kd,this.messages.account,()=>Promise.resolve(s));const a=this.caseSource;a&&Ss.interpretationEvents(a.json,this.plain(e).id).forEach((c,h)=>{const d=this.said.read(c.title)??`#${h+1}`,u=(c.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,u?this.messages.interpretationBy.replace("{title}",d).replace("{by}",u):d,()=>Ss.interpretationOf(c,a.url,f=>Co.json(f)))});const l=t&&[...this.interpretationSelect.options].some(c=>c.value===i)?i:kd;this.interpretationSelect.value=l,l===kd?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(l),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(e){this.sceneElement.compareAccount=e,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const e=this.sceneElement.compareAccount;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)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};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.observerDisplayName(e)??""}showConfrontation(e){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;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,l],c)=>{c>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,l&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}selectObserver(e){const t=this.entries.find(i=>i.src===e);t&&(this.currentSrc=e,this.observerSelect.value=e,this.sceneElement.documentUrl=t.src?new URL(t.src,location.href).href:void 0,this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=t.sighting,this.offerInterpretations(t),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(DA,{detail:{src:e}})))}async runAssessments(){const e=++this.assessmentToken,t=await new jv(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateAccountLine(){const e=this.entries.find(s=>s.src===this.currentSrc),t=e?this.observerDisplayName(this.plain(e).observer):void 0,i=t!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=t??"";const n=e&&this.plain(e).sources?.find(s=>/^https?:\/\//i.test(s.url??""));if(this.accountSourceLink.hidden=!n,n){this.accountSourceLink.href=n.url;const s=this.messages.accountSource.replace("{source}",n.title??n.url);this.accountSourceLink.title=s,this.accountSourceLink.setAttribute("aria-label",s)}this.editLink.hidden=!this.currentSrc,this.editLink.href=this.editorUrl(),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation)}observerDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id}plainRecordings=new WeakMap;plain(e){return this.stripped(e).recording}stripped(e){let t=this.plainRecordings.get(e.sighting);return t||(t=Vi.strip(e.sighting),this.plainRecordings.set(e.sighting,t)),t}basisOf(e,t){const i=this.stripped(e).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(l=>t.some(c=>l===c||l.startsWith(`${c}.`))).map(l=>i.at(l)),a=s.reduce((l,c)=>n[c.basis]>n[l]?c.basis:l,"stated"),o=s.filter(l=>l.basis===a&&l.rationale).map(l=>l.rationale);return{basis:a,rationales:o}}formatDate(e){const t=e.place?.[0],i=Ao(e.time??{},t?.lng??0,e.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(kr.DATE_LOCALES[this.language],{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")))}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)}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==="observer"?this.messages.observerGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const c=document.createElement("span");c.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,c.append(h),s={group:a.group,element:c},n.push(c)}const l=this.paramItem(a);s?s.element.append(l):n.push(l)}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(t=>t.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){const t=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(t&&this.appendInfoRow(this.infoObservationList,this.messages.case,t),!this.labelsShown){const s=this.formatDate(this.plain(e));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(e,kr.DATE_PATHS));const a=this.formatLocation(this.plain(e));a&&this.appendInfoRow(this.infoObservationList,this.messages.location,a,this.basisOf(e,kr.PLACE_PATHS))}const i=this.said.read(this.plain(e).description);i&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(e).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(e).tags;!this.labelsShown&&n&&n.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,n.map(s=>this.tags.name(s)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=xc,this.infoAppLink.textContent="UFO@home v0.80.0",Dn.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(e,t,i){const n=document.createElement("dt");n.textContent=t;const s=document.createElement("dd"),a=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const l=document.createElement("a");l.href=i.url,l.target="_blank",l.rel="noopener noreferrer",l.textContent=a,s.appendChild(l)}else s.append(a);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),e.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(e,t,i,n){const s=document.createElement("dt");s.textContent=t;const a=document.createElement("dd");if(a.textContent=i,n){const o=document.createElement("span");o.className=`basis basis-${n.basis}`,o.textContent=this.messages.basis[n.basis],n.rationales.length>0&&(o.title=n.rationales.join(`
8421
+ `);let s=Zn.cache.get(n);return s||(s=Promise.all(i.map(a=>Zn.load(a.url))).then(a=>a.reduce((o,l)=>Zn.concat(o,l))),Zn.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)}}}class Yc{constructor(e){this.names=e}body(e,t){return this.names?.bodies[e]??t}star(e){return this.names?.stars[e.name]??e.name}comet(e){return this.names?.comets[e.id]??e.name}nova(e){return this.names?.novae[e.id]??e.name}satelliteClass(e){return this.names?.satelliteClasses[e.id]??e.name}shower(e){return this.names?.showers[e.id]??e.name}lightRig(e){return this.names?.lightRigs[e.id]??e.name}instrument(e){return this.names?.instruments[e.id]??e.name}decorKind(e,t){return this.names?.decorKinds[e]??t}point(e){return Na.point(e,this.names?.compassPoints)}towards(e){return Na.towards(e,this.names)}}const oA=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,lA=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,cA=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,hA=20,dA=1;class uA{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};level=1;master;output(e){return this.master||(this.master=e.createGain(),this.master.gain.value=this.level,this.master.connect(e.destination)),this.master}setLevel(e){this.level=e,this.master&&(this.master.gain.value=e)}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}}Oa.unlock(this.context)}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(oA,this.ambientVolume).then(o=>this.applyIfCurrent(o,a,()=>this.ambientToken,l=>{this.ambientSource=l?.source,this.ambientGain=l?.gain,l&&(l.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(i/hA,1);const s=i>dA;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(lA,this.windVolume).then(o=>this.applyIfCurrent(o,a,()=>this.windToken,l=>{this.windSource=l?.source,this.windGain=l?.gain,l&&(l.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(cA,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear()}applyIfCurrent(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(this.output(i)),s.start(),{source:s,gain:a}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(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(this.output(i)),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 ys{constructor(e){this.elements=e;const{eccentricity:t,perihelionAu:i}=e,[n,s]=this.perifocalAxes(),a=Math.sqrt(ys.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*ys.stumpffC(n),o=t-i*i*i/Math.sqrt(ys.SUN_GM_AU3_PER_DAY2)*ys.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(ys.SUN_GM_AU3_PER_DAY2)*Math.abs(e),n=o=>{const l=this.inverseSemiMajorAxis*o*o,c=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*c)*o*o*o*ys.stumpffS(l)+c*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let a=0;for(let o=0;o<ys.MAX_ITERATIONS&&s-a>1e-13*Math.max(1,s);o++){const l=(a+s)/2;n(l)<i?a=l:s=l}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),l=Math.cos(i),c=Math.sin(i);return[{x:n*a-s*o*l,y:s*a+n*o*l,z:o*c},{x:-n*o-s*a*l,y:-s*o+n*a*l,z:a*c}]}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 uv=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672960498922706,perihelionAu:.5872100477652511,inclinationDeg:162.218798367122,ascendingNodeDeg:58.56208298700436,argumentOfPerihelionDeg:111.7366940639061,perihelionJd:2.4187816784171113e6},peakMagnitude:0,peakOn:"1910-05-20",absoluteMagnitude:4.72,activityExponent:4,tailLengthDeg:100,tailLengthAu:.1638,note:"Passed 0.15 au from Earth on 20 May 1910, and the Earth crossed the outer tail the day before — the apparition that produced a genuine public panic."},{id:"brooks-1911",designation:"C/1911 O1",name:"Comet Brooks",orbit:{eccentricity:.9876404970138669,perihelionAu:.4898172916113738,inclinationDeg:33.34043866978714,ascendingNodeDeg:293.7022074981857,argumentOfPerihelionDeg:153.5578007321686,perihelionJd:2.4193378856140426e6},peakMagnitude:2,peakOn:"1911-10-25",absoluteMagnitude:5.59,activityExponent:4},{id:"skjellerup-maristany-1927",designation:"C/1927 X1",name:"Comet Skjellerup-Maristany",orbit:{eccentricity:.999839726885059,perihelionAu:.1761569619628186,inclinationDeg:85.1125991950808,ascendingNodeDeg:78.24360172472711,argumentOfPerihelionDeg:47.15877857390136,perihelionJd:2.4252326808989984e6},peakMagnitude:-6,peakOn:"1927-12-15",absoluteMagnitude:1.19,activityExponent:4,note:"One of the few comets of the century seen in full daylight."},{id:"de-kock-paraskevopoulos-1941",designation:"C/1941 B2",name:"Comet de Kock-Paraskevopoulos",orbit:{eccentricity:.9991026715181549,perihelionAu:.7900329662827822,inclinationDeg:168.2039226531089,ascendingNodeDeg:43.10609347214336,argumentOfPerihelionDeg:268.6990344196369,perihelionJd:2430022157765061e-9},peakMagnitude:2,peakOn:"1941-02-05",absoluteMagnitude:5.01,activityExponent:4},{id:"southern-1947",designation:"C/1947 X1",name:"the Southern Comet",orbit:{eccentricity:.9998424430916737,perihelionAu:.1100045955093761,inclinationDeg:138.5113919632757,ascendingNodeDeg:337.3114969669252,argumentOfPerihelionDeg:196.1820121395961,perihelionJd:2.4325220864727003e6},peakMagnitude:-3,peakOn:"1947-12-08",absoluteMagnitude:3.01,activityExponent:4,note:"A bright southern-hemisphere comet of December 1947, the month the American sighting wave of that year was still being argued over."},{id:"eclipse-1948",designation:"C/1948 V1",name:"the Eclipse Comet",orbit:{eccentricity:.9999130678247334,perihelionAu:.1354437057263306,inclinationDeg:23.11668597152911,ascendingNodeDeg:211.0454985994762,argumentOfPerihelionDeg:107.2474157073104,perihelionJd:2.4328519265329437e6},peakMagnitude:-2,peakOn:"1948-11-01",absoluteMagnitude:4.79,activityExponent:4,note:"Found during the total solar eclipse of 1 November 1948, which is how a comet that bright had gone unnoticed: it had been hidden in the Sun's glare."},{id:"arend-roland-1957",designation:"C/1956 R1",name:"Comet Arend-Roland",orbit:{eccentricity:1.0002570255357,perihelionAu:.3160532361485914,inclinationDeg:119.9440863251822,ascendingNodeDeg:215.8548157717755,argumentOfPerihelionDeg:308.775920364167,perihelionJd:2.4359365327396123e6},peakMagnitude:.5,peakOn:"1957-04-25",absoluteMagnitude:3.96,activityExponent:4,note:"Showed a spike pointing back TOWARD the Sun in late April 1957 — a real anti-tail, and much reported at the time."},{id:"mrkos-1957",designation:"C/1957 P1",name:"Comet Mrkos",orbit:{eccentricity:.9993521583504134,perihelionAu:.3549238508212375,inclinationDeg:93.9433042053929,ascendingNodeDeg:68.32441518619923,argumentOfPerihelionDeg:40.31823675802871,perihelionJd:243605193752228e-8},peakMagnitude:1,peakOn:"1957-08-05",absoluteMagnitude:5.07,activityExponent:4,note:"The second bright naked-eye comet of 1957, four months after Arend-Roland."},{id:"seki-lines-1962",designation:"C/1962 C1",name:"Comet Seki-Lines",orbit:{eccentricity:1.000003791331562,perihelionAu:.03139689112215131,inclinationDeg:65.01487186102287,ascendingNodeDeg:304.6776602796538,argumentOfPerihelionDeg:11.47295326312573,perihelionJd:2437756163010178e-9},peakMagnitude:-2.5,peakOn:"1962-04-01",absoluteMagnitude:9.3,activityExponent:4},{id:"ikeya-seki-1965",designation:"C/1965 S1",name:"Comet Ikeya-Seki",orbit:{eccentricity:.9999141178248997,perihelionAu:.007785966366889336,inclinationDeg:141.8642315267051,ascendingNodeDeg:346.9951764632611,argumentOfPerihelionDeg:69.04909813996062,perihelionJd:2.4390546837018197e6},peakMagnitude:-10,peakOn:"1965-10-21",alsoRecordedMagnitude:2,alsoRecordedOn:"1965-10-30",absoluteMagnitude:5.26,activityExponent:4.002,tailLengthDeg:25,tailLengthAu:.5048,note:"A sungrazer that passed 450 000 km above the Sun's surface and was seen beside it in broad daylight — the brightest comet of the twentieth century. It then stood in the dawn sky for a fortnight with a tail some 25 degrees long, which is the second magnitude recorded here."},{id:"bennett-1970",designation:"C/1969 Y1",name:"Comet Bennett",orbit:{eccentricity:.9962979048768408,perihelionAu:.5376209981502136,inclinationDeg:90.03975717147327,ascendingNodeDeg:224.6576652531314,argumentOfPerihelionDeg:354.1494209173161,perihelionJd:2.4406655455270996e6},peakMagnitude:0,peakOn:"1970-03-26",absoluteMagnitude:3.36,activityExponent:4},{id:"white-ortiz-bolelli-1970",designation:"C/1970 K1",name:"Comet White-Ortiz-Bolelli",orbit:{eccentricity:.9999488875801225,perihelionAu:.00884411465256722,inclinationDeg:138.9520738221631,ascendingNodeDeg:336.8194095816687,argumentOfPerihelionDeg:61.10224765396615,perihelionJd:2.4407209807728203e6},peakMagnitude:1,peakOn:"1970-05-22",absoluteMagnitude:4.35,activityExponent:4},{id:"kohoutek-1973",designation:"C/1973 E1",name:"Comet Kohoutek",orbit:{eccentricity:1.000007152175185,perihelionAu:.1424250377812859,inclinationDeg:14.30414984159355,ascendingNodeDeg:258.4893339663974,argumentOfPerihelionDeg:37.79772760699667,perihelionJd:2442044930687027e-9},peakMagnitude:0,peakOn:"1974-01-05",absoluteMagnitude:4.89,activityExponent:4,note:"Announced in advance as the comet of the century and remembered for disappointing: it was an ordinary naked-eye object, not the spectacle the press had promised."},{id:"west-1976",designation:"C/1975 V1",name:"Comet West",orbit:{eccentricity:1.000017859625611,perihelionAu:.1966006188461085,inclinationDeg:43.07319920579427,ascendingNodeDeg:118.9189245655447,argumentOfPerihelionDeg:358.4315101259072,perihelionJd:2442833721841768e-9},peakMagnitude:-3,peakOn:"1976-02-25",absoluteMagnitude:4.41,activityExponent:4,tailLengthDeg:30,tailLengthAu:.4325,note:"Broke into four pieces at perihelion. Barely reported at the time — the press had been burned by Kohoutek two years earlier."},{id:"iras-araki-alcock-1983",designation:"C/1983 H1",name:"Comet IRAS-Araki-Alcock",orbit:{eccentricity:.9898409731606003,perihelionAu:.9913412593828502,inclinationDeg:73.25000846947029,ascendingNodeDeg:49.10235754476374,argumentOfPerihelionDeg:192.8506176754439,perihelionJd:2.4454757545235856e6},peakMagnitude:1.7,peakOn:"1983-05-11",absoluteMagnitude:9.04,activityExponent:4,note:"Passed 0.031 au from Earth on 11 May 1983, one of the closest cometary approaches on record: it crossed a quarter of the sky in a night, which no other comet in this list did."},{id:"halley-1986",designation:"1P/Halley",name:"Halley's Comet",orbit:{eccentricity:.9672792271749998,perihelionAu:.5871034488173393,inclinationDeg:162.2422242700916,ascendingNodeDeg:58.85993640671803,argumentOfPerihelionDeg:111.8655480539208,perihelionJd:2.4464709589610207e6},peakMagnitude:2.1,peakOn:"1986-03-10",absoluteMagnitude:2.71,activityExponent:4,note:"The worst-placed return in two thousand years — famous, expected, and for most observers a faint smudge."},{id:"hyakutake-1996",designation:"C/1996 B2",name:"Comet Hyakutake",orbit:{eccentricity:.9997295133739305,perihelionAu:.2302272039470452,inclinationDeg:124.923592343765,ascendingNodeDeg:188.0454295899424,argumentOfPerihelionDeg:130.1724036582639,perihelionJd:2.4502048946148166e6},peakMagnitude:0,peakOn:"1996-03-25",absoluteMagnitude:4.75,activityExponent:4,tailLengthDeg:80,tailLengthAu:1,note:"Passed 0.10 au from Earth in March 1996, five weeks BEFORE perihelion, with a tail measured at some 80 degrees — the longest of the modern era."},{id:"hale-bopp-1997",designation:"C/1995 O1",name:"Comet Hale-Bopp",orbit:{eccentricity:.9951314746156615,perihelionAu:.9141695067003724,inclinationDeg:89.43017155012492,ascendingNodeDeg:282.470602866853,argumentOfPerihelionDeg:130.5872524854533,perihelionJd:2450539633099368e-9},peakMagnitude:-.8,peakOn:"1997-04-01",absoluteMagnitude:-1.06,activityExponent:4,tailLengthDeg:20,tailLengthAu:.9938,note:"Visible to the naked eye for about eighteen months, longer than any comet on record."},{id:"mcnaught-2007",designation:"C/2006 P1",name:"Comet McNaught",orbit:{eccentricity:1.00001811603225,perihelionAu:.1707325614080681,inclinationDeg:77.83726446452654,ascendingNodeDeg:267.4149080498975,argumentOfPerihelionDeg:155.9756130642756,perihelionJd:2454113298753579e-9},peakMagnitude:-5.5,peakOn:"2007-01-13",absoluteMagnitude:2.53,activityExponent:4,tailLengthDeg:35,tailLengthAu:.5009,note:"The brightest comet since Ikeya-Seki, seen in daylight beside the Sun in January 2007."},{id:"lovejoy-2011",designation:"C/2011 W3",name:"Comet Lovejoy",orbit:{eccentricity:.999915056276912,perihelionAu:.005553783989325053,inclinationDeg:134.3558712062691,ascendingNodeDeg:326.3693517957772,argumentOfPerihelionDeg:53.50991655176601,perihelionJd:2455911511809431e-9},peakMagnitude:-3,peakOn:"2011-12-16",alsoRecordedMagnitude:1.5,alsoRecordedOn:"2011-12-22",absoluteMagnitude:3.51,activityExponent:1.194,note:"A sungrazer that was expected to be destroyed at perihelion and came out the other side, to stand in the southern dawn sky for the rest of December — which is the second magnitude recorded here."},{id:"panstarrs-2013",designation:"C/2011 L4",name:"Comet PANSTARRS",orbit:{eccentricity:1.000032542889696,perihelionAu:.301544229714915,inclinationDeg:84.2081978367921,ascendingNodeDeg:65.66588626213694,argumentOfPerihelionDeg:333.6516444379993,perihelionJd:2456361669960698e-9},peakMagnitude:1,peakOn:"2013-03-10",absoluteMagnitude:5.98,activityExponent:4},{id:"neowise-2020",designation:"C/2020 F3",name:"Comet NEOWISE",orbit:{eccentricity:.9991782081129224,perihelionAu:.2946512466331692,inclinationDeg:128.9375043020912,ascendingNodeDeg:61.01042991771634,argumentOfPerihelionDeg:37.2786526292898,perihelionJd:2.4590341788972816e6},peakMagnitude:.9,peakOn:"2020-07-08",absoluteMagnitude:5.79,activityExponent:4,tailLengthDeg:10,tailLengthAu:.1808,note:"The first comet since Hale-Bopp that ordinary observers in the northern hemisphere saw without being told where to look."},{id:"tsuchinshan-atlas-2024",designation:"C/2023 A3",name:"Comet Tsuchinshan-ATLAS",orbit:{eccentricity:1.000020192843226,perihelionAu:.3914228969475176,inclinationDeg:139.1105462619479,ascendingNodeDeg:21.55945689078845,argumentOfPerihelionDeg:308.4913086299446,perihelionJd:2460581242087108e-9},peakMagnitude:0,peakOn:"2024-10-14",absoluteMagnitude:3.97,activityExponent:4,tailLengthDeg:20,tailLengthAu:.1902,note:"Briefly reported far brighter around 9 October 2024, when it stood almost between the observer and the Sun and forward-scattered the light through its own dust — a geometry this catalog's brightness model does not attempt, so what is stored is the ordinary evening-sky peak a few days later."}];class fA{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 uv.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=$t(t),s=this.earthPositionAt(n),a=this.apparentPositionOf(e,2451545+n.tt,s),o=this.subtract(a,s),l=this.length(a),c=this.length(o),h=this.tailEndAt(e,a,s,l,n,t,i),d=this.horizontalOf(o,n,t,i);return{apparition:e,position:d,...h,heliocentricDistanceAu:l,earthDistanceAu:c,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(e,l,c)}}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 l=1+e.tailLengthAu/n,c=this.subtract({x:t.x*l,y:t.y*l,z:t.z*l},i),h=this.subtract(t,i);return{tailEnd:this.horizontalOf(c,s,a,o),tailLengthDeg:this.angleBetween(h,c)}}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=Nr(c5(),new kt(e.x,e.y,e.z,t)),a=Nr(j1(t),s),o=Gw(t,new K0(n.lat,n.lng,n.elevationM)),l=new kt(a.x-o.x,a.y-o.y,a.z-o.z,t),c=J0(l);return j0(c.ra,c.dec,i,n)}static earthPositionAt(e){return Nr(l5(),sa(we.Earth,e))}static julianDayOf(e){return 2451545+$t(e).tt}static orbitOf(e){const t=this.orbits.get(e.id);if(t)return t;const i=new ys(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 Dd=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class mg{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(e){const t=this.julianDayOf(e);return Dd.filter(i=>this.magnitudeAt(i,t)!==void 0)}static appearancesAt(e,t){const i=this.julianDayOf(e),n=[];for(const s of Dd){const a=this.magnitudeAt(s,i);a!==void 0&&n.push({outburst:s,position:On.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 Dd.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],[l,c]=i[s]??i[0];if(l===a)return o;const h=Math.min(1,Math.max(0,(n-a)/(l-a)));return o+h*(c-o)}static julianDayOf(e){return e.getTime()/864e5+this.UNIX_EPOCH_JD}}const pA=[{id:"quadrantids",code:"QUA",name:"Quadrantids",radiantRaHours:15.33,radiantDecDeg:49.7,start:{month:12,day:28},peak:{month:1,day:3},end:{month:1,day:12},peakZhr:110,velocityKmS:41,populationIndex:2.1},{id:"lyrids",code:"LYR",name:"April Lyrids",radiantRaHours:18.13,radiantDecDeg:33.3,start:{month:4,day:16},peak:{month:4,day:22},end:{month:4,day:25},peakZhr:18,velocityKmS:49,populationIndex:2.1},{id:"eta-aquariids",code:"ETA",name:"eta Aquariids",radiantRaHours:22.53,radiantDecDeg:-1,start:{month:4,day:19},peak:{month:5,day:6},end:{month:5,day:28},peakZhr:50,velocityKmS:66,populationIndex:2.4},{id:"alpha-capricornids",code:"CAP",name:"alpha Capricornids",radiantRaHours:20.47,radiantDecDeg:-9.2,start:{month:7,day:3},peak:{month:7,day:30},end:{month:8,day:15},peakZhr:5,velocityKmS:23,populationIndex:2.5},{id:"southern-delta-aquariids",code:"SDA",name:"Southern delta Aquariids",radiantRaHours:22.67,radiantDecDeg:-16.4,start:{month:7,day:12},peak:{month:7,day:30},end:{month:8,day:23},peakZhr:25,velocityKmS:41,populationIndex:3.2},{id:"perseids",code:"PER",name:"Perseids",radiantRaHours:3.22,radiantDecDeg:58,start:{month:7,day:17},peak:{month:8,day:12},end:{month:8,day:24},peakZhr:100,velocityKmS:59,populationIndex:2.2},{id:"southern-taurids",code:"STA",name:"Southern Taurids",radiantRaHours:3.47,radiantDecDeg:13,start:{month:9,day:10},peak:{month:10,day:10},end:{month:11,day:20},peakZhr:5,velocityKmS:27,populationIndex:2.3},{id:"draconids",code:"DRA",name:"October Draconids",radiantRaHours:17.47,radiantDecDeg:54,start:{month:10,day:6},peak:{month:10,day:8},end:{month:10,day:10},peakZhr:10,velocityKmS:20,populationIndex:2.6},{id:"orionids",code:"ORI",name:"Orionids",radiantRaHours:6.35,radiantDecDeg:15.6,start:{month:10,day:2},peak:{month:10,day:21},end:{month:11,day:7},peakZhr:20,velocityKmS:66,populationIndex:2.5},{id:"northern-taurids",code:"NTA",name:"Northern Taurids",radiantRaHours:3.87,radiantDecDeg:22,start:{month:10,day:20},peak:{month:11,day:12},end:{month:12,day:10},peakZhr:5,velocityKmS:29,populationIndex:2.3},{id:"leonids",code:"LEO",name:"Leonids",radiantRaHours:10.13,radiantDecDeg:21.6,start:{month:11,day:6},peak:{month:11,day:17},end:{month:11,day:30},peakZhr:15,velocityKmS:71,populationIndex:2.5},{id:"geminids",code:"GEM",name:"Geminids",radiantRaHours:7.47,radiantDecDeg:32.3,start:{month:12,day:4},peak:{month:12,day:14},end:{month:12,day:17},peakZhr:150,velocityKmS:35,populationIndex:2.6},{id:"ursids",code:"URS",name:"Ursids",radiantRaHours:14.47,radiantDecDeg:75.3,start:{month:12,day:17},peak:{month:12,day:22},end:{month:12,day:26},peakZhr:10,velocityKmS:33,populationIndex:3}],qc=6.5;class Id{static activeAt(e){return pA.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),l=this.wrappedDelta(s,n),c=this.wrappedDelta(a,s);return o<0?o<-l?0:1+o/l:o>0?o>c?0:1-o/c:1}static observedRatePerHour(e,t,i,n=qc){if(t<=0)return 0;const s=qc-n;return e*Math.sin(t*Math.PI/180)/Math.pow(i,s)}static radiantPosition(e,t,i){return On.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 ei{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(e,t){const i=$t(e),n=new oh(0,Bw(e).elon-90,1),s=Nr(d5(i),Z0(n,i)),a=J0(s);return j0(a.ra,a.dec,e,t)}static observedRatePerHour(e,t=qc){const i=ei.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(e*Math.PI/180)),n=qc-t;return(ei.QUIET_RATE_PER_HOUR+i)/Math.pow(ei.POPULATION_INDEX,n)}static schedule(e){const t=new hh(e.seed^1542469173);return ka.schedule(e).map(i=>{const n=ei.toCartesian({altitudeDeg:Math.asin(t.next())*180/Math.PI,azimuthDeg:t.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,a=ei.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:ei.toHorizontal(o),bearingDeg:ei.bearingFrom(o,n)}})}static turnAround(e,t){const[i,n]=ei.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]=ei.basisAround(e),s=e.x*t.x+e.y*t.y+e.z*t.z,a=ei.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=ei.normalise(ei.cross(e,t));return[i,ei.normalise(ei.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=ei.toCartesian(e.radiant??{altitudeDeg:90,azimuthDeg:0}),i=ei.turnAround(t,e.bearingDeg),n=e.fromRadiantDeg*Math.PI/180;return ei.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 gg="https://ufoathome.org/tle/index.json";class Ii{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??Ii.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(gg)||e.push(gg),e}static FIRST_SNAPSHOT="2021-02-22";async covers(e){const t=Date.parse(`${Ii.FIRST_SNAPSHOT}T00:00:00Z`)-Ii.MAX_ELEMENT_AGE_DAYS*Ii.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)-Ii.MAX_ELEMENT_AGE_DAYS*Ii.DAY_MS&&e.getTime()<=Date.parse(n.to)+Ii.MAX_ELEMENT_AGE_DAYS*Ii.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 l=await this.kindAt(o,e,i,n);s.push(...l),a.push(this.coverageOf(o,e,i,l.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*Ii.DAY_MS,o=Math.floor(s/a),l=s-o*a<a/2?o-1:o+1,c=new Set(i.kinds[e].bins),h=[o,l].map(v=>new Date(v*a).toISOString().slice(0,10)).filter(v=>c.has(v));if(h.length===0)return[];const[d,...u]=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 u)for(const m of Ii.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)/Ii.DAY_MS;if(m>Ii.MAX_ELEMENT_AGE_DAYS)continue;const g=d[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(),l=Ii.MAX_ELEMENT_AGE_DAYS*Ii.DAY_MS,c=n?"covered":o<Date.parse(s)-l?"before":o>Date.parse(a)+l?"after":"gap";return{kind:e,status:c,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 mA{lowerM;upperM;add(e,t){if(!(e<=0)){if(t.behindM!==void 0){const i=Tt.sizeMAt(t.behindM,e);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(t.inFrontM!==void 0){const i=Tt.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:Tt.distanceMAt(this.lowerM,e),maxM:this.upperM===void 0?void 0:Tt.distanceMAt(this.upperM,e)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ua{static DEG_PER_SECOND=360/86164.0905;static degOver(e){return Math.max(0,e)*Ua.DEG_PER_SECOND}static instants(e,t){if(!(t>0))return 1;const i=Ua.degOver(e)/t;return i<1?1:Math.min(Ua.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class Bi{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 Ua.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 Bi.EYE;const s=t.focalLengthMm??e.frame?.focalLengthMm??Bi.UNKNOWN_CAMERA_FOCAL_MM,a=s/n,o=Bi.resolutionArcsec(e,s,a);return{apertureMm:a,exposureSeconds:Math.min(i,Bi.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(e,t,i){const s=(e.detailUm??Bi.UNKNOWN_CAMERA_DETAIL_UM)/1e3/t*Bi.ARCSEC_PER_RADIAN,a=1.22*Bi.WAVELENGTH_M/(i/1e3)*Bi.ARCSEC_PER_RADIAN;return Math.max(s,a)}static trailLimitedSeconds(e){return e/Bi.skyDriftArcsecPerSecond}static gainOverEye(e,t={}){const i=Bi.graspOf(e,t),n=Bi.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:oi.focalLengthMmFor(e,t.fieldOfViewDeg);return Bi.gainOverEye(e,{fNumber:t.fNumber,focalLengthMm:i,exposureSeconds:t.exposureSeconds})}}const vg=111320,xo=Math.PI/180,gA=1.02,vA=1;class Uo{static of(e,t){const i=Uo.sightings(e,t);if(i.length<2)return;const n=Uo.baseline(i);if(!n)return;const{near:s,far:a,closedM:o}=n,l=Math.tan(a.widthDeg/2*xo)===0?0:Math.tan(s.widthDeg/2*xo)/Math.tan(a.widthDeg/2*xo);if(l<gA)return;const c=o/(l-1),h=Tt.sizeMAt(c,s.widthDeg),d=i.map(u=>({t:u.t,m:Tt.distanceMAt(h,u.widthDeg)}));return{widthM:h,distanceM:d,nearestM:Math.min(...d.map(u=>u.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=ti(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=Uo.closedAlongSight(i,n),[a,o,l]=s>=0?[n,i,s]:[i,n,-s];l<vA||a.widthDeg<=o.widthDeg||(!t||l>t.closedM)&&(t={near:a,far:o,closedM:l})}return t}static closedAlongSight(e,t){const i=(t.lat-e.lat)*vg,n=(t.lng-e.lng)*vg*Math.cos(e.lat*xo),s=(e.sightAzimuthDeg??0)*xo;return i*Math.cos(s)+n*Math.sin(s)}}class zi{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:zi.atLeastNearest(e.statedM),basis:"stated"};if(e.hypothesisM!==void 0&&e.hypothesisM>0)return{distanceM:zi.atLeastNearest(e.hypothesisM),basis:"hypothesis"};if(e.derivedM!==void 0&&e.derivedM>0)return{distanceM:zi.atLeastNearest(e.derivedM),basis:"derived"};const t=zi.largest(e.range?.minM,e.crossing?.behindM),i=zi.smallest(e.range?.maxM,e.crossing?.inFrontM),n=t===void 0?void 0:t*zi.MARGIN,s=i===void 0?void 0:i/zi.MARGIN;return n!==void 0&&s!==void 0?{distanceM:zi.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:zi.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<zi.CONVENTIONAL_M?{distanceM:zi.atLeastNearest(s),basis:"bounded"}:{distanceM:zi.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(e){return Math.max(zi.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 Pd=Math.PI/180;class et{constructor(e,t,i){this.body=e,this.ground=t;const n=[...e.track].sort((s,a)=>s.t-a.t);this.keys=this.place(n,i);for(const s of n)et.collect(this.motionKeys,s.t,s.motions),et.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(e,t,i){for(const[n,s]of Object.entries(i??{})){const a=e.get(n)??[];a.push({t,value:s}),e.set(n,a)}}motionsAt(e){return et.channelsAt(this.motionKeys,e,0)}lightsAt(e){return this.lightKeys.size>0?et.channelsAt(this.lightKeys,e,void 0):void 0}static channelsAt(e,t,i){const n={};for(const[s,a]of e){let o=a.length-1;for(;o>=0&&a[o].t>t;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const l=a[o],c=a[Math.min(o+1,a.length-1)],h=c===l||c.t===l.t?0:Math.min(1,(t-l.t)/(c.t-l.t));n[s]=et.lerp(l.value,c.value,h)}return n}static eyeOf(e,t,i){const n=ti(e,0),s=ti(e,t),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?ri(s.lat,s.lng,n.lat,n.lng):void 0,l=o?o.x:0,c=o?-o.z:0;return{eastM:l,northM:c,upM:i.heightAt(l,c)+et.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(e,t,i,n){const s=et.directionOf(t,i),a=c=>e.upM+s.upM*c-n.heightAt(e.eastM+s.eastM*c,e.northM+s.northM*c);let o=0,l=0;for(;l<et.MAX_RANGE_M;){if(l=o+Math.max(.5,o*.01),a(l)<=0){for(let c=0;c<30;c++){const h=(o+l)/2;a(h)<=0?l=h:o=h}return l}o=l}}static directionOf(e,t){const i=e*Pd,n=t*Pd;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=et.lerp(n.eastM,s.eastM,a),l=et.lerp(n.northM,s.northM,a),c={widthM:et.lerp(n.sizeM.widthM,s.sizeM.widthM,a),lengthM:et.lerp(n.sizeM.lengthM,s.sizeM.lengthM,a),heightM:et.lerp(n.sizeM.heightM,s.sizeM.heightM,a)},h={headingDeg:et.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,a),pitchDeg:et.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,a),rollDeg:et.lerp(n.attitude.rollDeg,s.attitude.rollDeg,a)};let d;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const u=et.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,a);d=this.groundUnderFootprint(o,l,c,h.headingDeg)+u+c.heightM/2}else d=et.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:l,upM:d,sizeM:c,attitude:h,appearance:{color:(a<1?n:s).appearance.color,albedo:et.lerp(n.appearance.albedo,s.appearance.albedo,a),luminanceCdM2:et.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,a)},flame:et.flameBetween(n.flame,s.flame,a),motions:this.motionsAt(e),lights:this.lightsAt(e),throwsFlame:this.body.track.some(u=>u.flame!==void 0&&u.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:et.lerp(n.lengthM,s.lengthM,i),widthM:et.lerp(n.widthM,s.widthM,i),luminanceCdM2:et.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*Pd,a={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let l=this.ground.heightAt(e,t);for(const[c,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const d=c*i.widthM/2,u=h*i.lengthM/2;l=Math.max(l,this.ground.heightAt(e+a.eastM*d+o.eastM*u,t+a.northM*d+o.northM*u))}return l}place(e,t){const i=[];let n;for(const s of e){const a=s.sizeM??n?.sizeM??et.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},l={color:s.appearance?.color??n?.appearance.color??et.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??et.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??et.DEFAULT_APPEARANCE.luminanceCdM2},c=this.positionOf(s,t)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s)??n.vertical});if(!c)continue;const h=s.flame??n?.flame,d=s.present??n?.present??!0;n={t:s.t,...c,sizeM:a,attitude:o,appearance:l,flame:h,present:d},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?et.lineOfSightMeetsGround(i,e.azimuthDeg,e.altitudeDeg,this.ground):void 0);if(n===void 0)return;const s=et.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 gr=Math.PI/180,bo=180/Math.PI;class Qt{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=Qt.projectionOf(a,i,n?.(a));if(o)for(const l of a.explains){const c=this.timeline.getInterpolatedShapeAt(e,l);!c||c.transparency>=1||s.push({...Qt.compare(l,a.id,{aim:c.aim,angular:c.angular},o),title:c.title})}}return s}static compare(e,t,i,n){const s=[],a=i.aim?Qt.separationDeg(i.aim,n.aim):void 0;if(a!==void 0){const c=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;a>Math.max(Qt.DIRECTION_TOLERANCE_DEG,c)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,l=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!Qt.withinSize(o)&&s.push("width"),l!==void 0&&!Qt.withinSize(l)&&s.push("height"),{sourceId:e,bodyId:t,stated:i,predicted:n,separationDeg:a,widthRatio:o,heightRatio:l,disagreements:s}}static projectionOf(e,t,i){const n=i&&i.length>0?i:Qt.outlineOf(e),s=i&&i.length>0?Qt.centreOf(i):e,a=Qt.normalized({eastM:s.eastM-t.eastM,northM:s.northM-t.northM,upM:s.upM-t.upM});if(!a)return;const o=Qt.normalized({eastM:a.northM,northM:-a.eastM,upM:0})??{eastM:1,northM:0,upM:0},l=Qt.cross(o,a);let c=1/0,h=-1/0,d=1/0,u=-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=Qt.dot(p,a);if(v<=0)return;const m=Math.atan2(Qt.dot(p,o),v),g=Math.atan2(Qt.dot(p,l),v);c=Math.min(c,m),h=Math.max(h,m),d=Math.min(d,g),u=Math.max(u,g)}return{aim:{azimuthDeg:(Math.atan2(a.eastM,a.northM)*bo+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,a.upM)))*bo},angular:{widthDeg:(h-c)*bo,heightDeg:(u-d)*bo}}}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*gr,n=t.altitudeDeg*gr,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((e.azimuthDeg-t.azimuthDeg)*gr);return Math.acos(Math.max(-1,Math.min(1,s)))*bo}static withinSize(e){return e<=Qt.SIZE_TOLERANCE&&e>=1/Qt.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"&&cv.includes(a))for(let d=0;d<=Qt.RINGS;d++){const u=d/Qt.RINGS*Math.PI;for(let f=0;f<Qt.SEGMENTS;f++){const p=f/Qt.SEGMENTS*2*Math.PI;s.push([t*Math.sin(u)*Math.cos(p),i*Math.sin(u)*Math.sin(p),n*Math.cos(u)])}}else for(const d of[-t,t])for(const u of[-i,i])for(const f of[-n,n])s.push([d,u,f]);const l=e.attitude.headingDeg*gr,c=e.attitude.pitchDeg*gr,h=e.attitude.rollDeg*gr;return s.map(([d,u,f])=>{const p=d*Math.cos(h)+f*Math.sin(h),v=-d*Math.sin(h)+f*Math.cos(h),m=u*Math.cos(c)-v*Math.sin(c),g=u*Math.sin(c)+v*Math.cos(c);return{eastM:e.eastM+p*Math.cos(l)+m*Math.sin(l),northM:e.northM-p*Math.sin(l)+m*Math.cos(l),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}}Hg();const MA={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},yA="{name} — mag {mag}, {alt}° above the horizon",xA="{name} — satellite, mag {mag}, {height} km up",bA="satellites-change",fv="rr0-confrontation",SA="{name} — mag {mag}, {alt}° below the horizontal",Ld="Credits",Mg="comet:",yg="nova:",_A={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",crop:"Crop row",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},wA=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,EA=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,AA=-18,TA={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Od={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class tf extends HTMLElement{creditsButton;set ownCredits(e){this.creditsButton.hidden=!e}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",As,Ts]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new Ii;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;starCatalogDepth=0;weatherAudio=new uA;vehicleAudio=new t2;vehicleHearing=new _c;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),l=this.naming,c=l.names,h=this.sceneRenderer.pickBodyAt(a,o);if(h){this.showHoverTooltip(e,this.bodyName(h));return}const d=this.sceneRenderer.pickDecorAt(a,o),u=d?this.ufoElement.sighting.decor.find(v=>v.id===d):void 0;if(u){this.showHoverTooltip(e,this.said.read(u.title)||l.decorKind(u.kind,_A[u.kind]));return}const f=this.sceneRenderer.pickSatelliteAt(a,o);if(f){this.showHoverTooltip(e,(c?.satelliteTooltip??xA).replace("{name}",f.name).replace("{mag}",f.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(f.heightKm).toLocaleString()));return}const p=this.sceneRenderer.pickStarAt(a,o);if(p){const v=p.star.mag,m=p.altitudeDeg,g=m<0?c?.starTooltipBelow??SA:c?.starTooltip??yA;this.showHoverTooltip(e,g.replace("{name}",l.star(p.star)).replace("{mag}",v.toLocaleString(void 0,{maximumFractionDigits:Math.abs(v)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(m)))));return}this.hoverTooltip.hidden=!0};bodyName(e){const t=e.startsWith(Mg)?e.slice(Mg.length):void 0,i=t?uv.find(a=>a.id===t):void 0;if(i)return this.naming.comet(i);const n=e.startsWith(yg)?mg.byId(e.slice(yg.length)):void 0;if(n)return this.naming.nova(n);const s=MA[e];return s===void 0?e:this.naming.body(e,s)}get naming(){return this.sceneNaming}sceneNaming=new Yc;namesLanguage="en";async loadSceneNames(){const e=u0(zr.preferencesFor(this),f0);if(e===this.namesLanguage)return;this.namesLanguage=e;const t=await Dg(e);e===this.namesLanguage&&this.applySceneNaming(new Yc(t))}applySceneNaming(e){this.sceneNaming=e;const t=e.names?.credits??Ld;this.creditsButton.title=t,this.creditsButton.setAttribute("aria-label",t),e.names&&(this.loaderNotVideo.textContent=e.names.notAVideo,this.loaderNote.textContent=e.names.isASimulation),this.sceneRenderer.setCompassPoints(e.names?.compassPoints)}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(),pi.thunderDelayMs(e))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(gf(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;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),this.vehicleAudio.setPaused(!t),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${n2}</style>${i2}`,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 Ut(this.sceneCanvas);const t=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.sceneRenderer.onFirstFrameHold=s=>{t.hidden=!s,this.ufoElement.captionHeld=s},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(zd),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.detail)),this.ufoElement.style.setProperty("--ufo-canvas-background","transparent"),this.ufoElement.style.setProperty("--ufo-canvas-border","none"),this.ufoElement.fullscreenTarget=this.stageElement,this.shadow.getElementById("ufo-slot").replaceWith(this.ufoElement),this.ufoElement.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&Dn.fill(n,this)}),this.creditsButton.title=Ld,this.creditsButton.setAttribute("aria-label",Ld),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,a)=>this.seekPreviewOf(a).paint(s,a),this.ufoElement.addEventListener("mutedchange",()=>this.weatherAudio.setLevel(this.ufoElement.level)),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of["pointerdown","pointerup","touchend","click","keydown"])this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Nn(zr.preferencesFor(this))}saidTexts;connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),document.addEventListener("fullscreenchange",this.handleFullscreenChange);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(),this.vehicleAudio.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,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===As||e===Ts)&&i!==t&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const e of[As,Ts]){const t=this.getAttribute(e);t===null?this.ufoElement.removeAttribute(e):this.ufoElement.setAttribute(e,t)}}setCompassForced(e){this.sceneRenderer.setCompassForced(e)}lookToward(e){const t=ti(this.ufoElement.sighting,this.lastTimeMs);if(e.kind==="observer"||t?.lat===void 0||t.lng===void 0||t.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=ri(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.precipitationAmount??1),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)}bodyScreenBox(e){return this.sceneRenderer.bodyScreenBox(e)}pickPlacedBodyAt(e,t){return this.sceneRenderer.pickPlacedBodyAt(e,t)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume()}async loadFromSrc(e){const t=Co.json(e);this.holdForNewScene(t);const i=await t;this.documentUrl=new URL(e,location.href).href,this.sightingData=i}holdForNewScene(e){this.sceneRenderer.holdForNewScene(e)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(e){this.sceneRenderer.documentUrl=e}get sightingData(){return this.ufoElement.sightingData}set sightingData(e){this.ufoElement.sightingData=e,this.seekPreview?.recordingChanged(e),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(e){const t=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(e.width/t);return e.height!==i&&(e.height=i),this.seekPreview??=new Xc(this,()=>document.createElement($c))}showAt(e){this.ufoElement.currentTime=e,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(e){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const t=e.getContext("2d");return t?(t.drawImage(this.sceneCanvas,0,0,e.width,e.height),!0):!1}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}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}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=Tt.CANVAS_HEIGHT_PX,i=oi.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:Rd,url:this.getAttribute("star-catalog-src")??wA},{magnitudeLimit:Cd,url:this.getAttribute("deep-star-catalog-src")??EA}],t=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=t>Rd?Cd:Rd;const n=await Zn.upTo(e,t);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Cd||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const e=this.ufoElement.sighting,t=Bi.gainFor(e.instrument,{fNumber:ti(e,0)?.fNumber,fieldOfViewDeg:Qi.fovOf(e,0),exposureSeconds:e.exposure});return zu(AA,t)}updateAstronomy(e){this.ensureStarsDeepEnough(),this.applySceneAt(e);const t=Ln.windowEndingAt(e,this.exposureSeconds()),i=t.seconds,n=this.degreesPerPixelAt(e),s=Ua.instants(i,n),a=Math.max(s,this.ufoElement.exposureTimes(e).length,Ln.instants(this.ufoElement.sighting.decor,ti(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:Qi.fovOf(this.ufoElement.sighting,e)/t}applySceneAt(e,t){const i=this.ufoElement.sighting;this.setWeather(gf(i,e)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),t||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,e)),this.updateMeteorShower(i,e),this.updateLightning(i,e,t!==void 0),this.sceneRenderer.setDecor(i.decor);const n=ti(i,e);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=ti(i,0),a=vr(i,0),o=Object.fromEntries(bc(vr(i,e)).map(x=>[x.id,Ef(e,i.weatherTrack,a,s,n,x.id)]));this.sceneRenderer.setCloudOffset(Ef(e,i.weatherTrack,a,s,n),o),this.sceneRenderer.setObserverPose(n??Od),this.sceneRenderer.setLensOptics(this.lensOpticsAt(e)),this.sceneRenderer.setInstrumentGain(Bi.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:Qi.fovOf(i,e),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(bt.bodyAt(i,e,this.ufoElement.steadyObserver)),this.sceneRenderer.updateDecorAnchoring(ti(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.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.pushPhenomenaAt(e);const l=n?.lat??Od.lat,c=n?.lng??Od.lng,h=Ao(i.event.time??{},c,i.event.utcOffsetHours),d={lat:l,lng:c,elevationM:n?.elevationM??0};if(this.pushSatellitesAt(h,e,d),t&&!t.sky)return;if(!h){this.sceneRenderer.setAstronomy(TA);return}const u=new Date(h.getTime()+e),f=Math.max(1,Math.round(.25*this.degreesPerPixelAt(e)/Ua.DEG_PER_SECOND*1e3)),p=Math.max(1e-8,this.degreesPerPixelAt(e)*.1),v=`${Math.floor(u.getTime()/f)}|${Math.round(l/p)}|${Math.round(c/p)}|${Math.round(d.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(v===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=v;const m={...ad("Sun",u,d),magnitude:rd("Sun",u)},g={...ad("Moon",u,d),phase:f5(u),magnitude:rd("Moon",u)},S=u5.map(x=>({body:x,position:ad(x,u,d),magnitude:rd(x,u)}));this.sceneRenderer.setAstronomy({sun:m,moon:g,planets:S,comet:this.cometAt(u,d),novae:mg.appearancesAt(u,d).map(({outburst:x,position:M,magnitude:_})=>({id:x.id,position:M,magnitude:_})),stars:this.starCatalog?{catalog:this.starCatalog,date:u,observer:d}:void 0,frame:{date:u,observer:d}}),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.isConnected&&this.dispatchEvent(new CustomEvent(bA)))},s=tf.tleArchive;(async()=>{if(!await s.covers(e))return n("outside");const[a,o]=await Promise.all([s.at(e),gi(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!a)return n("unavailable");this.satellites={snapshot:a,passes:new o.SatellitePasses(a.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const 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=ti(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 l=Ao(i.event.time??{},o,i.event.utcOffsetHours);if(!l)return[];const c=Math.min(Math.max(e,0),4*36e5),h={lat:a,lng:o,elevationM:n?.elevationM??0},d=JSON.stringify([this.satellitesFor,l.getTime(),a,o,h.elevationM,c]);if(this.satellitePassesMemo?.key===d)return this.satellitePassesMemo.passes;const u=Math.max(10,Math.ceil(c/1e3/600)),f=t.passes.passesDuring(l,new Date(l.getTime()+c),h,u);return this.satellitePassesMemo={key:d,passes:f},f}cometAt(e,t){const i=fA.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,l=new Map,c=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(Pn.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)},S=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,x=S?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};c.add(p),(S||v.aim)&&c.delete(p);const M=v.angular?.widthDeg??a.pxToDeg(v.bounds.width),_=this.sizeEstimateOf(p);_.add(M,x);const w=Uo.of(t,p);l.set(p,zi.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:w&&M>0?Tt.distanceMAt(w.widthM,M):void 0,range:_.distanceRangeAt(M),crossing:x}))}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 x=l.get(m);x&&l.set(p,{distanceM:x.distanceM*.999,basis:x.basis});break}this.depths=l;const h=i.sourceIds,d=[];for(const[p,v]of o)d.push({sourceId:p,shape:v,distanceM:l.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:c.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(ti(t,e)?.rollDeg??0)+bt.bodyAt(t,e,this.ufoElement.steadyObserver).rollDeg;this.sceneRenderer.setPhenomena(d,{projection:a,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:oi.starPointsOf(t.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(e){this.interpretationShown=e,this.updateAstronomy(this.lastTimeMs)}get accountInTheRound(){return this.inTheRound}set accountInTheRound(e){this.inTheRound=e}get compareAccount(){return this.comparing}set compareAccount(e){this.comparing=e,this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(e,t,i){const n=this.sceneRenderer.bodyGround,s=et.eyeOf(this.ufoElement.sighting,i,n);return s?et.lineOfSightMeetsGround(s,e,t,n):void 0}bodyReading(e,t){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=u=>et.eyeOf(n,u,i),a=new et(e,i,s).at(t),o=s(t);if(!a||!o)return;const l=a.eastM-o.eastM,c=a.northM-o.northM,h=a.upM-o.upM,d=Math.hypot(l,c);return{azimuthDeg:(Math.atan2(l,c)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,d)*180/Math.PI,distanceM:Math.hypot(d,h),eastM:a.eastM,northM:a.northM,aboveGroundM:a.upM-a.sizeM.heightM/2-i.heightAt(a.eastM,a.northM),sizeM:a.sizeM,attitude:a.attitude,appearance:a.appearance}}directionToBody(e,t){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>et.eyeOf(n,p,i),a=new et(e,i,s),o=a.at(t)?t:e.track[0]?.t,l=o===void 0?void 0:a.at(o),c=o===void 0?void 0:s(o);if(!l||!c)return;const h=l.eastM-c.eastM,d=l.northM-c.northM,u=l.upM-c.upM,f=Math.hypot(h,d);if(!(f===0&&u===0))return{azimuthDeg:(Math.atan2(h,d)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(u,f)*180/Math.PI}}placeBodiesAt(e,t){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],a=[];const o=this.sceneRenderer.bodyGround,l=p=>et.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new et(p,o,l).at(e)).filter(p=>p!==void 0));const c=vr(n,e),h=c.windDirectionDeg*Math.PI/180,d={x:c.windSpeed*Math.sin(h),z:-c.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,e/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],d);const u=i&&this.comparing?l(e):void 0;if(u&&(a=new Qt(n.timeline).at(e,s,u,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(fv,{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&&vr(e,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(e){const t=vr(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?Ao(n,s?.lng??0,e.event.utcOffsetHours):void 0,o=(e.event.durationSeconds??0)*1e3||e.timeline.duration||2e4,l=Math.round((a?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=pi.schedule({durationMs:o,seed:l,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?Ao(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),l=ei.schedule({ratePerHour:ei.observedRatePerHour(ei.apexPosition(n,s).altitudeDeg),durationMs:a,velocityKmS:ei.TYPICAL_VELOCITY_KM_S,seed:o}),c=Id.activeAt(n).map(d=>{const u=Id.radiantPosition(d.shower,n,s);return{entry:d,position:u,rate:Id.observedRatePerHour(d.zhr,u.altitudeDeg,d.shower.populationIndex)}}).sort((d,u)=>u.rate-d.rate)[0];if(!c||c.rate<=0){this.sceneRenderer.setMeteorShower(l,0,0);return}const h=ka.schedule({ratePerHour:c.rate,durationMs:a,velocityKmS:c.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...l],c.position.altitudeDeg,c.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=ti(t,e),a=s?.fNumber??i.fNumber;if(!n||a===void 0)return;const o=oi.focalLengthMmFor(i,Qi.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 ws.of(t.instrument,Tt.CANVAS_HEIGHT_PX,Qi.fovOf(t,e))}sizeEstimateOf(e){let t=this.sizeEstimates.get(e);return t||(t=new mA,this.sizeEstimates.set(e,t)),t}}const $c="rr0-scene";function pv(){Hg(),customElements.get($c)||customElements.define($c,tf)}const RA={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",sway:"Sway at rest",swayTitle:"How much the body holding the instrument moves the view when not walking: 1 for a person standing, 0 for a tripod. Blank: 1 (0 if the account says the observer was paralysed)",lightPollution:"Night sky",lightPollutionTitle:'The zenith of a moonless night at this place, in magnitudes per square arcsecond, as a Sky Quality Meter reads it or as the World Atlas of artificial sky brightness (Falchi et al. 2016, lightpollutionmap.info, "SQM") gives it. 22 is a natural sky; a suburb is about 19, a city centre 17. Blank: a natural sky',observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Observer 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"},observerGroup:"Observer",observerId:"ID",observerTitle:"Title",observerLastName:"Last name",observerFirstNames:"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",decorBridge:"Bridge",decorCrop:"Crop row",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorObserver:"Other observer",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",goToMilestone:"Go to this moment",confirmAccept:"Delete",confirmDecline:"Cancel",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelAdvanced:"Model from an address",decorModelFromCatalogue:"From the catalogue, which the recording names it by. Change a field and it becomes this recording's own address.",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorObserverSide:"Observer location",decorObserverSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},yc={...RA,accountBy:"Account by",unnamedObserver:"Observer {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",source:"Source",basis:{stated:"stated",derived:"derived",assumed:"assumed"},accountSource:"Go to the source: {source}",credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Replay",embedEdit:"Editor",share:"Share",embedObservation:"Embed the observation",back:"Back",embedCopy:"Copy",embedCopied:"Copied",showLabels:"Show what it states",interpretation:"Interpretation",account:"Account",interpretationBy:"{title}, by {by}",confrontation:"Against the account",confrontationDirection:"{deg}° off",confrontationWidth:"width ×{ratio}",confrontationHeight:"height ×{ratio}",showComparison:"Compare with the account",hideComparison:"Stop comparing with the account",hideLabels:"Hide what it states"},CA=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:yc},Symbol.toStringTag,{value:"Module"}));pv();const xc="https://ufoathome.org",Nd="compare-account",kd="account",xg=`${xc}/edit/`;class kr extends HTMLElement{static get observedAttributes(){return["src","show-labels",As,Ts,Nd]}shadow;sceneElement;toolbarElement;accountElement;accountPrefix;observerText;observerSelect;infoButton;infoPanel;infoAppLink;editLink;accountSourceLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;shareButton;shareDialog;shareTitle;shareMain;shareEmbed;shareBack;shareClose;shareEmbedOption;shareEmbedLabel;shareLink;shareCopy;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new bf(yc,new Yc,new Nn(["en"]),new lc({}));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;labelsShown=!1;language="en";messages=yc;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${_v}</style>${Sv}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.sceneElement=document.createElement($c),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.sceneElement.ownCredits=!1,this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.accountElement=this.shadow.getElementById("account"),this.accountPrefix=this.shadow.getElementById("account-prefix"),this.observerText=this.shadow.getElementById("observer-text"),this.observerSelect=this.shadow.getElementById("observer"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.editLink=this.shadow.getElementById("edit-link"),this.accountSourceLink=this.shadow.getElementById("account-source"),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.shareButton=document.createElement("button"),this.shareButton.type="button",this.shareButton.id="share-button",this.shareButton.setAttribute("aria-haspopup","dialog"),this.shareButton.innerHTML=$e.SHARE,this.sceneElement.ufoElement.addControl(this.shareButton),this.shareDialog=this.shadow.getElementById("share-dialog"),this.shareTitle=this.shadow.getElementById("share-title"),this.shareMain=this.shadow.getElementById("share-main"),this.shareEmbed=this.shadow.getElementById("share-embed"),this.shareBack=this.shadow.getElementById("share-back"),this.shareClose=this.shadow.getElementById("share-close"),this.shareEmbedOption=this.shadow.getElementById("share-embed-option"),this.shareEmbedLabel=this.shadow.getElementById("share-embed-label"),this.shareLink=this.shadow.getElementById("share-link"),this.shareCopy=this.shadow.getElementById("share-copy"),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-account"),this.compareButton.addEventListener("click",()=>this.setComparing(!this.sceneElement.compareAccount)),this.observerSelect.addEventListener("change",()=>this.selectObserver(this.observerSelect.value)),this.interpretationSelect.addEventListener("change",()=>void this.chooseInterpretation(this.interpretationSelect.value)),this.sceneElement.addEventListener(fv,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.shareButton.addEventListener("click",()=>this.openShare()),this.shareClose.addEventListener("click",()=>this.closeShare()),this.shareBack.addEventListener("click",()=>this.showShareView("main")),this.shareEmbedOption.addEventListener("click",()=>this.showShareView("embed")),this.shareCopy.addEventListener("click",()=>void this.copyText(this.shareLink.value,this.shareLink,this.shareCopy)),this.shareDialog.addEventListener("click",t=>{t.target===this.shareDialog&&this.closeShare()});for(const t of[this.embedReplayRadio,this.embedEditRadio])t.addEventListener("change",()=>this.refreshEmbedMarkup());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.isConnected&&this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const e=++this.localeToken,t=zr.preferencesFor(this);this.preferences=t;const i=u0(t,f0),[n,s,a]=i==="en"?[yc,{},void 0]:await Promise.all([b2(i),S2(i),Dg(i)]);if(e!==this.localeToken)return;const o=i!==this.language;this.language=i,this.messages=n,this.tags=new lc(s),this.said=new Nn(t),this.summaryBuilder=new bf(this.messages,new Yc(a),this.said,this.tags),this.accountPrefix.textContent=this.messages.accountBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const l=this.entries.find(c=>c.src===this.currentSrc);l&&this.offerInterpretations(l),this.updateCompareButton(),this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.syncLabelsToggle(),this.refreshParamSummary(),o&&this.currentSrc&&this.runAssessments(),this.shareButton.title=this.messages.share,this.shareButton.setAttribute("aria-label",this.messages.share),this.shareClose.setAttribute("aria-label",this.messages.close),this.shareBack.setAttribute("aria-label",this.messages.back),this.shareCopy.textContent=this.messages.embedCopy,this.shareEmbedLabel.textContent=this.messages.embed,this.syncShareTitle(),this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateAccountLine()}preferences=[];localeToken=0;said=new Nn(["en"]);tags=new lc({});connectedCallback(){zr.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===As||e===Ts)&&this.forwardPlayerAttributes(),e===Nd&&this.setComparing(this.hasAttribute(Nd))}forwardPlayerAttributes(){for(const e of[As,Ts]){const t=this.getAttribute(e);t===null?this.sceneElement.removeAttribute(e):this.sceneElement.setAttribute(e,t)}}async loadFromSrc(e){const t=Co.json(e);this.sceneElement.holdForNewScene(t);const i=await t;if(Array.isArray(i))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(Ss.isCase(i)){const n=Ss.sightingUrls(i,new URL(e,location.href).href);if(n.length===0)throw new Error(`${e} is a case with no sighting event: no recording to show`);await this.loadObserverUrls(n,{json:i,url:new URL(e,location.href).href})}else this.setEntries([{src:e,sighting:i}],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 observerUrls(){return this.entries.map(e=>e.src)}set observerUrls(e){this.loadObserverUrls(e)}async loadObserverUrls(e,t){const i=await Promise.all(e.map(async n=>({src:n,sighting:await Co.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.observerSelect.hidden=!i,this.observerText.hidden=i,this.observerSelect.innerHTML="";for(const s of e){const a=document.createElement("option");a.value=s.src,a.textContent=this.observerDisplayName(this.plain(s).observer)??this.messages.unnamedObserver.replace("{n}",String(e.indexOf(s)+1)),this.observerSelect.appendChild(a)}const n=e.find(s=>s.src===this.currentSrc)??e[0];n?this.selectObserver(n.src):this.updateAccountLine()}editorUrl(){if(!this.currentSrc)return xg;const e=new URL(this.currentSrc,location.href);return`${xg}?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>
8422
+ <${t} src="${n}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyText(e,t,i){try{await navigator.clipboard.writeText(e),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{t.select()}}async copyEmbedMarkup(){await this.copyText(this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){return this.currentSrc?`${xc}/play/?sighting=${encodeURIComponent(new URL(this.currentSrc,location.href).href)}`:`${xc}/play/`}shareView="main";openShare(){this.shareLink.value=this.playUrl(),this.refreshEmbedMarkup(),this.showShareView("main"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.shareLink.select()}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(e){this.shareView=e,this.shareMain.hidden=e!=="main",this.shareEmbed.hidden=e!=="embed",this.shareBack.hidden=e==="main",this.syncShareTitle()}syncShareTitle(){this.shareTitle.textContent=this.shareView==="embed"?this.messages.embedObservation:this.messages.share}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=(c,h,d)=>{const u=document.createElement("option");u.value=c,u.textContent=h,this.interpretationSelect.appendChild(u),this.interpretationLoaders.set(c,d)},s=e===this.entries.find(c=>c.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(kd,this.messages.account,()=>Promise.resolve(s));const a=this.caseSource;a&&Ss.interpretationEvents(a.json,this.plain(e).id).forEach((c,h)=>{const d=this.said.read(c.title)??`#${h+1}`,u=(c.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,u?this.messages.interpretationBy.replace("{title}",d).replace("{by}",u):d,()=>Ss.interpretationOf(c,a.url,f=>Co.json(f)))});const l=t&&[...this.interpretationSelect.options].some(c=>c.value===i)?i:kd;this.interpretationSelect.value=l,l===kd?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(l),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(e){this.sceneElement.compareAccount=e,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const e=this.sceneElement.compareAccount;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)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};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.observerDisplayName(e)??""}showConfrontation(e){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;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,l],c)=>{c>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,l&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}selectObserver(e){const t=this.entries.find(i=>i.src===e);t&&(this.currentSrc=e,this.observerSelect.value=e,this.sceneElement.documentUrl=t.src?new URL(t.src,location.href).href:void 0,this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=t.sighting,this.offerInterpretations(t),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(DA,{detail:{src:e}})))}async runAssessments(){const e=++this.assessmentToken,t=await new jv(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateAccountLine(){const e=this.entries.find(s=>s.src===this.currentSrc),t=e?this.observerDisplayName(this.plain(e).observer):void 0,i=t!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=t??"";const n=e&&this.plain(e).sources?.find(s=>/^https?:\/\//i.test(s.url??""));if(this.accountSourceLink.hidden=!n,n){this.accountSourceLink.href=n.url;const s=this.messages.accountSource.replace("{source}",n.title??n.url);this.accountSourceLink.title=s,this.accountSourceLink.setAttribute("aria-label",s)}this.editLink.hidden=!this.currentSrc,this.editLink.href=this.editorUrl(),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation)}observerDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id}plainRecordings=new WeakMap;plain(e){return this.stripped(e).recording}stripped(e){let t=this.plainRecordings.get(e.sighting);return t||(t=Vi.strip(e.sighting),this.plainRecordings.set(e.sighting,t)),t}basisOf(e,t){const i=this.stripped(e).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(l=>t.some(c=>l===c||l.startsWith(`${c}.`))).map(l=>i.at(l)),a=s.reduce((l,c)=>n[c.basis]>n[l]?c.basis:l,"stated"),o=s.filter(l=>l.basis===a&&l.rationale).map(l=>l.rationale);return{basis:a,rationales:o}}formatDate(e){const t=e.place?.[0],i=Ao(e.time??{},t?.lng??0,e.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(kr.DATE_LOCALES[this.language],{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")))}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)}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==="observer"?this.messages.observerGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const c=document.createElement("span");c.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,c.append(h),s={group:a.group,element:c},n.push(c)}const l=this.paramItem(a);s?s.element.append(l):n.push(l)}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(t=>t.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){const t=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(t&&this.appendInfoRow(this.infoObservationList,this.messages.case,t),!this.labelsShown){const s=this.formatDate(this.plain(e));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(e,kr.DATE_PATHS));const a=this.formatLocation(this.plain(e));a&&this.appendInfoRow(this.infoObservationList,this.messages.location,a,this.basisOf(e,kr.PLACE_PATHS))}const i=this.said.read(this.plain(e).description);i&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(e).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(e).tags;!this.labelsShown&&n&&n.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,n.map(s=>this.tags.name(s)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=xc,this.infoAppLink.textContent="UFO@home v0.80.1",Dn.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(e,t,i){const n=document.createElement("dt");n.textContent=t;const s=document.createElement("dd"),a=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const l=document.createElement("a");l.href=i.url,l.target="_blank",l.rel="noopener noreferrer",l.textContent=a,s.appendChild(l)}else s.append(a);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),e.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(e,t,i,n){const s=document.createElement("dt");s.textContent=t;const a=document.createElement("dd");if(a.textContent=i,n){const o=document.createElement("span");o.className=`basis basis-${n.basis}`,o.textContent=this.messages.basis[n.basis],n.rationales.length>0&&(o.title=n.rationales.join(`
8411
8423
  `)),a.append(" ",o)}e.appendChild(s),e.appendChild(a)}}const bg="rr0-sighting",DA="observerchange",Sg="rr0-eyeobserver";class IA extends kr{}function PA(){pv(),customElements.get(bg)||customElements.define(bg,kr),customElements.get(Sg)||customElements.define(Sg,IA)}PA();export{kA as $,en as A,it as B,se as C,Lp as D,Sn as E,HA as F,wt as G,lt as H,UA as I,FA as J,Ce as K,il as L,Sy as M,fl as N,Bt as O,x1 as P,tn as Q,Yo as R,Uo as S,LA as T,zA as U,ye as V,h1 as W,BA as X,xs as Y,It as Z,ji as _,NA as a,Bn as a0,c1 as a1,Tp as a2,hy as a3,Ac as a4,Eu as a5,Lc as a6,wi as a7,M1 as a8,O0 as a9,N0 as aa,rt as ab,aa as ac,tl as ad,Xi as ae,Ps as af,OA as b,ad as c,WA as d,Cc as e,Wi as f,VA as g,Je as h,R as i,gp as j,GA as k,XA as l,ry as m,Ra as n,Mh as o,m2 as p,cM as q,ot as r,Ao as s,Rt as t,$d as u,Ei as v,d1 as w,Ls as x,gy as y,_a as z};