@rr0/ufoathome 0.127.0 → 0.127.2
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.
|
@@ -1165,7 +1165,8 @@ ${U2.CSS}
|
|
|
1165
1165
|
<div id="playback-flash" class="playback-flash" aria-hidden="true"></div>
|
|
1166
1166
|
<!-- A thumbnail's only chrome (see MINIFIED_ATTRIBUTE): the played bar along the bottom edge, the time left above its right end,
|
|
1167
1167
|
the sound button in the top-right corner. Hidden in every other player. -->
|
|
1168
|
-
|
|
1168
|
+
<!-- The bar is also where a click sets the position, as on the video sites: a band taller than the line, for a pointer to find. -->
|
|
1169
|
+
<div id="mini-bar" class="mini-bar" aria-hidden="true"><div class="mini-track"><div id="mini-played" class="mini-played"></div></div></div>
|
|
1169
1170
|
<span id="mini-remaining" class="mini-remaining"></span>
|
|
1170
1171
|
<button id="mini-mute" type="button" class="mini-mute" title="Mute" aria-label="Mute" aria-pressed="false" hidden></button>
|
|
1171
1172
|
<!-- What is being played, top left over the picture as on a video site, and there with the controls
|
|
@@ -1778,13 +1779,26 @@ canvas[data-cursor="rotate"] {
|
|
|
1778
1779
|
left: 0;
|
|
1779
1780
|
right: 0;
|
|
1780
1781
|
bottom: 0;
|
|
1781
|
-
height:
|
|
1782
|
-
|
|
1782
|
+
height: 14px;
|
|
1783
|
+
cursor: pointer;
|
|
1783
1784
|
pointer-events: none;
|
|
1784
1785
|
opacity: 0;
|
|
1785
1786
|
transition: opacity 0.15s;
|
|
1786
1787
|
z-index: 3;
|
|
1787
1788
|
}
|
|
1789
|
+
.mini-track {
|
|
1790
|
+
position: absolute;
|
|
1791
|
+
left: 0;
|
|
1792
|
+
right: 0;
|
|
1793
|
+
bottom: 0;
|
|
1794
|
+
height: 3px;
|
|
1795
|
+
background: rgba(255, 255, 255, 0.3);
|
|
1796
|
+
transition: height 0.1s;
|
|
1797
|
+
}
|
|
1798
|
+
/* Thicker under the pointer, as on the video sites: it says the bar can be clicked. */
|
|
1799
|
+
.mini-bar:hover .mini-track {
|
|
1800
|
+
height: 5px;
|
|
1801
|
+
}
|
|
1788
1802
|
.mini-played {
|
|
1789
1803
|
height: 100%;
|
|
1790
1804
|
width: 0;
|
|
@@ -1832,12 +1846,15 @@ canvas[data-cursor="rotate"] {
|
|
|
1832
1846
|
}
|
|
1833
1847
|
.stage.minified:hover .mini-bar,
|
|
1834
1848
|
.stage.minified:not(.paused) .mini-bar,
|
|
1849
|
+
/* Once played, the bar stays under the cover, saying how far the reader got, as on the video sites. */
|
|
1850
|
+
.stage.minified:not(.unstarted) .mini-bar,
|
|
1835
1851
|
.stage.minified:hover .mini-mute:not([hidden]) {
|
|
1836
1852
|
opacity: 1;
|
|
1837
|
-
pointer-events: auto;
|
|
1838
1853
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1854
|
+
/* Only while hovered: at rest a click anywhere on the thumbnail, its bar included, is the page's. */
|
|
1855
|
+
.stage.minified:hover .mini-bar,
|
|
1856
|
+
.stage.minified:hover .mini-mute:not([hidden]) {
|
|
1857
|
+
pointer-events: auto;
|
|
1841
1858
|
}
|
|
1842
1859
|
/* Only where there is a hover to speak of: a touch screen keeps ":hover" on whatever was touched last,
|
|
1843
1860
|
and a focus ring on the button just tapped — either would keep the controls over the picture for
|
|
@@ -2435,9 +2452,9 @@ canvas[data-cursor="rotate"] {
|
|
|
2435
2452
|
`;class Rc{constructor(t){this.points=t}static STATIONARY_M=5;static of(t){const e=[];for(const i of t.observerTrack.allKeyframes){const{lat:n,lng:s,headingDeg:r}=i.pose;n===void 0||s===void 0||e.push({t:i.t,lat:n,lng:s,headingDeg:r})}if(e.length===0){const i=t.event.place?.[0];if(!i)return;e.push({t:0,lat:i.lat,lng:i.lng})}return new Rc(e)}static TRAVEL_M=50;get travels(){return this.spanM>Rc.TRAVEL_M}get moved(){return this.spanM>Rc.STATIONARY_M}get spanM(){const t=this.box,e=(t.south+t.north)/2,i=(t.west+t.east)/2;return Math.max(Math.abs(ue(e,t.east,e,t.west).x),Math.abs(ue(t.north,i,t.south,i).z))}get center(){const t=this.box;return{lat:(t.south+t.north)/2,lng:(t.west+t.east)/2}}boundsAround(t,e){const{lat:i,lng:n}=this.center,s=Math.max(this.spanM*(1+e),t)/2;return{north:is(0,-s,i,n).lat,south:is(0,s,i,n).lat,east:is(s,0,i,n).lng,west:is(-s,0,i,n).lng}}get box(){const t=this.points.map(i=>i.lat),e=this.points.map(i=>i.lng);return{south:Math.min(...t),north:Math.max(...t),west:Math.min(...e),east:Math.max(...e)}}}class cs{constructor(t,e){this.rotationPassed=t,this.scale=e}static SWAY_M=.012;static BREATH_M=.003;static DRIFT_YAW_DEG=.5;static DRIFT_PITCH_DEG=.4;static DRIFT_ROLL_DEG=.3;static GAZE_DRIFT_SHARE=.35;static HAND_HELD_S=.5;static HZ=[.11,.23,.17,.29,.37,.07];static of(t){const e=t.event.tags?.includes("paralysis")||(t.exposure??0)>cs.HAND_HELD_S,i=t.sway??(e?0:1);if(i>0)return new cs(Math.max(1-(t.instrument.stabilization??0),cs.GAZE_DRIFT_SHARE),i)}offsetAt(t){const e=t/1e3,i=this.scale,n=(u,d)=>Math.sin(2*Math.PI*u*e+d),[s,r,o,c,l,h]=cs.HZ;return{eastM:i*cs.SWAY_M*(.7*n(s,.3)+.3*n(c,1.9)),northM:i*cs.SWAY_M*(.6*n(o,2.2)+.4*n(l,.8)),upM:i*cs.BREATH_M*n(r,0),yawDeg:i*this.rotationPassed*cs.DRIFT_YAW_DEG*(.6*n(h,1.1)+.4*n(c,2.7)),pitchDeg:i*this.rotationPassed*cs.DRIFT_PITCH_DEG*(.5*n(r,1.6)+.5*n(o,.4)),rollDeg:i*this.rotationPassed*cs.DRIFT_ROLL_DEG*n(s,2.9)}}}class He{constructor(t,e){this.stretches=t,this.rotationPassed=e}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STOP_LURCH_M=.035;static STOP_PITCH_DEG=3;static START_LURCH_M=.015;static START_PITCH_DEG=1.2;static JOLT_HZ=1.4;static JOLT_DECAY_S=.35;static JOLT_LASTS_MS=1500;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(t){const e=Rc.of(t);if(!e||e.points.length<2)return;const i=[];let n=0;for(let s=1;s<e.points.length;s++){const r=e.points[s-1],o=e.points[s],c=(o.t-r.t)/1e3;if(c<=0)continue;const l=ue(o.lat,o.lng,r.lat,r.lng),h=l.x,u=-l.z,d=Math.hypot(h,u),f=d/c,p=He.stepHzFor(f);i.push({startMs:r.t,endMs:o.t,speedMPerS:f,eastUnit:d>0?h/d:0,northUnit:d>0?u/d:0,stepHz:p,stepsBefore:n,rampsIn:!0,rampsOut:!0}),n+=p*c}for(let s=0;s<i.length;s++){const r=i[s-1],o=i[s+1];i[s].rampsIn=r===void 0||r.stepHz===0,i[s].rampsOut=o===void 0||o.stepHz===0}if(i.some(s=>s.stepHz>0))return new He(i,1-(t.instrument.stabilization??0))}static bodyAt(t,e,i=!1){const n=He.of(t)?.offsetAt(e)??He.STILL;return i?n:He.add(n,cs.of(t)?.offsetAt(e))}static stepHzFor(t){return t<He.SLOWEST_WALK_M_PER_S||t>He.FASTEST_WALK_M_PER_S?0:He.REFERENCE_STEP_HZ*Math.pow(t/He.REFERENCE_SPEED_M_PER_S,He.CADENCE_EXPONENT)}offsetAt(t){return He.add(this.cycleAt(t),this.joltAt(t))}joltAt(t){for(const e of this.stretches){if(e.stepHz===0)continue;const i=e.speedMPerS/He.REFERENCE_SPEED_M_PER_S,n=(o,c,l,h)=>{if(o<0||o>He.JOLT_LASTS_MS)return;const u=o/1e3,d=Math.exp(-u/He.JOLT_DECAY_S)*Math.sin(2*Math.PI*He.JOLT_HZ*u),f=h*c*i*d;return{eastM:f*e.eastUnit,northM:f*e.northUnit,upM:-Math.abs(f)*.3,rollDeg:0,pitchDeg:-h*l*i*d*this.rotationPassed,yawDeg:0}},s=e.rampsOut?n(t-e.endMs,He.STOP_LURCH_M,He.STOP_PITCH_DEG,1):void 0;if(s)return s;const r=e.rampsIn?n(t-e.startMs,He.START_LURCH_M,He.START_PITCH_DEG,-1):void 0;if(r)return r}}static add(t,e){return e?{eastM:t.eastM+e.eastM,northM:t.northM+e.northM,upM:t.upM+e.upM,rollDeg:t.rollDeg+e.rollDeg,pitchDeg:t.pitchDeg+e.pitchDeg,yawDeg:t.yawDeg+e.yawDeg}:t}cycleAt(t){const e=this.stretches.find(c=>t>=c.startMs&&t<=c.endMs);if(!e||e.stepHz===0)return He.STILL;const i=e.stepsBefore+e.stepHz*(t-e.startMs)/1e3,n=2*Math.PI*i,s=this.amplitudeAt(e,t),r=He.SWAY_M*s*Math.cos(n/2),o=s*this.rotationPassed*e.speedMPerS/He.REFERENCE_SPEED_M_PER_S;return{eastM:r*e.northUnit,northM:-r*e.eastUnit,upM:He.RISE_M_PER_M_PER_S*e.speedMPerS*s*Math.cos(n),rollDeg:He.HEAD_ROLL_DEG*o*Math.cos(n/2),pitchDeg:-1.25*o*Math.cos(n),yawDeg:He.HEAD_YAW_DEG*o*Math.cos(n/2)}}amplitudeAt(t,e){const i=1e3/t.stepHz,n=Math.min(i,(t.endMs-t.startMs)/2);if(n<=0)return 1;const s=e-t.startMs,r=t.endMs-e,o=Math.min(t.rampsIn?s/n:1,t.rampsOut?r/n:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class Zw{constructor(t,e){this.timeline=t,this.onFrame=e}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const t=()=>{if(this.state!=="playing")return;const e=performance.now();if(this.currentT+=(e-this.lastWallTime)*this.playbackRate,this.lastWallTime=e,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t)};this.rafId=requestAnimationFrame(t)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(t){this.currentT=Math.max(0,Math.min(t,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(t){const e=new Map;for(const i of this.timeline.sourceIds){const n=this.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}this.onFrame(t,e)}}const ey=["nw","n","ne","e","se","s","sw","w"],Jw=24,Ch=8,jw=3,Qw=8;function Oh(a,t,e){const i=a.x-t.x,n=a.y-t.y,s=Math.cos(e),r=Math.sin(e);return{x:t.x+i*s-n*r,y:t.y+i*r+n*s}}function rl(a){return{x:a.x+a.width/2,y:a.y+a.height/2}}const tS={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 jn{static handlePointsFor(t){const{x:e,y:i,width:n,height:s}=t.bounds,r={nw:{x:e,y:i},n:{x:e+n/2,y:i},ne:{x:e+n,y:i},e:{x:e+n,y:i+s/2},se:{x:e+n,y:i+s},s:{x:e+n/2,y:i+s},sw:{x:e,y:i+s},w:{x:e,y:i+s/2},rotate:{x:e+n/2,y:i-Jw}},o=rl(t.bounds),c={};for(const l of Object.keys(r))c[l]=Oh(r[l],o,t.angle);return c}static hitTestHandle(t,e,i=8,n=[...ey,"rotate"]){const s=jn.handlePointsFor(t);for(const r of n)if(Math.hypot(e.x-s[r].x,e.y-s[r].y)<=i)return r}static HANDLE_DIRECTION_DEG={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315};static resizeAxisFor(t,e){const n=((jn.HANDLE_DIRECTION_DEG[t]+e*180/Math.PI)%180+180)%180/45,s=["ew","nwse","ns","nesw"];return s[Math.round(n)%s.length]}static resizeBounds(t,e,i,n){const s=rl(t),r=Oh(n,s,-e),{x:o,y:c,width:l,height:h}=t,u=tS[i];let d=o,f=c,p=o+l,v=c+h;return u.left&&(d=Math.min(r.x,p-Ch)),u.right&&(p=Math.max(r.x,d+Ch)),u.top&&(f=Math.min(r.y,v-Ch)),u.bottom&&(v=Math.max(r.y,f+Ch)),{x:d,y:f,width:p-d,height:v-f}}static resizeShape(t,e,i){if(e==="rotate")throw new Error("resizeShape does not accept the rotate handle");const{width:n,height:s}=t.bounds,r=jn.resizeBounds(t.bounds,t.angle,e,i);if(t.kind==="oval")return{...t,bounds:r};const o=n===0?1:r.width/n,c=s===0?1:r.height/s;return{...t,bounds:r,points:t.points.map(l=>({x:l.x*o,y:l.y*c}))}}static rotateShape(t,e){const i=rl(t.bounds),n=Math.atan2(e.y-i.y,e.x-i.x)+Math.PI/2;return{...t,angle:n}}static groupBoundsFor(t){const e=Math.min(...t.map(r=>r.x)),i=Math.min(...t.map(r=>r.y)),n=Math.max(...t.map(r=>r.x+r.width)),s=Math.max(...t.map(r=>r.y+r.height));return{x:e,y:i,width:n-e,height:s-i}}static vertexPointsFor(t){const e=rl(t.bounds);return t.points.map(i=>Oh({x:t.bounds.x+i.x,y:t.bounds.y+i.y},e,t.angle))}static hitTestVertex(t,e,i=Qw){const n=jn.vertexPointsFor(t);let s,r=i;return n.forEach((o,c)=>{const l=Math.hypot(e.x-o.x,e.y-o.y);l<=r&&(r=l,s=c)}),s}static toLocalPoint(t,e){const i=rl(t.bounds),n=Oh(e,i,-t.angle);return{x:n.x-t.bounds.x,y:n.y-t.bounds.y}}static moveVertex(t,e,i){const n=t.points.map((u,d)=>d===e?jn.toLocalPoint(t,i):u),s=Math.min(...n.map(u=>u.x)),r=Math.min(...n.map(u=>u.y)),o=Math.max(...n.map(u=>u.x)),c=Math.max(...n.map(u=>u.y)),l={x:t.bounds.x+s,y:t.bounds.y+r,width:o-s,height:c-r},h=n.map(u=>({x:u.x-s,y:u.y-r}));return{...t,bounds:l,points:h}}static insertVertexNear(t,e){const i=jn.toLocalPoint(t,e),{points:n}=t;let s=n.length-1,r=1/0;for(let c=0;c<n.length;c++){const l=n[c],h=n[(c+1)%n.length],u=jn.distanceToSegment(i,l,h);u<r&&(r=u,s=c)}const o=[...n.slice(0,s+1),i,...n.slice(s+1)];return{...t,points:o}}static distanceToSegment(t,e,i){const n=i.x-e.x,s=i.y-e.y,r=n*n+s*s,o=r===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*s)/r)),c=e.x+o*n,l=e.y+o*s;return Math.hypot(t.x-c,t.y-l)}static deleteVertex(t,e){return t.points.length<=jw?t:{...t,points:t.points.filter((i,n)=>n!==e)}}}const cp=6,Ph=cp/2,S1=20,E1=24,_1=9,A1=6,T1=7,R1=6,Fs=4;class Wc{constructor(t){this.ctx=t}starPoints=0;roll=0;clear(t,e){this.ctx.clearRect(0,0,t,e)}static paintExtent(t){const{x:e,y:i,width:n,height:s}=t.bounds,r=e+n/2,o=i+s/2,c=t.angle%(2*Math.PI)!==0,l=Math.hypot(n,s)/2,h=c?l:n/2,u=c?l:s/2,d=Math.max(n,s)/2,f=t.brightness??0,p=f>0?Math.max(d*(1+_1*f),R1*f)-d:0,v=f>0?d*(1+T1*f)-d:0,m=3*E1*(t.blur??0)+1.5*S1*t.haloScale,g=Math.max(p,v,0)+m+2;return{x:r-h-g,y:o-u-g,width:2*(h+g),height:2*(u+g)}}paintInto(t,e,i,n=!1){this.ctx.save(),this.ctx.scale(i,i),this.ctx.translate(-e.x,-e.y);const s=t.selected?{...t,selected:!1}:t;n?this.paintGhost(s,1.5):this.paintShape(s),this.ctx.restore()}paintShape(t){this.ctx.save(),this.ctx.globalAlpha=1-t.transparency;const e=t.blur??0;e>0&&(this.ctx.filter=`blur(${(E1*e).toFixed(2)}px)`);const i=t.brightness??0;i>0&&this.paintDazzle(t,i),t.haloScale>0&&this.paintHalo(t),this.paintBase(t),this.ctx.restore(),t.selected&&this.paintSelectionHandles(t)}setStarPoints(t){this.starPoints=Math.max(0,Math.floor(t))}setRoll(t){this.roll=t}paintDazzle(t,e){const{x:i,y:n,width:s,height:r}=t.bounds,o=i+s/2,c=n+r/2,l=Math.max(s,r)/2,h=Math.max(l*(1+_1*e),R1*e);if(h<=0)return;this.ctx.save(),this.ctx.globalCompositeOperation="lighter";const u=this.ctx.createRadialGradient(o,c,0,o,c,h);for(let d=0;d<=A1;d++){const f=d/A1,p=1/(1+24*f*f);this.ctx.globalAlpha=1,u.addColorStop(f,this.withAlpha(t.color,p*e*.55))}if(this.ctx.fillStyle=u,this.ctx.beginPath(),this.ctx.arc(o,c,h,0,2*Math.PI),this.ctx.fill(),this.starPoints>0){const d=l*(1+T1*e);this.ctx.lineWidth=Math.max(1,l*.12),this.ctx.lineCap="round";for(let f=0;f<this.starPoints;f++){const p=f/this.starPoints*Math.PI*2+this.roll,v=o+Math.cos(p)*d,m=c+Math.sin(p)*d,g=this.ctx.createLinearGradient(o,c,v,m);g.addColorStop(0,this.withAlpha(t.color,e*.55)),g.addColorStop(.35,this.withAlpha(t.color,e*.22)),g.addColorStop(1,this.withAlpha(t.color,0)),this.ctx.strokeStyle=g,this.ctx.beginPath(),this.ctx.moveTo(o,c),this.ctx.lineTo(v,m),this.ctx.stroke()}}this.ctx.restore()}dazzledFill(t,e){if(e<=0)return t.color;const i=/^#([0-9a-f]{6})$/i.exec(t.color.trim());if(!i)return t.color;const n=Number.parseInt(i[1],16),s=r=>Math.round(r+(255-r)*e);return`rgb(${s(n>>16&255)}, ${s(n>>8&255)}, ${s(n&255)})`}withAlpha(t,e){const i=Math.max(0,Math.min(1,e)),n=/^#([0-9a-f]{6})$/i.exec(t.trim());if(!n)return t;const s=Number.parseInt(n[1],16);return`rgba(${s>>16&255}, ${s>>8&255}, ${s&255}, ${i.toFixed(3)})`}paintBase(t){this.ctx.fillStyle=this.dazzledFill(t,t.brightness??0),this.tracePath(t),this.ctx.fill()}paintGhost(t,e){this.ctx.save(),this.tracePath(t),this.ctx.setLineDash([e*3,e*2]),this.ctx.lineWidth=e,this.ctx.strokeStyle=t.color,this.ctx.stroke(),this.ctx.restore()}tracePath(t){if(this.ctx.beginPath(),t.kind==="oval"){const{x:e,y:i,width:n,height:s}=t.bounds,r=n/2,o=s/2;this.ctx.ellipse(e+r,i+o,r,o,t.angle,0,2*Math.PI)}else{const{x:e,y:i,width:n,height:s}=t.bounds;this.ctx.save(),this.ctx.translate(e+n/2,i+s/2),this.ctx.rotate(t.angle),this.ctx.translate(-n/2,-s/2),t.points.forEach((r,o)=>{o===0?this.ctx.moveTo(r.x,r.y):this.ctx.lineTo(r.x,r.y)}),this.ctx.closePath(),this.ctx.restore()}}paintHalo(t){this.ctx.save(),this.ctx.shadowColor=t.color,this.ctx.shadowBlur=S1*t.haloScale,this.paintBase(t),this.ctx.restore()}paintSelectionHandles(t){this.paintHandleFrame(jn.handlePointsFor(t),{includeRotate:!0}),t.kind==="polygon"&&this.paintVertexHandles(t)}paintVertexHandles(t){this.ctx.fillStyle="#39f";for(const e of jn.vertexPointsFor(t))this.ctx.beginPath(),this.ctx.ellipse(e.x,e.y,Fs,Fs,0,0,2*Math.PI),this.ctx.fill()}paintMemberOutline(t){this.paintOutline(jn.handlePointsFor(t))}paintSelectionOnly(t){this.paintSelectionHandles(t)}paintPictureFrame(t,e,i){const n=this.ctx;if(n.save(),t&&t.length===4){n.strokeStyle="#39f",n.lineWidth=1.5,n.setLineDash([6,4]),n.beginPath(),n.moveTo(t[0].x,t[0].y);for(const s of t.slice(1))n.lineTo(s.x,s.y);n.closePath(),n.stroke(),n.setLineDash([])}for(const s of e){const r=Wc.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,Fs+2,Fs+2,0,0,2*Math.PI),n.stroke()),s.scene&&(n.strokeStyle=r,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=r,n.beginPath(),n.ellipse(s.scene.x,s.scene.y,Fs,Fs,0,0,2*Math.PI),n.fill()),n.strokeStyle=r,n.lineWidth=o,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,Fs+2,Fs+2,0,0,2*Math.PI),n.stroke(),this.paintLabel(s.label,s.picture.x+Fs+5,s.picture.y-Fs-2,r)}i&&this.paintLabel(i,8,8,"#fff",13),n.restore()}static landmarkColour(t){return t===void 0?"#ffb000":t<=1?"#3c3":t<=3?"#ffb000":"#f33"}paintLabel(t,e,i,n,s=11){const r=this.ctx;r.save(),r.font=`${s}px system-ui, sans-serif`,r.textBaseline="top";const o=r.measureText(t).width;r.fillStyle="rgba(0, 0, 0, 0.6)",r.fillRect(e-3,i-2,o+6,s+4),r.fillStyle=n,r.fillText(t,e,i),r.restore()}paintGroupHandles(t){this.paintHandleFrame(jn.handlePointsFor({bounds:t,angle:0}),{includeRotate:!0})}paintOutline(t){this.ctx.strokeStyle="lightgray",this.ctx.beginPath(),this.ctx.moveTo(t.nw.x,t.nw.y),this.ctx.lineTo(t.ne.x,t.ne.y),this.ctx.lineTo(t.se.x,t.se.y),this.ctx.lineTo(t.sw.x,t.sw.y),this.ctx.closePath(),this.ctx.stroke()}paintHandleFrame(t,{includeRotate:e}){this.paintOutline(t),this.ctx.fillStyle="lightgray";for(const i of ey){const n=t[i];this.ctx.fillRect(n.x-Ph,n.y-Ph,cp,cp)}e&&(this.ctx.beginPath(),this.ctx.moveTo(t.n.x,t.n.y),this.ctx.lineTo(t.rotate.x,t.rotate.y),this.ctx.stroke(),this.ctx.beginPath(),this.ctx.ellipse(t.rotate.x,t.rotate.y,Ph+1,Ph+1,0,0,2*Math.PI),this.ctx.fill())}}const I1=.05,D1=.08,C1=2,O1=3,eS=14,iS=.02;class nS{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",t);return}}ho.unlock(this.context)}setSound(t){if(this.requested=t,!this.context)return;const e=this.keyFor(t);if(!e){this.silence();return}if(this.voice?.key!==e){this.stopVoice();const i=++this.voiceToken;e.startsWith("src:")?this.buildRecordedVoice(t.src,e,i):this.voice=this.buildSynthesizedVoice(t,e)}this.applyTo(this.voice,t)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(t){if(!(t.volume<=0))return t.src?`src:${t.src}`:t.kind==="none"?void 0:t.kind}applyTo(t,e){const i=this.context;if(!t||!i)return;const n=i.currentTime;t.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,e.volume))*t.gainScale,n,I1);for(const{param:s,ratio:r}of t.pitch)s.setTargetAtTime(Math.min(e.pitchHz*r,i.sampleRate/2-1),n,I1)}buildSynthesizedVoice(t,e){const i=this.context;if(i)switch(t.kind){case"hum":return this.buildHum(i,e);case"whistle":return this.buildWhistle(i,e);case"rumble":return this.buildRumble(i,e);case"crackle":return this.buildCrackle(i,e);default:return}}buildHum(t,e){const i=t.createOscillator();i.type="sawtooth";const n=t.createOscillator();n.type="sawtooth";const s=t.createBiquadFilter();s.type="lowpass",s.Q.value=1;const r=t.createGain();return r.gain.value=0,i.connect(s),n.connect(s),s.connect(r).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,r],sources:[i,n],volumeParam:r.gain,gainScale:.16,pitch:[{param:i.frequency,ratio:1},{param:n.frequency,ratio:1.006},{param:s.frequency,ratio:6}]}}buildWhistle(t,e){const i=t.createOscillator();i.type="sine";const n=t.createOscillator();n.type="sine",n.frequency.value=5;const s=t.createGain(),r=t.createGain();return r.gain.value=0,n.connect(s).connect(i.frequency),i.connect(r).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,r],sources:[i,n],volumeParam:r.gain,gainScale:.22,pitch:[{param:i.frequency,ratio:1},{param:s.gain,ratio:.012}]}}buildRumble(t,e){const i=t.createBufferSource();i.buffer=this.brownNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="lowpass",n.Q.value=.8;const s=t.createGain();return s.gain.value=0,i.connect(n).connect(s).connect(this.output(t)),i.start(),{key:e,nodes:[n,s],sources:[i],volumeParam:s.gain,gainScale:1.4,pitch:[{param:n.frequency,ratio:1}]}}buildCrackle(t,e){const i=t.createBufferSource();i.buffer=this.whiteNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="bandpass",n.Q.value=1.2;const s=t.createGain();s.gain.value=0;const r=t.createBufferSource();r.buffer=this.crackleEnvelope(t),r.loop=!0;const o=t.createGain();return o.gain.value=0,r.connect(o).connect(s.gain),i.connect(n).connect(s).connect(this.output(t)),i.start(),r.start(),{key:e,nodes:[n,s,o],sources:[i,r],volumeParam:o.gain,gainScale:.9,pitch:[{param:n.frequency,ratio:4}]}}async buildRecordedVoice(t,e,i){const n=this.context;if(!n)return;let s;try{s=await this.getBuffer(t)}catch(c){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",c);return}if(i!==this.voiceToken||!this.context)return;const r=n.createBufferSource();r.buffer=s,r.loop=!0;const o=n.createGain();o.gain.value=0,r.connect(o).connect(this.output(n)),r.start(),this.voice={key:e,nodes:[o],sources:[r],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(t){const e=this.context;if(!e)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}whiteNoise(t){if(!this.noiseBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*C1),t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;this.noiseBuffer=e}return this.noiseBuffer}brownNoise(t){const e=t.createBuffer(1,Math.floor(t.sampleRate*C1),t.sampleRate),i=e.getChannelData(0);let n=0,s=0;for(let r=0;r<i.length;r++)n=(n+.02*(Math.random()*2-1))/1.02,i[r]=n,s=Math.max(s,Math.abs(n));if(s>0)for(let r=0;r<i.length;r++)i[r]/=s;return e}crackleEnvelope(t){if(!this.crackleBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*O1),t.sampleRate),i=e.getChannelData(0),n=Math.max(1,Math.floor(iS*t.sampleRate)),s=Math.round(O1*eS);for(let r=0;r<s;r++){const o=Math.floor(Math.random()*i.length),c=.4+Math.random()*.6;for(let l=0;l<n&&o+l<i.length;l++)i[o+l]=Math.max(i[o+l],c*(1-l/n))}this.crackleBuffer=e}return this.crackleBuffer}stopVoice(){const t=this.voice,e=this.context;if(this.voice=void 0,!t||!e)return;const i=e.currentTime;t.volumeParam.cancelScheduledValues(i),t.volumeParam.setTargetAtTime(0,i,D1/3);const n=i+D1;for(const s of t.sources){s.onended=()=>{s.disconnect();for(const r of t.nodes)r.disconnect()};try{s.stop(n)}catch{s.disconnect();for(const r of t.nodes)r.disconnect()}}}}function Bl(a){return[...a].sort((t,e)=>t.t-e.t)}function Rf(a,t){let e;for(const i of Bl(a)){if(i.t>t)break;e=i}return e}const If=Math.PI/180,Lh=180/Math.PI;class Pr{constructor(t,e,i){this.kind=t,this.canvasHeightPx=e,this.fovDeg=i;const n=i*If/2;this.focalPx=t==="equidistant"?e/2/n:e/2/Math.tan(n)}focalPx;static of(t,e,i){return new Pr(t.projection,e,i)}degToPx(t){const e=t*If;return this.kind==="equidistant"?this.focalPx*e:2*this.focalPx*Math.tan(e/2)}pxToDeg(t){return this.kind==="equidistant"?t/this.focalPx*Lh:2*Math.atan(t/(2*this.focalPx))*Lh}angleDegToRadiusPx(t){const e=t*If;return this.kind==="equidistant"?this.focalPx*e:this.focalPx*Math.tan(e)}halfWidthAngleDeg(t){return this.radiusPxToAngleDeg(this.canvasHeightPx*t/2)}radiusPxToAngleDeg(t){return this.kind==="equidistant"?t/this.focalPx*Lh:Math.atan(t/this.focalPx)*Lh}ofBounds(t){return{widthDeg:this.pxToDeg(t.width),heightDeg:this.pxToDeg(t.height)}}toBoundsSize(t){return{width:this.degToPx(t.widthDeg),height:this.degToPx(t.heightDeg)}}widthPx(t){return this.degToPx(qe.angularWidthDeg(t))}}class Hn{static fovOf(t,e){return ei(t,e)?.fovDeg??Li.fieldOfViewDeg(t.instrument)}static toAngular(t){this.eachKeyframe(t,(e,i)=>({...e,angular:i.ofBounds(e.bounds)}))}static toBounds(t){this.eachKeyframe(t,(e,i)=>{if(!e.angular)return e;const{width:n,height:s}=i.toBoundsSize(e.angular),r={x:e.bounds.x+(e.bounds.width-n)/2,y:e.bounds.y+(e.bounds.height-s)/2,width:n,height:s};if(e.kind!=="polygon")return{...e,bounds:r};const o=e.bounds.width===0?1:n/e.bounds.width,c=e.bounds.height===0?1:s/e.bounds.height;return{...e,bounds:r,points:e.points.map(l=>({x:l.x*o,y:l.y*c}))}})}static toAim(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);if(s&&Math.abs(s.x-e.bounds.x)<Hn.UNMOVED_PX&&Math.abs(s.y-e.bounds.y)<Hn.UNMOVED_PX)return e;const r=this.aimFrom(t,i,n,e.bounds);return r?{...e,aim:r}:e})}static UNMOVED_PX=.01;static aimOf(t,e,i){const n=Pr.of(t.instrument,qe.CANVAS_HEIGHT_PX,this.fovOf(t,e));return this.aimFrom(t,n,ei(t,e),i)}static aimFrom(t,e,i,n){if(i?.headingDeg===void 0)return;const s=this.frameCentre(t),r=e.radiusPxToAngleDeg(n.x+n.width/2-s.x),o=e.radiusPxToAngleDeg(s.y-(n.y+n.height/2));return{azimuthDeg:((i.headingDeg+r)%360+360)%360,altitudeDeg:i.pitchDeg+o}}static toPosition(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);return s?{...e,bounds:{...e.bounds,...s}}:e})}static positionOf(t,e,i,n,s){if(s?.headingDeg===void 0)return;const r=this.frameCentre(t),o=this.shortestArc(e.azimuthDeg-s.headingDeg),c=e.altitudeDeg-s.pitchDeg;return{x:r.x+this.offAxisPx(n,o)-i.width/2,y:r.y-this.offAxisPx(n,c)-i.height/2}}static frameCentre(t){return{x:Li.frameWidthPx(t.instrument,qe.CANVAS_HEIGHT_PX)/2,y:qe.CANVAS_HEIGHT_PX/2}}static shortestArc(t){return(t%360+540)%360-180}static offAxisPx(t,e){return Math.abs(e)>=Hn.OFF_CANVAS_DEG?Math.sign(e)*Hn.OFF_CANVAS_PX:t.angleDegToRadiusPx(e)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(t,e,i){const n=Li.frameWidthPx(e,qe.CANVAS_HEIGHT_PX)/2,s=Li.frameWidthPx(t.instrument,qe.CANVAS_HEIGHT_PX)/2,r=qe.CANVAS_HEIGHT_PX/2;for(const o of[...t.timeline.allKeyframes]){const c=this.fovOf(t,o.t),l=i?.get(o.t)??c,h=Pr.of(e,qe.CANVAS_HEIGHT_PX,l),u=Pr.of(t.instrument,qe.CANVAS_HEIGHT_PX,c);t.timeline.addKeyframe(o.t,o.shapes.map(d=>{const{bounds:f}=d.shape,p=f.x+f.width/2-n,v=f.y+f.height/2-r,m=Math.hypot(p,v),g=m===0?1:u.angleDegToRadiusPx(h.radiusPxToAngleDeg(m))/m,y={...f,x:s+p*g-f.width/2,y:r+v*g-f.height/2};return{...d,shape:{...d.shape,bounds:y}}}))}this.toBounds(t)}static eachKeyframe(t,e){const{timeline:i}=t;for(const n of[...i.allKeyframes]){const s=ei(t,n.t),r=this.fovOf(t,n.t),o=Pr.of(t.instrument,qe.CANVAS_HEIGHT_PX,r);i.addKeyframe(n.t,n.shapes.map(c=>({...c,shape:e(c.shape,o,s)})))}}}function sS(a){return Tn.restore(rS(a),a.provenance)}function rS(a){return Hn.toAngular(a),Hn.toAim(a),{version:1,id:a.id,time:a.event.time,endTime:a.event.endTime,durationSeconds:a.event.durationSeconds,durationText:a.event.durationText,utcOffsetHours:a.event.utcOffsetHours,timeZone:a.event.timeZone,place:a.event.place,observer:a.observer,account:a.account,sources:a.sources?.length?a.sources:void 0,sway:a.sway,vehicle:a.vehicle,description:a.event.description,image:a.event.image,summary:a.event.summary,summaryTime:a.event.summaryTime,tags:a.event.tags,timeline:a.timeline.toJSON(),observerTrack:a.observerTrack.toJSON(),weatherTrack:a.weatherTrack.toJSON(),soundTrack:a.soundTrack.toJSON(),weather:a.weather,decor:a.decor,milestones:a.milestones.length>0?a.milestones:void 0,references:a.references.length>0?a.references:void 0,roads:a.roads.length>0?a.roads:void 0,traces:a.traces.length>0?a.traces:void 0,weatherSource:a.weatherSource,instrument:a.instrumentId,exposureSeconds:a.exposureSeconds,iso:a.iso,lightPollution:a.lightPollution,observerMap:a.observerMap,interpretation:a.interpretation}}function aS(a){const{recording:t,provenance:e}=Tn.strip(a),i=oS(t);return i.provenance=e,i}function oS(a){const t=[],e=new cf({eventType:"sighting",time:a.time,endTime:a.endTime,durationSeconds:a.durationSeconds,durationText:a.durationText,utcOffsetHours:a.utcOffsetHours,timeZone:a.timeZone,place:a.place,description:a.description,image:a.image,summary:a.summary,summaryTime:a.summaryTime,tags:a.tags},nf.fromJSON(a.timeline,t),a.observerTrack?ih.fromJSON(a.observerTrack):new ih,a.weatherTrack?nh.fromJSON(a.weatherTrack):new nh,a.soundTrack?sh.fromJSON(a.soundTrack):new sh,a.observer&&{id:a.observer.id,title:a.observer.title,lastName:a.observer.lastName,firstNames:a.observer.firstNames},a.id,a.weather,a.decor??[],a.weatherSource,a.instrument,a.exposureSeconds??a.observerTrack?.keyframes.map(i=>i.pose.exposureSeconds).find(i=>i!==void 0),Bl(a.milestones??[]),a.references??[],a.roads??[],a.traces??[]);return e.account=a.account,e.sources=a.sources,e.sway=a.sway,e.iso=a.iso,e.lightPollution=a.lightPollution,e.observerMap=a.observerMap,e.vehicle=a.vehicle,e.interpretation=a.interpretation,e.loadIssues=t,Hn.toBounds(e),Hn.toPosition(e),e}class Xc{static EN={"unknown-key":"{path}: unknown key, ignored","wrong-type":"{path}: expected {expected}, found {found}","not-in-list":"{path}: {found} is not one of {expected}",defaulted:"{path}: missing, {expected} used",unplaced:"{path}: no aim (and no bounds), drawn at the middle of the view",unsized:"{path}: no angular size (and no bounds), drawn one pixel wide","pixels-over-angles":"{path}: bounds restated without aim or angular, so the shape follows the pixels"};static text(t,e=Xc.EN){return e[t.kind].replace("{path}",t.path).replace("{expected}",t.expected??"").replace("{found}",t.found??"")}static warn(t,e){if(t.length===0)return;const i=t.map(n=>` ${Xc.text(n)}`);console.warn(`UFO@home: ${t.length} problem(s) in ${e??"this recording"}:
|
|
2436
2453
|
${i.join(`
|
|
2437
2454
|
`)}`)}}class ws{constructor(t){this.format=t}issues(t){const e=[];return this.object(t,this.format,"",e),e}object(t,e,i,n){if(!ws.isObject(t)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:ws.typeOf(t)});return}for(const[s,r]of Object.entries(t)){const o=i?`${i}.${s}`:s,c=e[s];c?this.field(r,c,o,n):n.push({kind:"unknown-key",path:o})}}field(t,e,i,n){if(ws.isStated(t)){this.field(t.value,e,i,n);return}if(!(e.loose||t===void 0||t===null))switch(e.type){case"enum":(typeof t!="string"||!e.values?.includes(t))&&n.push({kind:"not-in-list",path:i,expected:(e.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(t)});return;case"object":e.fields?this.object(t,e.fields,i,n):ws.isObject(t)||n.push({kind:"wrong-type",path:i,expected:"object",found:ws.typeOf(t)});return;case"array":Array.isArray(t)?e.fields&&t.forEach((s,r)=>{const o=ws.isStated(s)?s.value:s;this.object(o,e.fields,`${i}.${r}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:ws.typeOf(t)});return;default:typeof t!==e.type&&n.push({kind:"wrong-type",path:i,expected:e.type,found:ws.typeOf(t)})}}static isObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}static isStated(t){return ws.isObject(t)&&"value"in t&&Object.keys(t).every(e=>e==="value"||e==="basis"||e==="rationale")}static typeOf(t){return Array.isArray(t)?"array":t===null?"null":typeof t}}class Ts{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(t,e){const i=Number.isFinite(e)?Math.max(0,e):0,n=Math.max(0,t-i*1e3),s=Math.max(0,t-n);return{fromMs:n,toMs:t,ms:s,seconds:s/1e3}}static instants(t,e,i,n,s){if(!(n>0))return 1;const r=s>0?Ts.travelDegOver(t,e,i,i+n*1e3)/s/Ts.PIXELS_PER_INSTANT:0,o=Ts.flashesOver(t,n)*Ts.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(r,o));return c<2?1:Math.min(Ts.MAX_INSTANTS,c)}static travelDegOver(t,e,i,n){let s=0;for(const r of t){if(!r.track||r.track.length<2)continue;const o=Ts.directionAt(r,e,i),c=Ts.directionAt(r,e,n),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));s=Math.max(s,Math.acos(l)*180/Math.PI)}return s}static flashesOver(t,e){let i=0;for(const n of t)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*e}static directionAt(t,e,i){const n=or(t,i),s=n.eastM,r=n.altitudeM-e,o=n.northM,c=Math.hypot(s,r,o);return c===0?{x:0,y:1,z:0}:{x:s/c,y:r/c,z:o/c}}}const Gm=["en","fr","es","it"],cS={en:()=>Xe(()=>Promise.resolve().then(()=>fS),void 0,import.meta.url).then(a=>a.ufoMessages_en),fr:()=>Xe(()=>import("./UfoMessages_fr-Cs2GCHEt.js"),[],import.meta.url).then(a=>a.ufoMessages_fr),es:()=>Xe(()=>import("./UfoMessages_es-BRCWkzr3.js"),[],import.meta.url).then(a=>a.ufoMessages_es),it:()=>Xe(()=>import("./UfoMessages_it-B2hvjhgb.js"),[],import.meta.url).then(a=>a.ufoMessages_it)};function lS(a){return cS[a]()}const hS={en:()=>Xe(()=>Promise.resolve().then(()=>t8),void 0,import.meta.url).then(a=>a.sightingMessages_en),fr:()=>Xe(()=>import("./SightingMessages_fr-ylqIoox7.js"),[],import.meta.url).then(a=>a.sightingMessages_fr),es:()=>Xe(()=>import("./SightingMessages_es-OXYzPf-m.js"),[],import.meta.url).then(a=>a.sightingMessages_es),it:()=>Xe(()=>import("./SightingMessages_it-B9f92W5s.js"),[],import.meta.url).then(a=>a.sightingMessages_it)};function uS(a){return hS[a]()}function dS(a){switch(a){case"fr":return Xe(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(t=>t.tagNames_fr);case"es":return Xe(()=>import("./TagNames_es-BfnMpc3D.js"),[],import.meta.url).then(t=>t.tagNames_es);case"it":return Xe(()=>import("./TagNames_it-n6E4EGYO.js"),[],import.meta.url).then(t=>t.tagNames_it);default:return Promise.resolve({})}}function iy(a){switch(a){case"fr":return Xe(()=>import("./SceneNames_fr-BtjbcaRx.js"),[],import.meta.url).then(t=>t.sceneNames_fr);case"es":return Xe(()=>import("./SceneNames_es-VHJ-mGWu.js"),[],import.meta.url).then(t=>t.sceneNames_es);case"it":return Xe(()=>import("./SceneNames_it-Ck8f90Z6.js"),[],import.meta.url).then(t=>t.sceneNames_it);default:return Promise.resolve(void 0)}}const ny={play:"Play",clickToPlay:"Click to 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",noSound:"No sound recorded",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",showTraces:"Show the investigator's lines",hideTraces:"Hide the investigator's lines",referenceOpacity:"Picture opacity",referencesMenu:"Pictures of the place",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:Xc.EN},fS=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:ny},Symbol.toStringTag,{value:"Module"})),sy=Math.PI/180,pS=180/Math.PI,mS=256,ry=19,gS=1.25;function ay(a,t){return 156543.03392*Math.cos(a*sy)/2**t}function oy(a,t){return ay(a,t)*mS}function vS(a,t){let e=0;for(;e<ry&&oy(a,e+1)>=t;)e++;return e}function cy(a,t){return oy(a,t)}function MS(a,t){const e=t*gS;let i=0;for(;i<ry&&ay(a,i)>e;)i++;return i}function Hu(a){const t=a*sy;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}function ly(a,t,e){const i=2**e;return{x:(a+180)/360*i,y:Hu(t)*i}}function hy(a,t,e){const i=Hu(a.north),n=Hu(a.south);return{x:(t-a.west)/(a.east-a.west),y:(Hu(e)-i)/(n-i)}}function yS(a,t,e){const{x:i,y:n}=ly(a,t,e);return{x:Math.floor(i),y:Math.floor(n),z:e}}function xS(a){const t=2**a.z,e=a.x/t*360-180,i=(a.x+1)/t*360-180,n=P1(a.y,t);return{south:P1(a.y+1,t),north:n,west:e,east:i}}function P1(a,t){const e=a/t;return Math.atan(Math.sinh(Math.PI*(1-2*e)))*pS}function uy(a,t,e,i){const n=yS(a,t,e),s=Math.floor(i/2),r=[];for(let l=-s;l<=s;l++)for(let h=-s;h<=s;h++)r.push({x:n.x+h,y:n.y+l,z:e});const o=r.map(xS),c={south:Math.min(...o.map(l=>l.south)),north:Math.max(...o.map(l=>l.north)),west:Math.min(...o.map(l=>l.west)),east:Math.max(...o.map(l=>l.east))};return{tiles:r,bounds:c}}const bS="#2ec4ff";class za{constructor(t){this.ctx=t}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(t,e){let i,n=1/0;for(const s of this.targets){const r=Math.hypot(s.x-t,s.y-e);r>s.radius||r>n||(i=s,n=r)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(t){const{ctx:e}=this;e.save(),this.targets=[],e.clearRect(0,0,this.width,this.height),this.paintGround(t),this.paintNight(t.nightFraction),this.paintPath(t),this.paintTraces(t),t.position?(this.paintCone(t,t.position),this.paintDecor(t),this.paintMarkers(t),this.paintObserver(t,t.position)):(this.paintDecor(t),this.paintMarkers(t)),this.paintNorth(),this.paintFooter(t.bounds,t.attribution),e.restore()}toCanvas(t,e,i){const n=hy(t,i,e);return{x:n.x*this.width,y:n.y*this.height}}paintGround(t){const{ctx:e}=this;e.fillStyle="#1d2321",e.fillRect(0,0,this.width,this.height);const i=t.imagery;if(!i)return;const n=this.toCanvas(t.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(t.bounds,i.bounds.south,i.bounds.east);e.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(t=0){if(t<=0)return;const{ctx:e}=this;e.save(),e.fillStyle=`rgba(6, 12, 30, ${Math.min(t,1)*.78})`,e.fillRect(0,0,this.width,this.height),e.restore()}paintDecor(t){const{ctx:e}=this;for(const i of t.decor){const n=this.toCanvas(t.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),e.beginPath(),e.rect(n.x-3.5,n.y-3.5,7,7),e.fillStyle="rgba(120, 220, 255, 0.85)",e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.7)",e.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),e.lineWidth=3,e.strokeStyle="rgba(0, 0, 0, 0.6)",e.stroke(),e.lineWidth=1.5,e.strokeStyle="rgba(120, 220, 255, 0.9)",e.stroke()}}paintPath(t){if(!t.path.moved)return;const{ctx:e}=this,i=t.path.points.map(n=>this.toCanvas(t.bounds,n.lat,n.lng));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))e.lineTo(n.x,n.y);e.lineJoin="round",e.lineCap="round",e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=5,e.stroke(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.stroke()}paintTraces(t){const{ctx:e}=this;for(const i of t.traces??[]){const n=i.points.map(r=>this.toCanvas(t.bounds,r.lat,r.lng));if(n.length===0)continue;const s=i.color??bS;if(i.kind==="point")e.beginPath(),e.moveTo(n[0].x,n[0].y-6),e.lineTo(n[0].x+6,n[0].y),e.lineTo(n[0].x,n[0].y+6),e.lineTo(n[0].x-6,n[0].y),e.closePath(),e.fillStyle=s,e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.8)",e.stroke();else{e.beginPath(),e.moveTo(n[0].x,n[0].y);for(const r of n.slice(1))e.lineTo(r.x,r.y);i.kind==="polygon"&&e.closePath(),e.lineJoin="round",e.setLineDash([]),e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=4.5,e.stroke(),e.setLineDash([9,5]),e.strokeStyle=s,e.lineWidth=2.5,e.stroke(),e.setLineDash([])}if(i.label){e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle";let r=n[0];if(i.kind==="line"&&t.position){const o=this.toCanvas(t.bounds,t.position.lat,t.position.lng);r=n.reduce((c,l)=>Math.hypot(l.x-o.x,l.y-o.y)>Math.hypot(c.x-o.x,c.y-o.y)?l:c)}this.paintOutlinedText(i.label,r.x+9,r.y-9)}}}paintCone(t,e){const{headingDeg:i,coneHalfAngleDeg:n}=t;if(i===void 0||n===void 0)return;const{ctx:s}=this,r=this.toCanvas(t.bounds,e.lat,e.lng),o=Math.hypot(this.width,this.height),c=(i-90)*Math.PI/180,l=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(r.x,r.y),s.arc(r.x,r.y,o,c-l,c+l),s.closePath();const h=s.createRadialGradient(r.x,r.y,0,r.x,r.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(t){const{ctx:e}=this;e.textAlign="center",e.textBaseline="middle",e.font="bold 10px sans-serif";for(const i of[...t.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(t.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:za.MARKER_RADIUS_PX}),e.beginPath(),e.arc(n.x,n.y,za.MARKER_RADIUS_PX,0,Math.PI*2),e.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",e.fill(),e.lineWidth=2,e.strokeStyle="rgba(255, 255, 255, 0.9)",e.stroke(),e.fillStyle=i.current?"#1d2321":"#fff",e.fillText(i.label,n.x,n.y)}}paintObserver(t,e){const{ctx:i}=this,n=this.toCanvas(t.bounds,e.lat,e.lng);t.observerLabel&&this.targets.push({kind:"observer",label:t.observerLabel,lat:e.lat,lng:e.lng,x:n.x,y:n.y,radius:8});const s=t.markers.some(r=>{if(!r.current)return!1;const o=ue(r.lat,r.lng,e.lat,e.lng);return Math.hypot(o.x,o.z)<=za.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?za.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:t}=this,e=this.width-14,i=16;t.beginPath(),t.moveTo(e,i-9),t.lineTo(e-4.5,i+5),t.lineTo(e,i+2),t.lineTo(e+4.5,i+5),t.closePath(),t.fillStyle="rgba(255, 255, 255, 0.92)",t.strokeStyle="rgba(0, 0, 0, 0.6)",t.lineWidth=1,t.fill(),t.stroke(),t.font="bold 9px sans-serif",t.textAlign="center",t.textBaseline="top",t.strokeText("N",e,i+6),t.fillText("N",e,i+6)}paintFooter(t,e){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=e?this.wrap(e,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const r=(t.south+t.north)/2,c=Math.abs(ue(r,t.east,r,t.west).x)/this.width,l=za.SCALE_STEPS_M.find(f=>f/c<=this.width/3);if(l===void 0)return;const h=l/c,u=8,d=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(u,d),i.lineTo(u+h,d),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(l>=1e3?`${l/1e3} km`:`${l} m`,u,d-3)}paintOutlinedText(t,e,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(t,e,i),n.fillStyle="#fff",n.fillText(t,e,i)}wrap(t,e){const i=[];let n="";for(const s of t.split(" ")){const r=n?`${n} ${s}`:s;n&&this.ctx.measureText(r).width>e?(i.push(n),n=s):n=r}return n&&i.push(n),i}}class fi{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(t,e,i){const n=Math.min(fi.MAX_ZOOM,Math.max(fi.MIN_ZOOM,this.zoom*i)),s=this.centerX+(t-.5)/this.zoom,r=this.centerY+(e-.5)/this.zoom;this.centerX=s-(t-.5)/n,this.centerY=r-(e-.5)/n,this.zoom=n}panBy(t,e){this.centerX-=t/this.zoom,this.centerY-=e/this.zoom}refit(t,e){if(!this.changed)return;const i=this.boundsWithin(t),n=fi.mercatorY01(e.north),s=fi.mercatorY01(e.south),r=fi.mercatorY01(i.north),o=fi.mercatorY01(i.south);this.zoom=(e.east-e.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-e.west)/(e.east-e.west),this.centerY=((r+o)/2-n)/(s-n)}keepInView(t,e,i){if(!this.changed)return!1;const n=this.boundsWithin(t),s=fi.mercatorY01(n.north),r=fi.mercatorY01(n.south),o=(e.lng-n.west)/(n.east-n.west),c=(fi.mercatorY01(e.lat)-s)/(r-s);return o>=i&&o<=1-i&&c>=i&&c<=1-i?!1:(this.panBy(.5-o,.5-c),!0)}boundsWithin(t){if(!this.changed)return t;const e=.5/this.zoom,i=fi.mercatorY01(t.north),n=fi.mercatorY01(t.south),s=t.east-t.west;return{west:t.west+(this.centerX-e)*s,east:t.west+(this.centerX+e)*s,north:fi.latitudeAt(i+(this.centerY-e)*(n-i)),south:fi.latitudeAt(i+(this.centerY+e)*(n-i))}}static including(t,e,i=3){const n=(t.north+t.south)/2,s=(t.east+t.west)/2,r=ue(n,t.east,n,s).x;let o=r;for(const c of e){const{x:l,z:h}=ue(c.lat,c.lng,n,s),u=Math.max(Math.abs(l),Math.abs(h));u<=r*i&&(o=Math.max(o,u*1.15))}return o<=r?t:{north:is(0,-o,n,s).lat,south:is(0,o,n,s).lat,east:is(o,0,n,s).lng,west:is(-o,0,n,s).lng}}static expand(t,e){const i=t.east-t.west,n=t.north-t.south;return{west:t.west-i*e,east:t.east+i*e,south:t.south-n*e,north:t.north+n*e}}static pointAt(t,e,i){const n=fi.mercatorY01(t.north),s=fi.mercatorY01(t.south);return{lat:fi.latitudeAt(n+i*(s-n)),lng:t.west+e*(t.east-t.west)}}static mercatorY01(t){const e=t*Math.PI/180;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}static latitudeAt(t){return Math.atan(Math.sinh(Math.PI*(1-2*t)))*180/Math.PI}}const as=256,L1=3,wS=32768;class SS{fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(t,e){const i=(t.south+t.north)/2,n=(t.west+t.east)/2,s=Math.abs(ue(i,t.east,i,t.west).x),r=Math.abs(ue(t.north,n,t.south,n).z),o=vS(i,Math.max(s,r)),{tiles:c}=uy(n,i,o,L1),l=L1*as,h=new Float32Array(l*l),u=c[0];await Promise.all(c.map(f=>this.decodeTileInto(f,u,h,l)));const d=new Float32Array(e.width*e.height);for(let f=0;f<e.height;f++){const p=t.north+(t.south-t.north)*(f/(e.height-1));for(let v=0;v<e.width;v++){const m=t.west+(t.east-t.west)*(v/(e.width-1));d[f*e.width+v]=this.sampleAt(p,m,o,u,h,l)}}return{heights:d,width:e.width,height:e.height,bounds:t}}async decodeTileInto(t,e,i,n){const s=this.tileUrlTemplate.replace("{z}",String(t.z)).replace("{x}",String(t.x)).replace("{y}",String(t.y)),r=await this.fetchImpl(s);if(!r.ok)throw new Error(`Elevation tile fetch failed (${r.status}): ${s}`);const o=await createImageBitmap(await r.blob()),c=document.createElement("canvas");c.width=as,c.height=as;const l=c.getContext("2d");if(!l)throw new Error("2D canvas context unavailable");l.drawImage(o,0,0);const{data:h}=l.getImageData(0,0,as,as),u=(t.x-e.x)*as,d=(t.y-e.y)*as;for(let f=0;f<as;f++)for(let p=0;p<as;p++){const v=(f*as+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-wS,g=u+p,y=d+f;i[y*n+g]=m}}sampleAt(t,e,i,n,s,r){const{x:o,y:c}=ly(e,t,i),l=(o-n.x)*as,h=(c-n.y)*as,u=Math.max(0,Math.min(r-1,Math.floor(l))),d=Math.max(0,Math.min(r-1,Math.floor(h))),f=Math.min(r-1,u+1),p=Math.min(r-1,d+1),v=l-u,m=h-d,g=s[d*r+u],y=s[d*r+f],x=s[p*r+u],M=s[p*r+f],w=g+(y-g)*v,S=x+(M-x)*v;return w+(S-w)*m}}class hf{constructor(t,e,i,n){this.width=t,this.height=e,this.samples=i,this.values=n}at(t,e,i=0){return this.values[(e*this.width+t)*this.samples+i]}static parse(t){const e=new DataView(t);if(t.byteLength<8||e.getUint16(0)!==18761||e.getUint16(2,!0)!==42)throw new Error("Not a little-endian TIFF");const i=e.getUint32(4,!0),n=e.getUint16(i,!0),s=new Map;for(let g=0;g<n;g++){const y=i+2+g*12;s.set(e.getUint16(y,!0),{type:e.getUint16(y+2,!0),count:e.getUint32(y+4,!0),value:e.getUint32(y+8,!0)})}const r=(g,y)=>{const x=s.get(g);if(x===void 0){if(y===void 0)throw new Error(`TIFF without tag ${g}`);return y}return x.type===3?x.value&65535:x.value},o=g=>{const y=s.get(g);if(y===void 0)throw new Error(`TIFF without tag ${g}`);const x=y.type===3?2:4,M=[];if(y.count*x<=4){const w=new DataView(new ArrayBuffer(4));w.setUint32(0,y.value,!0);for(let S=0;S<y.count;S++)M.push(x===2?w.getUint16(S*2,!0):w.getUint32(0,!0))}else for(let w=0;w<y.count;w++)M.push(x===2?e.getUint16(y.value+w*2,!0):e.getUint32(y.value+w*4,!0));return M};if(r(259,1)!==1)throw new Error("Compressed TIFF");if(s.has(322))throw new Error("Tiled TIFF");const c=r(256),l=r(257),h=r(277,1),u=o(258)[0],d=r(339,1)===3;if(!(d&&u===32||!d&&u===8))throw new Error(`Unsupported TIFF samples: ${u} bits`);const f=o(273),p=o(279),v=new Uint8Array(c*l*h*(u/8));let m=0;for(let g=0;g<f.length&&m<v.length;g++){const y=Math.min(p[g],v.length-m);v.set(new Uint8Array(t,f[g],y),m),m+=y}if(m<v.length)throw new Error("Truncated TIFF");return new hf(c,l,h,d?new Float32Array(v.buffer):v)}}class Yr extends Error{constructor(t,e){super(e),this.reason=t,this.name="SurroundingsUnavailableError"}}class ES{constructor(t,e,i,n,s){this.heights=t,this.plants=e,this.buildings=i,this.size=n,this.metresPerPixel=s}structureAt(t,e){const i=Math.floor(t/this.metresPerPixel+this.size/2),n=Math.floor(this.size/2-e/this.metresPerPixel);if(i<0||n<0||i>=this.size||n>=this.size)return;const s=n*this.size+i;if(!(this.plants[s]||this.buildings[s]))return this.heights[s]}tallestStructureNear(t,e,i){let n;const s=Math.ceil(i/this.metresPerPixel);for(let r=-s;r<=s;r++)for(let o=-s;o<=s;o++){if(Math.hypot(o,r)*this.metresPerPixel>i)continue;const c=this.structureAt(t+o*this.metresPerPixel,e+r*this.metresPerPixel);c!==void 0&&(n===void 0||c>n)&&(n=c)}return n}}class _e{static covers(t,e){return t>=41.2&&t<=51.3&&e>=-5.4&&e<=9.8}static WMS="https://data.geopf.fr/wms-r/wms";static WFS="https://data.geopf.fr/wfs/ows";static HEIGHT_LAYER="IGNF_LIDAR-HD_MNH_ELEVATION.ELEVATIONGRIDCOVERAGE.LAMB93";static CLASS_LAYER="IGNF_LIDAR-HD_CLASS";static PHOTO_LAYER="ORTHOIMAGERY.ORTHOPHOTOS";static MAX_PHOTO_PIXELS=1e3;static METRES_PER_PIXEL=.5;static MAX_RADIUS_M=3e3;static MAX_LIDAR_RADIUS_M=150;static NO_DATA=-9999;static METRES_PER_DEGREE=111320;fetchImpl;wms;wfs;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.wms=t.wmsEndpoint??_e.WMS,this.wfs=t.wfsEndpoint??_e.WFS}static radius(t){return Math.min(t,_e.MAX_RADIUS_M)}static lidarRadius(t){return Math.min(t,_e.MAX_LIDAR_RADIUS_M)}async lidar(t,e){const i=_e.lidarRadius(e),n=Math.ceil(2*i/_e.METRES_PER_PIXEL),[s,r]=await Promise.all([this.raster(t,i,n,_e.HEIGHT_LAYER),this.raster(t,i,n,_e.CLASS_LAYER)]);if(s.samples!==1||r.samples<3)throw new Yr("unreachable","The survey answered in a layout this does not read");const o=s.values;if(o.every(u=>u===_e.NO_DATA))throw new Yr("no-coverage","No LiDAR HD survey here yet");const c=new Uint8Array(n*n),l=new Uint8Array(n*n);for(let u=0;u<n*n;u++){const d=r.values[u*r.samples],f=r.values[u*r.samples+1],p=r.values[u*r.samples+2];c[u]=f>d&&f>p?1:0,l[u]=d>120&&f<90&&p<90?1:0}const h=2*i/n;return{size:n,metresPerPixel:h,heights:o,vegetation:c,building:l,structures:new ES(o,c,l,n,h)}}async laserDate(t){return _e.latest(await this.dated("IGNF_LIDAR-HD_METADONNEE:metadata","geom","date_fin_acquisition",t))}async photoDate(t){return _e.latest(await this.dated("ORTHOIMAGERY.ORTHOPHOTOS.GRAPHE-MOSAIQUAGE:graphe_bdortho","geom","date_vol",t))}static latest(t){return t.map(i=>/^\d{4}-\d{2}-\d{2}/.exec(String(i??""))?.[0]).filter(i=>i!==void 0).sort().at(-1)}async dated(t,e,i,n){const r=[n.lng-1e-4,n.lat-1e-4,n.lng+1e-4,n.lat+1e-4].map(o=>o.toFixed(6)).join(",");try{return(await this.features(t,`BBOX(${e},${r},'EPSG:4326')`,i,20)).map(o=>o.properties[i])}catch{return[]}}async photo(t,e){const i=_e.radius(e),n=Math.min(_e.MAX_PHOTO_PIXELS,Math.ceil(2*i/_e.METRES_PER_PIXEL)),s=await this.raster(t,i,n,_e.PHOTO_LAYER);if(s.samples<3)throw new Yr("unreachable","The photograph came in a layout this does not read");return{size:n,metresPerPixel:2*i/n,samples:s.samples,values:s.values}}async vectors(t,e,i){const n=_e.radius(e),s=n/_e.METRES_PER_DEGREE,r=n/(_e.METRES_PER_DEGREE*Math.cos(t.lat*Math.PI/180)),c=`BBOX(geometrie,${[t.lng-r,t.lat-s,t.lng+r,t.lat+s].map(g=>g.toFixed(6)).join(",")},'EPSG:4326')`,[l,h,u,d,f,p]=await Promise.all([this.features("construction_lineaire",`${c} AND nature='Pont'`,"nature,geometrie"),this.features("troncon_de_route",`${c} AND position_par_rapport_au_sol>'0'`,"nature,largeur_de_chaussee,position_par_rapport_au_sol,nom_voie_ban_gauche,nom_voie_ban_droite,cpx_toponyme_route_nommee,geometrie"),this.features("troncon_de_voie_ferree",`${c} AND position_par_rapport_au_sol>'0'`,"position_par_rapport_au_sol,geometrie").catch(()=>[]),this.features("ligne_electrique",c,"voltage,geometrie"),i?this.features("batiment",c,_e.BUILDING_PROPERTIES,5e3):Promise.resolve([]),i?this.features("zone_d_activite_ou_d_interet",c,"toponyme,categorie,geometrie",100).catch(()=>[]):Promise.resolve([])]),v=i?await this.wholeWorship(p,f,[t.lng-r,t.lat-s,t.lng+r,t.lat+s]):[],m=[...f,...v];return{bridges:l,elevatedRoads:h,elevatedRailways:u,lines:d,buildings:m,zones:p,mapDate:_e.latest(m.map(g=>g.properties.date_modification))}}static BUILDING_PROPERTIES="cleabs,nature,usage_1,hauteur,nombre_d_etages,materiaux_des_murs,materiaux_de_la_toiture,date_d_apparition,date_modification,geometrie";static MAX_WHOLE_M=300;async wholeWorship(t,e,i){const[n,s,r,o]=i,c=_e.MAX_WHOLE_M/_e.METRES_PER_DEGREE;let l;for(const u of t){if(u.properties.categorie!=="Religieux")continue;const[d,f,p,v]=_e.extent(u);if(d>=n&&f>=s&&p<=r&&v<=o)continue;const m=[Math.max(d,n-c),Math.max(f,s-c),Math.min(p,r+c),Math.min(v,o+c)];l=l?[Math.min(l[0],m[0]),Math.min(l[1],m[1]),Math.max(l[2],m[2]),Math.max(l[3],m[3])]:m}if(!l)return[];const h=new Set(e.map(u=>u.properties.cleabs));try{return(await this.features("batiment",`BBOX(geometrie,${l.map(d=>d.toFixed(6)).join(",")},'EPSG:4326')`,_e.BUILDING_PROPERTIES,1e3)).filter(d=>!h.has(d.properties.cleabs))}catch{return[]}}static extent(t){let e=1/0,i=1/0,n=-1/0,s=-1/0;const r=o=>{Array.isArray(o)&&typeof o[0]=="number"?(e=Math.min(e,o[0]),n=Math.max(n,o[0]),i=Math.min(i,o[1]),s=Math.max(s,o[1])):Array.isArray(o)&&o.forEach(r)};return r(t.geometry.coordinates),[e,i,n,s]}async elevatedRoadLines(t){const e=`BBOX(geometrie,${[t.west,t.south,t.east,t.north].map(s=>s.toFixed(6)).join(",")},'EPSG:4326')`,i=await this.features("troncon_de_route",`${e} AND position_par_rapport_au_sol>'0'`,"geometrie",300),n=[];for(const s of i){const{type:r,coordinates:o}=s.geometry,c=r==="LineString"?[o]:r==="MultiLineString"?o:[];for(const l of c)n.push(l.map(h=>({lat:h[1],lng:h[0]})))}return n}async waterSurfaces(t){const e=`BBOX(geometrie,${[t.west,t.south,t.east,t.north].map(i=>i.toFixed(6)).join(",")},'EPSG:4326')`;return this.features("surface_hydrographique",`${e} AND position_par_rapport_au_sol='0' AND persistance='Permanent'`,"cleabs,nature,geometrie",500)}async roads(t){const e=`BBOX(geometrie,${[t.west,t.south,t.east,t.north].map(i=>i.toFixed(6)).join(",")},'EPSG:4326')`;return this.features("troncon_de_route",`${e} AND nature<>'Sentier' AND nature<>'Escalier' AND position_par_rapport_au_sol>='0'`,"cleabs,nature,largeur_de_chaussee,nombre_de_voies,sens_de_circulation,vitesse_moyenne_vl,urbain,nom_voie_ban_gauche,nom_voie_ban_droite,cpx_toponyme_route_nommee,geometrie",3e3)}async railways(t){const e=`BBOX(geometrie,${[t.west,t.south,t.east,t.north].map(i=>i.toFixed(6)).join(",")},'EPSG:4326')`;return this.features("troncon_de_voie_ferree",`${e} AND etat_de_l_objet='En service'`,"cleabs,nature,electrifie,largeur,nombre_de_voies,position_par_rapport_au_sol,cpx_toponyme,geometrie",3e3)}async raster(t,e,i,n){const s=e/_e.METRES_PER_DEGREE,r=e/(_e.METRES_PER_DEGREE*Math.cos(t.lat*Math.PI/180)),o=new URLSearchParams({SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",LAYERS:n,STYLES:"",CRS:"EPSG:4326",BBOX:[t.lat-s,t.lng-r,t.lat+s,t.lng+r].map(l=>l.toFixed(6)).join(","),WIDTH:String(i),HEIGHT:String(i),FORMAT:"image/geotiff"});let c;try{c=await this.fetchImpl(`${this.wms}?${o}`)}catch(l){throw new Yr("unreachable",l instanceof Error?l.message:String(l))}if(!c.ok)throw new Yr("unreachable",`The survey answered ${c.status}`);try{return hf.parse(await c.arrayBuffer())}catch(l){throw new Yr("unreachable",l instanceof Error?l.message:String(l))}}async features(t,e,i,n=200){const s=new URLSearchParams({SERVICE:"WFS",VERSION:"2.0.0",REQUEST:"GetFeature",TYPENAMES:t.includes(":")?t:`BDTOPO_V3:${t}`,SRSNAME:"EPSG:4326",OUTPUTFORMAT:"application/json",COUNT:String(n),CQL_FILTER:e,PROPERTYNAME:i});let r;try{r=await this.fetchImpl(`${this.wfs}?${s}`)}catch(c){throw new Yr("unreachable",c instanceof Error?c.message:String(c))}if(!r.ok)throw new Yr("unreachable",`The map answered ${r.status}`);return(await r.json()).features??[]}}class ra{static NEAR_M=15;static ALIGNED_DEG=30;static LONG_ENOUGH_M=15;static SAMPLE_M=5;static follows(t,e){if(t.length<2||e.length<2)return!1;const i=e[0],n=e.map(o=>ue(o.lat,o.lng,i.lat,i.lng)),s=t.map(o=>ue(o.lat,o.lng,i.lat,i.lng));let r=0;for(let o=0;o<s.length-1;o++){const c=s[o],l=s[o+1],h=Math.hypot(l.x-c.x,l.z-c.z);if(h<1e-6)continue;const u=Math.max(1,Math.ceil(h/ra.SAMPLE_M)),d=Math.atan2(l.x-c.x,-(l.z-c.z));for(let f=0;f<=u;f++){const p=f/u,v=ra.nearest(n,c.x+(l.x-c.x)*p,c.z+(l.z-c.z)*p);v.distanceM>ra.NEAR_M||ra.angleBetween(d,v.heading)<=ra.ALIGNED_DEG&&(r+=h/u)}}return r>=ra.LONG_ENOUGH_M}static nearest(t,e,i){let n={distanceM:1/0,heading:0};for(let s=0;s<t.length-1;s++){const r=t[s],o=t[s+1],c=o.x-r.x,l=o.z-r.z,h=c*c+l*l,u=h<1e-9?0:Math.max(0,Math.min(1,((e-r.x)*c+(i-r.z)*l)/h)),d=Math.hypot(e-(r.x+c*u),i-(r.z+l*u));d<n.distanceM&&(n={distanceM:d,heading:Math.atan2(c,-l)})}return n}static angleBetween(t,e){const i=Math.abs((t-e)*180/Math.PI%180);return Math.min(i,180-i)}}class xe{static WMS="https://data.geopf.fr/wms-r/wms";static LAYERS=["IGNF_LIDAR-HD_MNT_ELEVATION.ELEVATIONGRIDCOVERAGE.LAMB93","ELEVATION.ELEVATIONGRIDCOVERAGE.HIGHRES"];static METRES_PER_PIXEL=4;static METRES_PER_DEGREE=111320;static CLASS_LAYER="IGNF_LIDAR-HD_CLASS";static SURFACE_LAYER="IGNF_LIDAR-HD_MNS_ELEVATION.ELEVATIONGRIDCOVERAGE.LAMB93";static DECK=[240,240,0];static NO_CLASS=[0,0,0];static DECK_END_PIXELS=3;static DECK_HALF_WIDTH_M=8;static DECK_APPROACH_M=10;static DECK_STRAIGHT_MAX_M=200;static MIN_PIXELS=8;static MAX_PIXELS=700;static NO_DATA_BELOW=-9e3;static MESH_FROM_VERTICES=33;static FINE_SPACING_M=7;static MAX_SEGMENTS=256;static MAX_HOLE_SHARE=.05;static DEFAULT_TIMEOUT_MS=12e3;static MAX_WINDOW_M=50;fetchImpl;wms;timeoutMs;maxWindowM;geoplatform;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.wms=t.wmsEndpoint??xe.WMS,this.timeoutMs=t.timeoutMs??xe.DEFAULT_TIMEOUT_MS,this.maxWindowM=t.maxWindowM??xe.MAX_WINDOW_M,this.geoplatform=new _e({fetchImpl:this.fetchImpl,wmsEndpoint:this.wms,wfsEndpoint:t.wfsEndpoint})}async getElevationGrid(t,e,i){const n={lat:(t.south+t.north)/2,lng:(t.west+t.east)/2};if(!_e.covers(n.lat,n.lng))throw new Error("The IGN's relief covers France only");const s=Math.abs(ue(n.lat,t.east,n.lat,t.west).x),r=Math.abs(ue(t.north,n.lng,t.south,n.lng).z);e=this.finer(e,s,r);const o={x:s/Math.max(1,e.width-1),y:r/Math.max(1,e.height-1)},c={x:Math.min(o.x,this.maxWindowM),y:Math.min(o.y,this.maxWindowM)},l={south:t.south-c.y/xe.METRES_PER_DEGREE,north:t.north+c.y/xe.METRES_PER_DEGREE,west:t.west-c.x/(xe.METRES_PER_DEGREE*Math.cos(n.lat*Math.PI/180)),east:t.east+c.x/(xe.METRES_PER_DEGREE*Math.cos(n.lat*Math.PI/180))},h=p=>Math.min(xe.MAX_PIXELS,Math.max(xe.MIN_PIXELS,Math.ceil(p/xe.METRES_PER_PIXEL))),u={width:h(s+2*c.x),height:h(r+2*c.y)},d={x:(s+2*c.x)/u.width,y:(r+2*c.y)/u.height};let f=new Error("No layer of the IGN's relief answered");for(const p of xe.LAYERS)try{const v=await this.heights(l,u,p);p===xe.LAYERS[0]&&await this.layBridgeDecks(v,l,u,i?.route);const m=this.sample(v,e,t,l,d,o);if(m)return{heights:m,width:e.width,height:e.height,bounds:t};f=new Error(`${p} does not cover this place`)}catch(v){f=v}throw f}finer(t,e,i){if(t.width<xe.MESH_FROM_VERTICES||t.height<xe.MESH_FROM_VERTICES)return t;const n=(s,r)=>{const o=Math.ceil(s/xe.FINE_SPACING_M),c=Math.max(r-1,Math.min(xe.MAX_SEGMENTS,o));return c%2===0?c:c+1};return{width:n(e,t.width)+1,height:n(i,t.height)+1}}async raster(t,e,i){const n=new URLSearchParams({SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",LAYERS:i,STYLES:"",CRS:"EPSG:4326",BBOX:[t.south,t.west,t.north,t.east].map(r=>r.toFixed(6)).join(","),WIDTH:String(e.width),HEIGHT:String(e.height),FORMAT:"image/geotiff"}),s=await this.fetchImpl(`${this.wms}?${n}`,{signal:AbortSignal.timeout(this.timeoutMs)});if(!s.ok)throw new Error(`The IGN's relief answered ${s.status}`);return hf.parse(await s.arrayBuffer())}async heights(t,e,i){const n=await this.raster(t,e,i);if(n.samples!==1||!(n.values instanceof Float32Array))throw new Error("The IGN's relief came in a layout this does not read");return n}async layBridgeDecks(t,e,i,n){if(!(!n||n.length<2)&&!(!(t.values instanceof Float32Array)||!t.values.some(s=>s>xe.NO_DATA_BELOW)))try{const s=(await this.geoplatform.elevatedRoadLines({west:e.west,south:e.south,east:e.east,north:e.north})).filter(o=>ra.follows(n,o));if(s.length===0)return;const r=Float32Array.from(t.values);await this.layClassifiedDecks(t,e,i,s),this.layRouteDecks(t,r,e,s)}catch{}}async layClassifiedDecks(t,e,i,n){try{const s=await this.raster(e,i,xe.CLASS_LAYER);if(s.samples<3||s.width!==t.width||s.height!==t.height)return;const r=(m,[g,y,x])=>s.values[m*s.samples]===g&&s.values[m*s.samples+1]===y&&s.values[m*s.samples+2]===x,o=t.width,c=t.height,l=new Uint8Array(o*c);let h=!1;for(let m=0;m<l.length;m++)r(m,xe.DECK)&&(l[m]=1,h=!0);if(!h)return;const u=xe.DECK_END_PIXELS,d=[];for(let m=0;m<l.length;m++){if(l[m]!==1)continue;const g=m%o,y=(m-g)/o;for(let x=-u;x<=u;x++)for(let M=-u;M<=u;M++){const w=g+M,S=y+x;if(w<0||S<0||w>=o||S>=c)continue;const _=S*o+w;l[_]===0&&r(_,xe.NO_CLASS)&&d.push(_)}}for(const m of d)l[m]=1;const f=this.paint(n,e,o,c),p=this.touching(l,f,o,c);if(p.every(m=>m===0))return;const v=await this.heights(e,i,xe.SURFACE_LAYER);if(v.width!==o||v.height!==c)return;for(let m=0;m<p.length;m++){if(p[m]===0)continue;const g=v.values[m];Number.isFinite(g)&&g>xe.NO_DATA_BELOW&&g>t.values[m]&&(t.values[m]=g)}}catch{}}layRouteDecks(t,e,i,n){const{width:s,height:r}=t,o=(i.north+i.south)/2,c=(i.east-i.west)*xe.METRES_PER_DEGREE*Math.cos(o*Math.PI/180),l=(i.north-i.south)*xe.METRES_PER_DEGREE,h=c/s,u=l/r,d=g=>({x:(g.lng-i.west)/(i.east-i.west)*c,y:(i.north-g.lat)/(i.north-i.south)*l}),f=(g,y)=>{const x=Math.floor(g/h),M=Math.floor(y/u);if(x<0||M<0||x>=s||M>=r)return;const w=e[M*s+x];return Number.isFinite(w)&&w>xe.NO_DATA_BELOW?w:void 0},p=xe.DECK_HALF_WIDTH_M,v=xe.DECK_APPROACH_M,m=(g,y)=>{const x=Math.hypot(g.x-y.x,g.y-y.y)||1,M={x:(g.x-y.x)/x,y:(g.y-y.y)/x},w=[0,v/2,v].map(S=>f(g.x+M.x*S,g.y+M.y*S)).filter(S=>S!==void 0);return w.length>0?Math.max(...w):void 0};for(const g of xe.chains(n.map(y=>y.map(d)))){const y=[0];for(let I=1;I<g.length;I++)y.push(y[I-1]+Math.hypot(g[I].x-g[I-1].x,g[I].y-g[I-1].y));const x=y[y.length-1];if(x<1||x>xe.DECK_STRAIGHT_MAX_M)continue;const M=m(g[0],g[1]),w=m(g[g.length-1],g[g.length-2]);if(M===void 0||w===void 0)continue;const S=p+v,_=Math.max(0,Math.floor((Math.min(...g.map(I=>I.x))-S)/h)),b=Math.min(s-1,Math.ceil((Math.max(...g.map(I=>I.x))+S)/h)),A=Math.max(0,Math.floor((Math.min(...g.map(I=>I.y))-S)/u)),D=Math.min(r-1,Math.ceil((Math.max(...g.map(I=>I.y))+S)/u));for(let I=A;I<=D;I++)for(let O=_;O<=b;O++){const N=xe.nearestAlong(g,y,{x:(O+.5)*h,y:(I+.5)*u});if(N.distance>p||N.s<-v||N.s>x+v)continue;const F=M+(w-M)*Math.min(1,Math.max(0,N.s/x)),P=I*s+O;e[P]>=F||(t.values[P]=F)}}}static chains(t){const e=t.filter(s=>s.length>=2).map(s=>[...s]),i=[],n=(s,r)=>Math.hypot(s.x-r.x,s.y-r.y)<=1;for(;e.length>0;){let s=e.shift(),r=!0;for(;r;){r=!1;for(let o=0;o<e.length;o++){const c=e[o],l=s[0],h=s[s.length-1];if(n(h,c[0]))s=[...s,...c.slice(1)];else if(n(h,c[c.length-1]))s=[...s,...[...c].reverse().slice(1)];else if(n(l,c[c.length-1]))s=[...c.slice(0,-1),...s];else if(n(l,c[0]))s=[...[...c].reverse().slice(0,-1),...s];else continue;e.splice(o,1),r=!0;break}}i.push(s)}return i}static nearestAlong(t,e,i){let n={s:0,distance:1/0};for(let s=0;s<t.length-1;s++){const r=t[s],o=t[s+1],c=o.x-r.x,l=o.y-r.y,h=c*c+l*l;if(h<1e-9)continue;let u=((i.x-r.x)*c+(i.y-r.y)*l)/h;s>0&&(u=Math.max(0,u)),s<t.length-2&&(u=Math.min(1,u));const d=Math.hypot(i.x-(r.x+c*u),i.y-(r.y+l*u));d<n.distance&&(n={s:e[s]+u*Math.sqrt(h),distance:d})}return n}paint(t,e,i,n){const s=new Uint8Array(i*n),r=c=>(c-e.west)/(e.east-e.west)*i,o=c=>(e.north-c)/(e.north-e.south)*n;for(const c of t)for(let l=0;l<c.length-1;l++){const h=r(c[l].lng),u=o(c[l].lat),d=r(c[l+1].lng),f=o(c[l+1].lat),p=Math.max(1,Math.ceil(Math.hypot(d-h,f-u)*2));for(let v=0;v<=p;v++){const m=Math.floor(h+(d-h)*v/p),g=Math.floor(u+(f-u)*v/p);for(let y=-1;y<=1;y++)for(let x=-1;x<=1;x++){const M=m+x,w=g+y;M>=0&&w>=0&&M<i&&w<n&&(s[w*i+M]=1)}}}return s}touching(t,e,i,n){const s=new Uint8Array(t.length),r=new Uint8Array(t.length);for(let o=0;o<t.length;o++){if(t[o]===0||r[o]===1)continue;const c=[],l=[o];r[o]=1;let h=!1;for(;l.length>0;){const u=l.pop();c.push(u),e[u]===1&&(h=!0);const d=u%i,f=(u-d)/i;for(let p=-1;p<=1;p++)for(let v=-1;v<=1;v++){const m=d+v,g=f+p;if(m<0||g<0||m>=i||g>=n)continue;const y=g*i+m;t[y]===1&&r[y]===0&&(r[y]=1,l.push(y))}}if(h)for(const u of c)s[u]=1}return s}sample(t,e,i,n,s,r){const{width:o,height:c}=e,l=new Float32Array(o*c),h=new Uint8Array(o*c),u=Math.min(r.x,this.maxWindowM)/s.x,d=Math.min(r.y,this.maxWindowM)/s.y;let f=0;for(let p=0;p<c;p++){const v=i.north+(i.south-i.north)*(c===1?.5:p/(c-1)),m=(n.north-v)/(n.north-n.south)*t.height-.5;for(let g=0;g<o;g++){const x=(i.west+(i.east-i.west)*(o===1?.5:g/(o-1))-n.west)/(n.east-n.west)*t.width-.5,M=u>1||d>1?this.tent(t,x,m,Math.max(1,u),Math.max(1,d)):this.bilinear(t,x,m),w=p*o+g;M===void 0?f++:(l[w]=M,h[w]=1)}}if(!(f===o*c||f/(o*c)>xe.MAX_HOLE_SHARE))return this.fill(l,h,o,c),l}tent(t,e,i,n,s){let r=0,o=0,c=0;const l=Math.max(0,Math.ceil(i-s)),h=Math.min(t.height-1,Math.floor(i+s)),u=Math.max(0,Math.ceil(e-n)),d=Math.min(t.width-1,Math.floor(e+n));for(let f=l;f<=h;f++){const p=1-Math.abs(f-i)/s;if(!(p<=0))for(let v=u;v<=d;v++){const m=p*(1-Math.abs(v-e)/n);if(m<=0)continue;c+=m;const g=t.at(v,f);!Number.isFinite(g)||g<xe.NO_DATA_BELOW||(r+=m*g,o+=m)}}return c>0&&o>=c*.5?r/o:void 0}bilinear(t,e,i){const n=Math.max(0,Math.min(t.width-1,Math.floor(e))),s=Math.max(0,Math.min(t.height-1,Math.floor(i))),r=Math.min(t.width-1,n+1),o=Math.min(t.height-1,s+1),c=Math.max(0,Math.min(1,e-n)),l=Math.max(0,Math.min(1,i-s)),h=t.at(n,s),u=t.at(r,s),d=t.at(n,o),f=t.at(r,o);for(const m of[h,u,d,f])if(!Number.isFinite(m)||m<xe.NO_DATA_BELOW)return;const p=h+(u-h)*c,v=d+(f-d)*c;return p+(v-p)*l}fill(t,e,i,n){let s=e.reduce((r,o)=>r+(o?0:1),0);for(;s>0;){const r=[];for(let o=0;o<n;o++)for(let c=0;c<i;c++){const l=o*i+c;if(e[l])continue;let h=0,u=0;for(let d=-1;d<=1;d++)for(let f=-1;f<=1;f++){const p=o+d,v=c+f;p<0||v<0||p>=n||v>=i||!e[p*i+v]||(h+=t[p*i+v],u++)}u>0&&r.push([l,h/u])}if(r.length===0)return;for(const[o,c]of r)t[o]=c,e[o]=1;s-=r.length}}}class _S{providers;constructor(...t){this.providers=t}async getElevationGrid(t,e,i){let n=new Error("No source of relief to ask");for(const s of this.providers)try{return await s.getElevationGrid(t,e,i)}catch(r){n=r}throw n}}const Gu=256,AS=5;async function TS(a,t,e,i){const n=(a.south+a.north)/2,s=(a.west+a.east)/2,r=Math.abs(ue(n,a.east,n,a.west).x),o=Math.abs(ue(a.north,s,a.south,s).z),c=Math.max(r,o),{zoom:l,gridSize:h}=RS(n,c,Math.max(t.width,t.height)),{tiles:u,bounds:d}=uy(s,n,l,h),f=h*Gu,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=u[0];await Promise.all(u.map(async M=>{const w=e(M),S=await i(w);if(!S.ok)throw new Error(`Imagery tile fetch failed (${S.status}): ${w}`);const _=await createImageBitmap(await S.blob());v.drawImage(_,(M.x-m.x)*Gu,(M.y-m.y)*Gu)}));const g=Math.min(Math.max(t.width,t.height),f);if(g===f)return{source:p,width:f,height:f,bounds:d};const y=document.createElement("canvas");y.width=g,y.height=g;const x=y.getContext("2d");if(!x)throw new Error("2D canvas context unavailable");return x.drawImage(p,0,0,f,f,0,0,g,g),{source:y,width:g,height:g,bounds:d}}function RS(a,t,e){let i=MS(a,t/Math.max(1,e)),n=N1(a,i,t);for(;n>AS&&i>0;)i--,n=N1(a,i,t);return{zoom:i,gridSize:n,mPerPixel:cy(a,i)/Gu}}function N1(a,t,e){const i=Math.ceil(e/2/cy(a,t));return Math.max(3,2*i+1)}class IS{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(t,e){return TS(t,e,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class Jn{static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];static FRANCE_ENDPOINT="https://overpass.openstreetmap.fr/api/interpreter";static FRANCE={south:41.3,west:-5.2,north:51.1,east:9.6};static endpointsFor(t,e=Jn.ENDPOINTS){const i=/\((-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?)\)/.exec(t);if(!i)return[...e];const[n,s,r,o]=i.slice(1).map(Number),c=(n+r)/2,l=(s+o)/2,h=Jn.FRANCE;return c>=h.south&&c<=h.north&&l>=h.west&&l<=h.east?[Jn.FRANCE_ENDPOINT,...e.filter(d=>d!==Jn.FRANCE_ENDPOINT)]:[...e]}fetchImpl;endpoints;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.endpoints=t.endpoints}static queue=Promise.resolve();static HANG_MS=4e4;static RETRY_MS=4e3;query(t){return this.queued(()=>this.ask(t))}queued(t){const e=Jn.queue.then(t,t);return Jn.queue=e.catch(()=>{}),e}async ask(t){let e;for(const i of this.endpoints??Jn.endpointsFor(t))for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(Jn.HANG_MS)});if(s.ok)return await s.json();if(e=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){e=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,Jn.RETRY_MS))}throw e??new Error("No Overpass instance answered")}}class aa{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;client;constructor(t={}){this.client=new Jn(t)}async getRoads(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];way["highway"~"^(${aa.DRIVABLE.join("|")})$"](${e});out geom;`;return this.waysFrom(await this.client.query(i))}waysFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||e.push({id:`osm-${i.id??e.length}`,name:s.name,surface:aa.surfaceOf(s),widthM:aa.widthOf(s),...aa.paintOf(s),points:n.map(r=>({lat:r.lat,lng:r.lon}))})}return e}static paintOf(t){const e=t.highway??"",i=t.junction==="roundabout"||t.junction==="circular",n=t.oneway,s=n==="yes"||n==="1"||n==="true"||n===void 0&&(e==="motorway"||i),r=n==="-1"||n==="reverse",o=Number.parseInt(t.lanes??"",10),c=Number.parseInt(t.maxspeed??"",10),l=i?"roundabout":e==="motorway"?"motorway":e.endsWith("_link")?"slip":(e==="trunk"||e==="primary")&&(s||r)?"dual":e?"road":void 0;return{...l?{kind:l}:{},...Number.isFinite(o)&&o>0?{lanes:o}:{},...n!==void 0||e==="motorway"||i?{direction:r?"backward":s?"forward":"both"}:{},...Number.isFinite(c)&&c>0?{speedKmh:c}:{}}}static widthOf(t){const e=Number.parseFloat(t.width??t.est_width??"");if(Number.isFinite(e)&&e>0)return e;const i=Number.parseInt(t.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:aa.WIDTH_M[t.highway]??aa.DEFAULT_WIDTH_M}static surfaceOf(t){const e=t.surface;return e==="dirt"||e==="earth"||e==="mud"?"dirt":e==="gravel"||e==="fine_gravel"||e==="compacted"||e==="ground"||e==="sand"||e==="unpaved"?"gravel":e?"paved":t.highway==="track"?"gravel":"paved"}}const Df="https://ufoathome.org/roads/index.json";class pc{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??pc.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRoads(t);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(t){let e;try{e=await this.load()}catch{return}const i=e.find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){if(this.index)return this.index;if(!this.sharing)return this.index=this.fetchFirstAvailable();const t=this.indexUrls.join(`
|
|
2438
|
-
`);let e=pc.shared.get(t);return e||(e=this.fetchFirstAvailable(),pc.shared.set(t,e),e.then(i=>{i.length===0&&pc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.
|
|
2439
|
-
`);let e=mc.shared.get(t);return e||(e=this.fetchFirstAvailable(),mc.shared.set(t,e),e.then(i=>{i.length===0&&mc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.
|
|
2440
|
-
`);let e=vc.shared.get(t);return e||(e=this.fetchFirstAvailable(),vc.shared.set(t,e),e.then(i=>{i.length===0&&vc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.0")}`,e=typeof location>"u"?void 0:new URL("/railways/index.json",location.href).href;return(e&&e!==Of?[e,Of]:[Of]).map(i=>i+t)}}function PS(){return{elevation:LS(),imagery:dy(),roads:NS(),water:kS(),railways:US()}}function LS(){return new _S(new xe,new SS)}function dy(){return new IS}function NS(){return new pc({fallback:new DS(new ha,new aa)})}function kS(){return new mc({fallback:new Nn(new CS(new oh,new Ba))})}function US(){return new vc({fallback:new Fi(new OS(new ua,new gc))})}const FS=new Set,cr="show-observer-map",lr="hide-milestones",no="minified";class be extends HTMLElement{static get observedAttributes(){return["src",cr,lr,no]}shadow;stageElement;canvas;canvasRenderer;chromeCanvas;chromeRenderer;chromeResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>{this.chromeDirty&&this.refresh()});chromeDirty=!1;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;accountHidden=!1;referenceViews=new Map;referencesMenu;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new fi;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;playerTitleBox;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=cf.create();issues=[];issueCheck=0;sightingAudio=new nS;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;static LIVE_BODY_MAX_RATE=2;get steadyBody(){return this.steadyObserver||this.player.playbackState!=="playing"||this.player.playbackRate>be.LIVE_BODY_MAX_RATE}selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=ny;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");be.setIcon(this.moreButton,t?Xt.UNFOLDED:Xt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<be.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=fi.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=fi.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},be.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=fi.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Kw}</style>${qw}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new Wc(this.canvas.getContext("2d")),this.chromeCanvas=this.shadow.getElementById("chrome"),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",e=>{e.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.referencesMenu=this.shadow.getElementById("references-menu"),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 za(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.playerTitleBox=this.shadow.getElementById("player-title"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.miniPlayed=this.shadow.getElementById("mini-played"),this.miniRemaining=this.shadow.getElementById("mini-remaining"),this.miniMuteButton=this.shadow.getElementById("mini-mute"),this.miniMuteButton.addEventListener("click",e=>{e.stopPropagation(),this.toggleMuted()}),this.stageElement.addEventListener("pointerenter",this.handleMinifiedEnter),this.stageElement.addEventListener("pointerleave",this.handleMinifiedLeave),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",e=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(e),this.beginTouchScrub(e)}),this.seekInput.addEventListener("pointerup",e=>{this.seekSnapArmed=!1,this.endTouchScrub(e)}),this.seekInput.addEventListener("pointercancel",e=>this.endTouchScrub(e)),this.seekInput.addEventListener("pointermove",e=>{this.nameMarkUnder(e),this.hoverSeek(e),this.touchScrub(e)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const e of["touchend","click"])this.stageElement.addEventListener(e,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",e=>{if(!(!this.enableClickToPlay||this.minified)){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}e.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",e=>{!this.enableClickToPlay||this.minified||(e.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.chromeResizeObserver?.observe(this.chromeCanvas),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.chromeResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===cr&&this.applyObserverMapDefault(),t===lr&&this.setMilestonesShown(!this.hasAttribute(lr)),t===no){const n=this.minified;this.stageElement.classList.toggle("minified",n),n&&e===null&&(this.muted=!0),this.updateStartState()}}get minified(){return this.hasAttribute(no)}miniPlayed;miniRemaining;miniMuteButton;handleMinifiedEnter=t=>{!this.minified||t.pointerType==="touch"||(this.minifiedHovered=!0,this.play())};minifiedHovered=!1;handleMinifiedLeave=t=>{!this.minified||t.pointerType==="touch"||(this.minifiedHovered=!1,this.pause(),this.player.seek(0),this.dispatchEvent(new CustomEvent(py)))};started=!1;updateStartState(){this.playRequested&&(this.started=!0);const t=!this.started&&this.enableClickToPlay;this.stageElement.classList.toggle("unstarted",t),t&&!this.minified?this.canvas.title=this.messages.clickToPlay:this.canvas.removeAttribute("title")}async loadFromSrc(t){this.sightingData=await Fl.json(t)}get sightingData(){return sS(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=aS(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.started=!1,this.syncPlayerTitle(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault(),this.minified&&this.minifiedHovered&&this.play()}set playerTitle(t){this.titleOverride=t,this.syncPlayerTitle()}titleOverride;syncPlayerTitle(){const t=this.said.read(this.titleOverride)??this.currentSighting.observer?.title??"";this.playerTitleBox.textContent=t,this.playerTitleBox.hidden=t===""}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await Xe(async()=>{const{default:r}=await import("./sightingSchema-v2l1p6Ld.js");return{default:r}},[],import.meta.url);n=new ws(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Xc.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(zS,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Xc.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){if(!(this.player.seekableDuration<=0||this.playbackState==="playing")){if(this.clockHeld){this.playAfterHold=!0,this.announcePlayRequest();return}this.togglePlayPause()}}get playRequested(){return this.playbackState==="playing"||this.playAfterHold}announcePlayRequest(){this.started=!0,this.updateStartState(),this.dispatchEvent(new CustomEvent("playrequest"))}clockHeld=!1;playAfterHold=!1;holdClock(t){if(t!==this.clockHeld){if(this.clockHeld=t,t){if(this.playbackState!=="playing")return;this.playAfterHold=!0,this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton();return}this.playAfterHold&&(this.playAfterHold=!1,!(this.player.seekableDuration<=0||this.playbackState==="playing")&&(this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton()))}}pause(){this.playAfterHold=!1,this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateMuteButton(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}repaintOverlay(){this.quietFrame=!0;try{this.player.seek(this.player.time)}finally{this.quietFrame=!1}}quietFrame=!1;hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}get severalReferences(){return this.currentSighting.references.length>1}toggleReferences(){if(this.severalReferences){this.toggleReferencesMenu();return}this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity));for(const e of[...this.referenceViews.keys()])t.some(i=>i.id===e)||this.referenceViews.delete(e);this.severalReferences?this.referencesMenu.hidden||this.renderReferencesMenu():this.closeReferencesMenu(),this.updateReferencesButton(),this.severalReferences&&this.dispatchReferenceView()}viewOfReference(t){let e=this.referenceViews.get(t.id);return e||(e={shown:!0,opacity:t.opacity},this.referenceViews.set(t.id,e)),e}toggleReferencesMenu(){this.referencesMenu.hidden?this.openReferencesMenu():this.closeReferencesMenu()}openReferencesMenu(){this.renderReferencesMenu(),this.referencesMenu.hidden=!1,this.placeReferencesMenu(),this.referencesButton.setAttribute("aria-expanded","true"),document.addEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.addEventListener("keydown",this.handleReferencesMenuKey,!0)}closeReferencesMenu(){this.referencesMenu.hidden||(this.referencesMenu.hidden=!0,this.referencesButton.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.removeEventListener("keydown",this.handleReferencesMenuKey,!0))}handleReferencesMenuOutside=t=>{const e=t.composedPath();e.includes(this.referencesMenu)||e.includes(this.referencesButton)||this.closeReferencesMenu()};handleReferencesMenuKey=t=>{t.key==="Escape"&&(this.closeReferencesMenu(),this.referencesButton.focus())};placeReferencesMenu(){const t=this.referencesButton.getBoundingClientRect(),e=this.referencesMenu,i=4;e.style.bottom=`${Math.max(i,window.innerHeight-t.top+i)}px`,e.style.top="auto";const n=e.getBoundingClientRect().width;e.style.left=`${Math.max(i,Math.min(t.left,window.innerWidth-n-i))}px`}renderReferencesMenu(){const t=this.currentSighting.references.map(e=>{const i=this.viewOfReference(e),n=this.said.read(e.title)??e.id,s=document.createElement("div");s.className="reference-row";const r=document.createElement("label"),o=document.createElement("input");o.type="checkbox",o.checked=i.shown;const c=document.createElement("span");c.textContent=n,c.title=n,r.append(o,c);const l=document.createElement("input");return l.type="range",l.min="0",l.max="1",l.step="0.05",l.value=String(i.opacity),l.title=this.messages.referenceOpacity,l.setAttribute("aria-label",`${this.messages.referenceOpacity}: ${n}`),l.disabled=!i.shown,o.addEventListener("change",()=>{i.shown=o.checked,l.disabled=!i.shown,this.updateReferencesButton(),this.dispatchReferenceView()}),l.addEventListener("input",()=>{i.opacity=Number(l.value),this.dispatchReferenceView()}),s.append(r,l),s});this.referencesMenu.setAttribute("aria-label",this.messages.referencesMenu),this.referencesMenu.replaceChildren(...t)}updateReferencesButton(){const t=this.currentSighting.references.length>0,e=this.severalReferences,i=e?this.currentSighting.references.some(s=>this.viewOfReference(s).shown):this.referencesShownState;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState||e,this.referencesButton.setAttribute("aria-pressed",String(i)),e?this.referencesButton.setAttribute("aria-haspopup","true"):this.referencesButton.removeAttribute("aria-haspopup"),be.setIcon(this.referencesButton,i?Xt.PICTURES_ON:Xt.PICTURES_OFF);const n=e?this.messages.referencesMenu:this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=n,this.referencesButton.setAttribute("aria-label",n),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),be.setIcon(this.tracesButton,this.tracesShownState?Xt.TRACES_ON:Xt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){const t=this.severalReferences?Object.fromEntries(this.currentSighting.references.map(e=>[e.id,{...this.viewOfReference(e)}])):void 0;this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity,views:t}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Bl(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",r=this.said.read(i.note),o=r?`${s} — ${r}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const r=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${r} — ${o}`:r,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(r=>r>0&&r<t))].sort((r,o)=>r-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let r=0;r<n.length-1;r++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[r+1]-n[r],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[r],end:n[r+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintMiniProgress(t){const e=this.player.seekableDuration;this.miniPlayed.style.width=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`,this.miniRemaining.textContent=this.formatRemaining(t)}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=be.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,r=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=be.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===r))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?Rf(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}paintChrome(t){const e=this.chromeCanvas.getContext("2d"),i=this.overlayPainter!==void 0||this.selectionShown;if(!i&&!this.chromeDirty)return;const n=this.chromeCanvas.clientWidth,s=this.chromeCanvas.clientHeight;if(!e||typeof e.setTransform!="function"||n===0||s===0){t(this.canvasRenderer);return}const r=window.devicePixelRatio||1,o=Math.max(1,Math.round(n*r)),c=Math.max(1,Math.round(s*r));this.chromeCanvas.width!==o&&(this.chromeCanvas.width=o),this.chromeCanvas.height!==c&&(this.chromeCanvas.height=c),e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,o,c),this.chromeDirty=!1,i&&(e.setTransform(o/this.canvas.width,0,0,c/this.canvas.height,0,0),this.chromeRenderer??=new Wc(e),this.chromeDirty=!0,t(this.chromeRenderer))}chromeDraw;repaintChrome(){this.chromeDraw&&this.overlayPainter&&this.paintChrome(this.chromeDraw)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=be.MARK_SNAP_PX/i*e;let s;for(const r of this.milestoneMarks.children){const o=Number(r.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:r.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?Rf(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=Ts.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<be.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(be.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/be.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/be.EXPOSURE_STEP_PX),s=Math.min(be.MAX_TRAVEL_STEPS,Math.max(i,n)),r=[];for(let o=0;o<s;o++)r.push(e.fromMs+e.ms*o/(s-1));return r}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[r,o]of i){const c=n.get(r);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){if(!this.accountHidden)for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=Li.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:FS;this.canvasRenderer.setStarPoints(Li.starPointsOf(this.sighting.instrument));const n=(ei(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),r=this.frameShift;if(this.paintsShapes)for(const c of s)for(const[,l]of c.shapes){const h=c.share,u=h===1?l:{...l,transparency:1-(1-l.transparency)*h};this.canvasRenderer.paintShape(this.shifted(u,r))}for(const[c,l]of s[0].shapes)!this.selectionShown||!i.has(c)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,r)));const o=this.selectionShown&&i.size>1?jn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds)):void 0;this.chromeDraw=c=>{o&&c.paintGroupHandles(o),this.overlayPainter?.(c)},this.paintChrome(this.chromeDraw),this.mapShapeBounds=s.flatMap(c=>[...c.shapes.values()].filter(l=>l.transparency<1).map(l=>this.shifted(l,r).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.minified&&this.paintMiniProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(K2(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),!this.quietFrame&&this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Zw(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*be.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){if(!(this.player.seekableDuration<=0)){if(this.player.playbackState==="playing")this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh();else if(this.clockHeld){this.playAfterHold=!this.playAfterHold,this.playAfterHold&&this.announcePlayRequest();return}else this.announcePlayRequest(),this.sightingAudio.resume(),this.player.play();this.updatePlayPauseButton(),this.flashPlayback()}}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Xt.PLAY:Xt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){be.icons.get(t)!==e&&(be.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}set controlsHeld(t){this.stageElement.classList.toggle("controls-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},be.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,this.updateStartState(),be.setIcon(this.playPauseButton,t?Xt.PAUSE:Xt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear(),this.dispatchEvent(new CustomEvent("observermapchange",{bubbles:!0,composed:!0,detail:{open:t}}))}get observerMapOpen(){return!this.observerMapPanel.hidden}get milestonesVisible(){return this.milestonesShown}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(cr),e=t===null?this.sighting.observerMap??this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;be.setIcon(this.observerMapButton,t?Xt.MAP_ON:Xt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Rc.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=fi.including(this.observerPath.boundsAround(be.OBSERVER_MAP_MIN_SPAN_M,be.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?fi.expand(t,be.OBSERVER_MAP_IMAGERY_AHEAD):t,n=be.OBSERVER_MAP_IMAGERY_PX*(e?1+2*be.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=dy();try{const r=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=r,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?fi.expand(t,be.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,r=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!r}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],r=be.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],r))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=ei(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},be.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?Rf(this.currentSighting.milestones,t):void 0;for(const r of this.milestonesShown?Bl(this.currentSighting.milestones):[]){const o=ei(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?Pr.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(Li.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(r=>({kind:r.kind,points:r.points,color:r.color,label:this.said.read(r.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Bl(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,be.setIcon(this.milestonesButton,this.milestonesShown?Xt.MILESTONES_ON:Xt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=ei(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=or(i,t),{lat:s,lng:r}=is(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:r,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=ei(this.currentSighting,this.currentTime),s=Pr.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return He.bodyAt(this.currentSighting,t,this.steadyBody)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=be.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.hasSound&&(this.muted=!this.mutedState)}ambientSound;get hasSound(){return this.currentSighting.soundTrack.allKeyframes.length>0||this.ambientSound?.(this.currentSighting)===!0}updateMuteButton(){const t=!this.hasSound;this.miniMuteButton.hidden=t,this.miniMuteButton.setAttribute("aria-pressed",String(this.mutedState)),be.setIcon(this.miniMuteButton,this.mutedState?Xt.MUTED:Xt.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;if(this.miniMuteButton.title=e,this.miniMuteButton.setAttribute("aria-label",e),this.muteButton.disabled=t,this.volumeInput.hidden=t,t){be.setIcon(this.muteButton,Xt.MUTED),this.muteButton.title=this.messages.noSound,this.muteButton.setAttribute("aria-label",this.messages.noSound),this.muteButton.setAttribute("aria-pressed","true");return}be.setIcon(this.muteButton,this.mutedState?Xt.MUTED:Xt.VOLUME);const i=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=i,this.muteButton.setAttribute("aria-label",i),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;be.setIcon(this.fullscreenButton,t?Xt.EXIT_FULLSCREEN:Xt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new fs(ya.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=Hm(ya.preferencesFor(this),Gm);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await lS(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=q2(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?ap(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.paintMiniProgress(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return ko(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?U1(k1(this.realStartMs+i)):ko(i)}formatRemaining(t){const e=this.currentSighting.timeline.duration;if(this.realDurationMs===void 0)return ko(Math.max(0,e-t));const i=e>0&&t<=e?t/e*this.realDurationMs:t;return ko(Math.max(0,this.realDurationMs-i))}formatEndOfTimeline(){return this.realDurationMs===void 0?ko(this.currentSighting.timeline.duration):this.canShowClockTime?U1(k1(this.realStartMs+this.realDurationMs)):ko(this.realDurationMs)}}function k1(a){const t=new Date(a);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function U1(a){if(a.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return a.second?`${t(a.hour)}:${t(a.minute??0)}:${t(a.second)}`:`${t(a.hour)}:${t(a.minute??0)}`}function ko(a){const t=Math.round(a/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const lp="rr0-ufo";function fy(){customElements.get(lp)||customElements.define(lp,be)}const zS="recordingissues",py="minifiedreset";/**
|
|
2455
|
+
`);let e=pc.shared.get(t);return e||(e=this.fetchFirstAvailable(),pc.shared.set(t,e),e.then(i=>{i.length===0&&pc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.2")}`,e=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(e&&e!==Df?[e,Df]:[Df]).map(i=>i+t)}}class ha{attribution="Roads © IGN, BD TOPO (Licence Ouverte 2.0), as drawn today";contemporary=!0;static BY_NATURE={"Type autoroutier":{surface:"paved",widthM:11},"Route à 2 chaussées":{surface:"paved",widthM:7},"Route à 1 chaussée":{surface:"paved",widthM:5.5},"Rond-point":{surface:"paved",widthM:6},Bretelle:{surface:"paved",widthM:5},"Route empierrée":{surface:"gravel",widthM:3.5},Chemin:{surface:"dirt",widthM:3},"Piste cyclable":{surface:"paved",widthM:2.5}};static DEFAULT={surface:"paved",widthM:5};static KINDS={"Type autoroutier":"motorway","Route à 2 chaussées":"dual","Route à 1 chaussée":"road","Rond-point":"roundabout",Bretelle:"slip"};static DIRECTIONS={"Double sens":"both","Sens direct":"forward","Sens inverse":"backward"};platform;constructor(t={}){this.platform=new _e(t)}static covers(t){return _e.covers((t.south+t.north)/2,(t.west+t.east)/2)}async getRoads(t){return(await this.platform.roads(t)).flatMap((i,n)=>ha.wayOf(i,n))}static wayOf(t,e){if(t.geometry.type!=="LineString")return[];const i=t.geometry.coordinates.map(([d,f])=>({lat:f,lng:d}));if(i.length<2)return[];const n=String(t.properties.nature??""),s=ha.BY_NATURE[n]??ha.DEFAULT,r=Number(t.properties.largeur_de_chaussee),o=Number(t.properties.nombre_de_voies),c=Number(t.properties.vitesse_moyenne_vl),l=ha.DIRECTIONS[String(t.properties.sens_de_circulation??"")],h=ha.KINDS[n],u=[t.properties.cpx_toponyme_route_nommee,t.properties.nom_voie_ban_gauche,t.properties.nom_voie_ban_droite].find(d=>typeof d=="string"&&d.length>0);return[{id:String(t.properties.cleabs??`ign-${e}`),...u?{name:u}:{},surface:s.surface,widthM:Number.isFinite(r)&&r>0?r:s.widthM,...t.properties.urbain===!0?{urban:!0}:{},...h?{kind:h}:{},...Number.isInteger(o)&&o>0?{lanes:o}:{},...l?{direction:l}:{},...Number.isFinite(c)&&c>0?{speedKmh:c}:{},points:i}]}}class DS{constructor(t,e){this.regional=t,this.worldwide=e}attribution="Roads © IGN, BD TOPO, in France; © OpenStreetMap contributors elsewhere, as drawn today";contemporary=!0;async getRoads(t){if(ha.covers(t))try{const e=await this.regional.getRoads(t);if(e.length>0)return e}catch{}return this.worldwide.getRoads(t)}}class oh{attribution="Water © IGN, BD TOPO (Licence Ouverte 2.0)";platform;constructor(t={}){this.platform=new _e(t)}static covers(t){return _e.covers((t.south+t.north)/2,(t.west+t.east)/2)}async getWater(t){return(await this.platform.waterSurfaces(t)).flatMap((i,n)=>oh.surfacesOf(i,n))}static surfacesOf(t,e){const{type:i,coordinates:n}=t.geometry,s=i==="Polygon"?[n]:i==="MultiPolygon"?n:[],r=String(t.properties.cleabs??`ign-water-${e}`);return s.flatMap((o,c)=>{const l=o.map(h=>oh.open(h.map(u=>({lat:u[1],lng:u[0]})))).filter(h=>h.length>=3);return l.length>0?[{id:s.length>1?`${r}-${c}`:r,rings:l}]:[]})}static open(t){const e=t[0],i=t[t.length-1];return t.length>1&&e.lat===i.lat&&e.lng===i.lng?t.slice(0,-1):t}}class Ba{attribution="Water © OpenStreetMap contributors";client;constructor(t={}){this.client=new Jn(t)}async getWater(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];(way["natural"="water"](${e});way["waterway"="riverbank"](${e});)->.w;(relation["natural"="water"](${e});relation["waterway"="riverbank"](${e});)->.r;.w out geom;.r out body;way(r.r)(${e});out geom;`;return Ba.surfacesFrom(await this.client.query(i))}static surfacesFrom(t){const e=t.elements??[],i=new Map;for(const r of e)r.type==="way"&&r.id!==void 0&&r.geometry&&i.set(r.id,r.geometry.map(o=>({lat:o.lat,lng:o.lon})));const n=[],s=new Set;for(const r of e){if(r.type!=="relation")continue;const o=l=>(r.members??[]).filter(h=>h.type==="way"&&h.role===l&&h.ref!==void 0&&i.has(h.ref)).map(h=>(s.add(h.ref),i.get(h.ref))),c=Ba.rings(o("inner"));for(const[l,h]of Ba.rings(o("outer")).entries()){const u=c.filter(d=>Ba.contains(h,d[0]));n.push({id:`osm-r${r.id}-${l}`,rings:[h,...u]})}}for(const r of e)if(!(r.type!=="way"||!r.tags||r.id===void 0||s.has(r.id))&&!(r.tags.natural!=="water"&&r.tags.waterway!=="riverbank"))for(const o of Ba.rings([i.get(r.id)??[]]))n.push({id:`osm-w${r.id}`,rings:[o]});return n}static rings(t){const e=(s,r)=>s.lat===r.lat&&s.lng===r.lng,i=t.filter(s=>s.length>=2).map(s=>[...s]),n=[];for(;i.length>0;){let s=i.pop(),r=!0;for(;!e(s[0],s[s.length-1])&&r;){r=!1;for(let o=0;o<i.length;o++){const c=i[o],l=s[s.length-1];if(e(l,c[0]))s=[...s,...c.slice(1)];else if(e(l,c[c.length-1]))s=[...s,...[...c].reverse().slice(1)];else continue;i.splice(o,1),r=!0;break}}s.length>=4&&e(s[0],s[s.length-1])&&n.push(s.slice(0,-1))}return n}static contains(t,e){let i=!1;for(let n=0,s=t.length-1;n<t.length;s=n++){const r=t[n],o=t[s];r.lat>e.lat!=o.lat>e.lat&&e.lng<(o.lng-r.lng)*(e.lat-r.lat)/(o.lat-r.lat)+r.lng&&(i=!i)}return i}}class CS{constructor(t,e){this.regional=t,this.worldwide=e}attribution="Water © IGN, BD TOPO, in France; © OpenStreetMap contributors elsewhere";async getWater(t){if(oh.covers(t))try{const e=await this.regional.getWater(t);if(e.length>0)return e}catch{}return this.worldwide.getWater(t)}}const Cf="https://ufoathome.org/water/index.json";class mc{attributionRead;fetchImpl;indexUrls;fallback;index;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??mc.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Water © OpenStreetMap contributors"}async getWater(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getWater(t);return this.attributionRead=this.fallback.attribution,i}async held(t){const i=(await this.load().catch(()=>[])).find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.surfaces)?(this.attributionRead=s.attribution,s.surfaces):void 0}catch{return}}load(){if(this.index)return this.index;if(!this.sharing)return this.index=this.fetchFirstAvailable();const t=this.indexUrls.join(`
|
|
2456
|
+
`);let e=mc.shared.get(t);return e||(e=this.fetchFirstAvailable(),mc.shared.set(t,e),e.then(i=>{i.length===0&&mc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.2")}`,e=typeof location>"u"?void 0:new URL("/water/index.json",location.href).href;return(e&&e!==Cf?[e,Cf]:[Cf]).map(i=>i+t)}}class Nn{constructor(t){this.water=t}static CACHE_NAME="rr0-water";static MAX_AGE_MS=720*3600*1e3;static FORMAT=1;static MAX_STORED=400;static asked=new Map;get attribution(){return this.water.attribution}async getWater(t){const e=Nn.key(t);let i=Nn.asked.get(e);return i===void 0&&(i=this.recalled(e,t),Nn.asked.set(e,i),i.catch(()=>Nn.asked.delete(e))),structuredClone(await i)}static forget(){Nn.asked.clear()}static key(t){return`v${Nn.FORMAT}/${[t.north,t.south,t.east,t.west].map(e=>e.toFixed(5)).join("/")}`}async recalled(t,e){const i=await Nn.openCache(),n=Nn.request(t);if(i)try{const r=await i.match(n);if(r){const{savedAt:o,surfaces:c}=await r.json();if(Date.now()-o<Nn.MAX_AGE_MS&&Array.isArray(c))return c;await i.delete(n)}}catch{}const s=await this.water.getWater(e);return i&&Nn.store(i,n,s),s}static async store(t,e,i){try{const n={savedAt:Date.now(),surfaces:i};await t.put(e,new Response(JSON.stringify(n),{headers:{"Content-Type":"application/json"}}));const s=await t.keys();for(const r of s.slice(0,Math.max(0,s.length-Nn.MAX_STORED)))await t.delete(r)}catch{}}static async openCache(){try{return typeof caches>"u"?void 0:await caches.open(Nn.CACHE_NAME)}catch{return}}static request(t){const e=typeof location>"u"?"http://localhost":location.origin;return new Request(`${e}/__water__/${encodeURIComponent(t)}`)}}class ua{attribution="Railways © IGN, BD TOPO (Licence Ouverte 2.0), as drawn today";contemporary=!0;static BY_NATURE={"Voie ferrée principale":{kind:"rail"},LGV:{kind:"rail",highSpeed:!0},"Voie de service":{kind:"rail",service:!0},Métro:{kind:"subway"},Tramway:{kind:"tram"},"Transport urbain":{kind:"light_rail"},"Funiculaire ou crémaillère":{kind:"funicular"}};static GAUGE_MM={Normale:1435,Etroite:1e3,Étroite:1e3,Large:1668};static NO_ALTITUDE=-1e3;platform;constructor(t={}){this.platform=new _e(t)}static covers(t){return _e.covers((t.south+t.north)/2,(t.west+t.east)/2)}async getRailways(t){return(await this.platform.railways(t)).flatMap((i,n)=>ua.linesOf(i,n))}static linesOf(t,e){const{type:i,coordinates:n}=t.geometry,s=i==="LineString"?[n]:i==="MultiLineString"?n:[],r=ua.BY_NATURE[String(t.properties.nature??"")];if(!r)return[];const o=String(t.properties.cleabs??`ign-rail-${e}`),c=Number(t.properties.nombre_de_voies),l=Number(t.properties.position_par_rapport_au_sol),h=t.properties.cpx_toponyme,u=ua.GAUGE_MM[String(t.properties.largeur??"")]??1435,d=ua.electrificationOf(r.kind,u,t.properties.electrifie);return s.flatMap((f,p)=>{const v=f.map(m=>({lat:m[1],lng:m[0],...m.length>2&&Number.isFinite(m[2])&&m[2]>ua.NO_ALTITUDE?{altitudeM:m[2]}:{}}));return v.length<2?[]:[{id:s.length>1?`${o}-${p}`:o,...typeof h=="string"&&h.length>0?{name:h}:{},kind:r.kind,...r.service?{service:!0}:{},...r.highSpeed?{highSpeed:!0}:{},gaugeMm:u,tracks:Number.isInteger(c)&&c>0?c:1,...d?{electrification:d}:{},level:Number.isFinite(l)?l:0,points:v}]})}static electrificationOf(t,e,i){if(i===!1)return"none";if(i===!0){if(t==="subway")return"third_rail";if(!(t==="funicular"||e<1435))return"overhead"}}}class gc{attribution="Railways © OpenStreetMap contributors, as surveyed today";contemporary=!0;static KINDS=["rail","light_rail","tram","subway","narrow_gauge","funicular","preserved"];client;constructor(t={}){this.client=new Jn(t)}async getRailways(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:25];way["railway"~"^(${gc.KINDS.join("|")})$"](${e});out tags geom;`;return this.linesFrom(await this.client.query(i))}linesFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;if(!s||!n||n.length<2)continue;const r=gc.kindOf(s),o=Number.parseInt((s.gauge??"").split(";")[0],10),c=Number.parseInt(s.tracks??"",10),l=gc.electrificationOf(s.electrified),h=s.highspeed==="yes"||Number.parseInt(s.maxspeed??"",10)>=250;e.push({id:`osm-rail-${i.id??e.length}`,...s.name?{name:s.name}:{},kind:r,...s.service||s.usage==="industrial"?{service:!0}:{},...h?{highSpeed:!0}:{},gaugeMm:Number.isFinite(o)&&o>300?o:s.railway==="narrow_gauge"?1e3:1435,tracks:Number.isFinite(c)&&c>0?c:1,...l?{electrification:l}:{},level:gc.levelOf(s),points:n.map(u=>({lat:u.lat,lng:u.lon}))})}return e}static kindOf(t){switch(t.railway){case"tram":return"tram";case"subway":return"subway";case"light_rail":return"light_rail";case"funicular":return"funicular";default:return"rail"}}static electrificationOf(t){if(t!==void 0){if(t==="no")return"none";if(t==="contact_line"||t==="yes")return"overhead";if(t==="rail"||t==="4th_rail"||t==="ground-level_power_supply")return"third_rail"}}static levelOf(t){const e=Number.parseInt(t.layer??"",10);return t.tunnel&&t.tunnel!=="no"?Number.isFinite(e)&&e<0?e:-1:t.covered==="yes"&&t.location==="underground"?-1:t.bridge&&t.bridge!=="no"?Number.isFinite(e)&&e>0?e:1:0}}class OS{constructor(t,e){this.regional=t,this.worldwide=e}attribution="Railways © IGN, BD TOPO, in France; © OpenStreetMap contributors elsewhere, as drawn today";contemporary=!0;async getRailways(t){if(!ua.covers(t))return this.worldwide.getRailways(t);let e;try{if(e=await this.regional.getRailways(t),e.length>0)return e}catch{}try{return await this.worldwide.getRailways(t)}catch(i){if(e)return e;throw i}}}class Fi{constructor(t,e=Date.now){this.railways=t,this.now=e}static CACHE_NAME="rr0-railways";static MAX_AGE_MS=720*3600*1e3;static FORMAT=1;static MAX_STORED=400;static RETRY_AFTER_MS=300*1e3;static asked=new Map;static failedAt=-1/0;get attribution(){return this.railways.attribution}get contemporary(){return this.railways.contemporary}async getRailways(t){const e=Fi.key(t);let i=Fi.asked.get(e)??Fi.containing(t);if(i===void 0){const n=this.recalled(e,t);i={bounds:t,answer:n},Fi.asked.set(e,i),n.catch(()=>Fi.asked.delete(e))}return structuredClone(await i.answer)}static forget(){Fi.asked.clear(),Fi.failedAt=-1/0}static key(t){return`v${Fi.FORMAT}/${[t.north,t.south,t.east,t.west].map(e=>e.toFixed(5)).join("/")}`}static containing(t){for(const e of Fi.asked.values()){const i=e.bounds;if(i.north>=t.north&&i.south<=t.south&&i.east>=t.east&&i.west<=t.west)return e}}async recalled(t,e){const i=await Fi.openCache(),n=Fi.request(t);let s;if(i)try{const o=await i.match(n);if(o){const{savedAt:c,lines:l}=await o.json();if(Array.isArray(l)){if(this.now()-c<Fi.MAX_AGE_MS)return l;s=l}}}catch{}if(this.now()-Fi.failedAt<Fi.RETRY_AFTER_MS){if(s)return s;throw new Error("The railway survey failed a moment ago: not asked again yet")}let r;try{r=await this.railways.getRailways(e)}catch(o){if(Fi.failedAt=this.now(),s)return s;throw o}return i&&Fi.store(i,n,{savedAt:this.now(),lines:r}),r}static async store(t,e,i){try{await t.delete(e),await t.put(e,new Response(JSON.stringify(i),{headers:{"Content-Type":"application/json"}}));const n=await t.keys();for(const s of n.slice(0,Math.max(0,n.length-Fi.MAX_STORED)))await t.delete(s)}catch{}}static async openCache(){try{return typeof caches>"u"?void 0:await caches.open(Fi.CACHE_NAME)}catch{return}}static request(t){const e=typeof location>"u"?"http://localhost":location.origin;return new Request(`${e}/__railways__/${encodeURIComponent(t)}`)}}const Of="https://ufoathome.org/railways/index.json";class vc{contemporary=!0;attributionRead;fetchImpl;indexUrls;fallback;index;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??vc.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Railways © OpenStreetMap contributors"}async getRailways(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRailways(t);return this.attributionRead=this.fallback.attribution,i}async held(t){const i=(await this.load().catch(()=>[])).find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.lines)?(this.attributionRead=s.attribution,s.lines):void 0}catch{return}}load(){if(this.index)return this.index;if(!this.sharing)return this.index=this.fetchFirstAvailable();const t=this.indexUrls.join(`
|
|
2457
|
+
`);let e=vc.shared.get(t);return e||(e=this.fetchFirstAvailable(),vc.shared.set(t,e),e.then(i=>{i.length===0&&vc.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.127.2")}`,e=typeof location>"u"?void 0:new URL("/railways/index.json",location.href).href;return(e&&e!==Of?[e,Of]:[Of]).map(i=>i+t)}}function PS(){return{elevation:LS(),imagery:dy(),roads:NS(),water:kS(),railways:US()}}function LS(){return new _S(new xe,new SS)}function dy(){return new IS}function NS(){return new pc({fallback:new DS(new ha,new aa)})}function kS(){return new mc({fallback:new Nn(new CS(new oh,new Ba))})}function US(){return new vc({fallback:new Fi(new OS(new ua,new gc))})}const FS=new Set,cr="show-observer-map",lr="hide-milestones",no="minified";class be extends HTMLElement{static get observedAttributes(){return["src",cr,lr,no]}shadow;stageElement;canvas;canvasRenderer;chromeCanvas;chromeRenderer;chromeResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>{this.chromeDirty&&this.refresh()});chromeDirty=!1;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;accountHidden=!1;referenceViews=new Map;referencesMenu;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new fi;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;playerTitleBox;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=cf.create();issues=[];issueCheck=0;sightingAudio=new nS;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;static LIVE_BODY_MAX_RATE=2;get steadyBody(){return this.steadyObserver||this.player.playbackState!=="playing"||this.player.playbackRate>be.LIVE_BODY_MAX_RATE}selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=ny;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");be.setIcon(this.moreButton,t?Xt.UNFOLDED:Xt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<be.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=fi.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=fi.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},be.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=fi.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Kw}</style>${qw}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new Wc(this.canvas.getContext("2d")),this.chromeCanvas=this.shadow.getElementById("chrome"),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",i=>{i.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.referencesMenu=this.shadow.getElementById("references-menu"),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 za(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.playerTitleBox=this.shadow.getElementById("player-title"),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",i=>{i.key!=="Enter"&&i.key!==" "||(i.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.miniPlayed=this.shadow.getElementById("mini-played"),this.miniRemaining=this.shadow.getElementById("mini-remaining"),this.miniMuteButton=this.shadow.getElementById("mini-mute");const e=this.shadow.getElementById("mini-bar");e.addEventListener("click",i=>{i.stopPropagation();const n=e.getBoundingClientRect(),s=this.player.seekableDuration;n.width<=0||s<=0||this.player.seek(Math.min(Math.max((i.clientX-n.left)/n.width,0),1)*s)}),this.miniMuteButton.addEventListener("click",i=>{i.stopPropagation(),this.toggleMuted()}),this.stageElement.addEventListener("pointerenter",this.handleMinifiedEnter),this.stageElement.addEventListener("pointerleave",this.handleMinifiedLeave),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",i=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(i),this.beginTouchScrub(i)}),this.seekInput.addEventListener("pointerup",i=>{this.seekSnapArmed=!1,this.endTouchScrub(i)}),this.seekInput.addEventListener("pointercancel",i=>this.endTouchScrub(i)),this.seekInput.addEventListener("pointermove",i=>{this.nameMarkUnder(i),this.hoverSeek(i),this.touchScrub(i)}),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 i of["touchend","click"])this.stageElement.addEventListener(i,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",i=>{if(!(!this.enableClickToPlay||this.minified)){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}i.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",i=>{!this.enableClickToPlay||this.minified||(i.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.chromeResizeObserver?.observe(this.chromeCanvas),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.chromeResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===cr&&this.applyObserverMapDefault(),t===lr&&this.setMilestonesShown(!this.hasAttribute(lr)),t===no){const n=this.minified;this.stageElement.classList.toggle("minified",n),n&&e===null&&(this.muted=!0),this.updateStartState()}}get minified(){return this.hasAttribute(no)}miniPlayed;miniRemaining;miniMuteButton;handleMinifiedEnter=t=>{!this.minified||t.pointerType==="touch"||(this.minifiedHovered=!0,this.play())};minifiedHovered=!1;handleMinifiedLeave=t=>{!this.minified||t.pointerType==="touch"||(this.minifiedHovered=!1,this.pause(),this.dispatchEvent(new CustomEvent(py)))};started=!1;updateStartState(){this.playRequested&&(this.started=!0);const t=!this.started&&this.enableClickToPlay;this.stageElement.classList.toggle("unstarted",t),t&&!this.minified?this.canvas.title=this.messages.clickToPlay:this.canvas.removeAttribute("title")}async loadFromSrc(t){this.sightingData=await Fl.json(t)}get sightingData(){return sS(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=aS(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.started=!1,this.syncPlayerTitle(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault(),this.minified&&this.minifiedHovered&&this.play()}set playerTitle(t){this.titleOverride=t,this.syncPlayerTitle()}titleOverride;syncPlayerTitle(){const t=this.said.read(this.titleOverride)??this.currentSighting.observer?.title??"";this.playerTitleBox.textContent=t,this.playerTitleBox.hidden=t===""}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await Xe(async()=>{const{default:r}=await import("./sightingSchema-v2l1p6Ld.js");return{default:r}},[],import.meta.url);n=new ws(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Xc.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(zS,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Xc.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){if(!(this.player.seekableDuration<=0||this.playbackState==="playing")){if(this.clockHeld){this.playAfterHold=!0,this.announcePlayRequest();return}this.togglePlayPause()}}get playRequested(){return this.playbackState==="playing"||this.playAfterHold}announcePlayRequest(){this.started=!0,this.updateStartState(),this.dispatchEvent(new CustomEvent("playrequest"))}clockHeld=!1;playAfterHold=!1;holdClock(t){if(t!==this.clockHeld){if(this.clockHeld=t,t){if(this.playbackState!=="playing")return;this.playAfterHold=!0,this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton();return}this.playAfterHold&&(this.playAfterHold=!1,!(this.player.seekableDuration<=0||this.playbackState==="playing")&&(this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton()))}}pause(){this.playAfterHold=!1,this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateMuteButton(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}repaintOverlay(){this.quietFrame=!0;try{this.player.seek(this.player.time)}finally{this.quietFrame=!1}}quietFrame=!1;hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}get severalReferences(){return this.currentSighting.references.length>1}toggleReferences(){if(this.severalReferences){this.toggleReferencesMenu();return}this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity));for(const e of[...this.referenceViews.keys()])t.some(i=>i.id===e)||this.referenceViews.delete(e);this.severalReferences?this.referencesMenu.hidden||this.renderReferencesMenu():this.closeReferencesMenu(),this.updateReferencesButton(),this.severalReferences&&this.dispatchReferenceView()}viewOfReference(t){let e=this.referenceViews.get(t.id);return e||(e={shown:!0,opacity:t.opacity},this.referenceViews.set(t.id,e)),e}toggleReferencesMenu(){this.referencesMenu.hidden?this.openReferencesMenu():this.closeReferencesMenu()}openReferencesMenu(){this.renderReferencesMenu(),this.referencesMenu.hidden=!1,this.placeReferencesMenu(),this.referencesButton.setAttribute("aria-expanded","true"),document.addEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.addEventListener("keydown",this.handleReferencesMenuKey,!0)}closeReferencesMenu(){this.referencesMenu.hidden||(this.referencesMenu.hidden=!0,this.referencesButton.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.removeEventListener("keydown",this.handleReferencesMenuKey,!0))}handleReferencesMenuOutside=t=>{const e=t.composedPath();e.includes(this.referencesMenu)||e.includes(this.referencesButton)||this.closeReferencesMenu()};handleReferencesMenuKey=t=>{t.key==="Escape"&&(this.closeReferencesMenu(),this.referencesButton.focus())};placeReferencesMenu(){const t=this.referencesButton.getBoundingClientRect(),e=this.referencesMenu,i=4;e.style.bottom=`${Math.max(i,window.innerHeight-t.top+i)}px`,e.style.top="auto";const n=e.getBoundingClientRect().width;e.style.left=`${Math.max(i,Math.min(t.left,window.innerWidth-n-i))}px`}renderReferencesMenu(){const t=this.currentSighting.references.map(e=>{const i=this.viewOfReference(e),n=this.said.read(e.title)??e.id,s=document.createElement("div");s.className="reference-row";const r=document.createElement("label"),o=document.createElement("input");o.type="checkbox",o.checked=i.shown;const c=document.createElement("span");c.textContent=n,c.title=n,r.append(o,c);const l=document.createElement("input");return l.type="range",l.min="0",l.max="1",l.step="0.05",l.value=String(i.opacity),l.title=this.messages.referenceOpacity,l.setAttribute("aria-label",`${this.messages.referenceOpacity}: ${n}`),l.disabled=!i.shown,o.addEventListener("change",()=>{i.shown=o.checked,l.disabled=!i.shown,this.updateReferencesButton(),this.dispatchReferenceView()}),l.addEventListener("input",()=>{i.opacity=Number(l.value),this.dispatchReferenceView()}),s.append(r,l),s});this.referencesMenu.setAttribute("aria-label",this.messages.referencesMenu),this.referencesMenu.replaceChildren(...t)}updateReferencesButton(){const t=this.currentSighting.references.length>0,e=this.severalReferences,i=e?this.currentSighting.references.some(s=>this.viewOfReference(s).shown):this.referencesShownState;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState||e,this.referencesButton.setAttribute("aria-pressed",String(i)),e?this.referencesButton.setAttribute("aria-haspopup","true"):this.referencesButton.removeAttribute("aria-haspopup"),be.setIcon(this.referencesButton,i?Xt.PICTURES_ON:Xt.PICTURES_OFF);const n=e?this.messages.referencesMenu:this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=n,this.referencesButton.setAttribute("aria-label",n),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),be.setIcon(this.tracesButton,this.tracesShownState?Xt.TRACES_ON:Xt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){const t=this.severalReferences?Object.fromEntries(this.currentSighting.references.map(e=>[e.id,{...this.viewOfReference(e)}])):void 0;this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity,views:t}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Bl(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",r=this.said.read(i.note),o=r?`${s} — ${r}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const r=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${r} — ${o}`:r,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(r=>r>0&&r<t))].sort((r,o)=>r-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let r=0;r<n.length-1;r++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[r+1]-n[r],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[r],end:n[r+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintMiniProgress(t){const e=this.player.seekableDuration;this.miniPlayed.style.width=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`,this.miniRemaining.textContent=this.formatRemaining(t)}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=be.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,r=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=be.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===r))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?Rf(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}paintChrome(t){const e=this.chromeCanvas.getContext("2d"),i=this.overlayPainter!==void 0||this.selectionShown;if(!i&&!this.chromeDirty)return;const n=this.chromeCanvas.clientWidth,s=this.chromeCanvas.clientHeight;if(!e||typeof e.setTransform!="function"||n===0||s===0){t(this.canvasRenderer);return}const r=window.devicePixelRatio||1,o=Math.max(1,Math.round(n*r)),c=Math.max(1,Math.round(s*r));this.chromeCanvas.width!==o&&(this.chromeCanvas.width=o),this.chromeCanvas.height!==c&&(this.chromeCanvas.height=c),e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,o,c),this.chromeDirty=!1,i&&(e.setTransform(o/this.canvas.width,0,0,c/this.canvas.height,0,0),this.chromeRenderer??=new Wc(e),this.chromeDirty=!0,t(this.chromeRenderer))}chromeDraw;repaintChrome(){this.chromeDraw&&this.overlayPainter&&this.paintChrome(this.chromeDraw)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=be.MARK_SNAP_PX/i*e;let s;for(const r of this.milestoneMarks.children){const o=Number(r.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:r.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?Rf(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=Ts.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<be.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(be.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/be.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/be.EXPOSURE_STEP_PX),s=Math.min(be.MAX_TRAVEL_STEPS,Math.max(i,n)),r=[];for(let o=0;o<s;o++)r.push(e.fromMs+e.ms*o/(s-1));return r}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[r,o]of i){const c=n.get(r);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){if(!this.accountHidden)for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=Li.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:FS;this.canvasRenderer.setStarPoints(Li.starPointsOf(this.sighting.instrument));const n=(ei(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),r=this.frameShift;if(this.paintsShapes)for(const c of s)for(const[,l]of c.shapes){const h=c.share,u=h===1?l:{...l,transparency:1-(1-l.transparency)*h};this.canvasRenderer.paintShape(this.shifted(u,r))}for(const[c,l]of s[0].shapes)!this.selectionShown||!i.has(c)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,r)));const o=this.selectionShown&&i.size>1?jn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds)):void 0;this.chromeDraw=c=>{o&&c.paintGroupHandles(o),this.overlayPainter?.(c)},this.paintChrome(this.chromeDraw),this.mapShapeBounds=s.flatMap(c=>[...c.shapes.values()].filter(l=>l.transparency<1).map(l=>this.shifted(l,r).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.minified&&this.paintMiniProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(K2(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),!this.quietFrame&&this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Zw(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*be.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){if(!(this.player.seekableDuration<=0)){if(this.player.playbackState==="playing")this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh();else if(this.clockHeld){this.playAfterHold=!this.playAfterHold,this.playAfterHold&&this.announcePlayRequest();return}else this.announcePlayRequest(),this.sightingAudio.resume(),this.player.play();this.updatePlayPauseButton(),this.flashPlayback()}}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Xt.PLAY:Xt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){be.icons.get(t)!==e&&(be.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}set controlsHeld(t){this.stageElement.classList.toggle("controls-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},be.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,this.updateStartState(),be.setIcon(this.playPauseButton,t?Xt.PAUSE:Xt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear(),this.dispatchEvent(new CustomEvent("observermapchange",{bubbles:!0,composed:!0,detail:{open:t}}))}get observerMapOpen(){return!this.observerMapPanel.hidden}get milestonesVisible(){return this.milestonesShown}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(cr),e=t===null?this.sighting.observerMap??this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;be.setIcon(this.observerMapButton,t?Xt.MAP_ON:Xt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Rc.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=fi.including(this.observerPath.boundsAround(be.OBSERVER_MAP_MIN_SPAN_M,be.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?fi.expand(t,be.OBSERVER_MAP_IMAGERY_AHEAD):t,n=be.OBSERVER_MAP_IMAGERY_PX*(e?1+2*be.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=dy();try{const r=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=r,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?fi.expand(t,be.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,r=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!r}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],r=be.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],r))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=ei(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},be.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?Rf(this.currentSighting.milestones,t):void 0;for(const r of this.milestonesShown?Bl(this.currentSighting.milestones):[]){const o=ei(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?Pr.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(Li.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(r=>({kind:r.kind,points:r.points,color:r.color,label:this.said.read(r.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Bl(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,be.setIcon(this.milestonesButton,this.milestonesShown?Xt.MILESTONES_ON:Xt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=ei(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=or(i,t),{lat:s,lng:r}=is(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:r,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=ei(this.currentSighting,this.currentTime),s=Pr.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return He.bodyAt(this.currentSighting,t,this.steadyBody)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=be.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.hasSound&&(this.muted=!this.mutedState)}ambientSound;get hasSound(){return this.currentSighting.soundTrack.allKeyframes.length>0||this.ambientSound?.(this.currentSighting)===!0}updateMuteButton(){const t=!this.hasSound;this.miniMuteButton.hidden=t,this.miniMuteButton.setAttribute("aria-pressed",String(this.mutedState)),be.setIcon(this.miniMuteButton,this.mutedState?Xt.MUTED:Xt.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;if(this.miniMuteButton.title=e,this.miniMuteButton.setAttribute("aria-label",e),this.muteButton.disabled=t,this.volumeInput.hidden=t,t){be.setIcon(this.muteButton,Xt.MUTED),this.muteButton.title=this.messages.noSound,this.muteButton.setAttribute("aria-label",this.messages.noSound),this.muteButton.setAttribute("aria-pressed","true");return}be.setIcon(this.muteButton,this.mutedState?Xt.MUTED:Xt.VOLUME);const i=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=i,this.muteButton.setAttribute("aria-label",i),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;be.setIcon(this.fullscreenButton,t?Xt.EXIT_FULLSCREEN:Xt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new fs(ya.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=Hm(ya.preferencesFor(this),Gm);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await lS(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=q2(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?ap(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.paintMiniProgress(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return ko(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?U1(k1(this.realStartMs+i)):ko(i)}formatRemaining(t){const e=this.currentSighting.timeline.duration;if(this.realDurationMs===void 0)return ko(Math.max(0,e-t));const i=e>0&&t<=e?t/e*this.realDurationMs:t;return ko(Math.max(0,this.realDurationMs-i))}formatEndOfTimeline(){return this.realDurationMs===void 0?ko(this.currentSighting.timeline.duration):this.canShowClockTime?U1(k1(this.realStartMs+this.realDurationMs)):ko(this.realDurationMs)}}function k1(a){const t=new Date(a);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function U1(a){if(a.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return a.second?`${t(a.hour)}:${t(a.minute??0)}:${t(a.second)}`:`${t(a.hour)}:${t(a.minute??0)}`}function ko(a){const t=Math.round(a/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const lp="rr0-ufo";function fy(){customElements.get(lp)||customElements.define(lp,be)}const zS="recordingissues",py="minifiedreset";/**
|
|
2441
2458
|
* @license
|
|
2442
2459
|
* Copyright 2010-2026 Three.js Authors
|
|
2443
2460
|
* SPDX-License-Identifier: MIT
|
|
@@ -8423,7 +8440,7 @@ uniform float uWindowLuminance;
|
|
|
8423
8440
|
varying float vLitRank;
|
|
8424
8441
|
${c.fragmentShader.replace("#include <emissivemap_fragment>",`#include <emissivemap_fragment>
|
|
8425
8442
|
totalEmissiveRadiance *= step(vLitRank, uLitShare) * uWindowLuminance * ${wt.WINDOW_VARIETY_GLSL};`)}`},r.customProgramCacheKey=()=>"facade-lit-windows";const o=new xt(s,r);return o.castShadow=!0,o.receiveShadow=!0,e.add(o),e}static litWindowShare={value:0};static WINDOW_LUMINANCE_CD_M2=50;static ROOM_LIGHT_K=2900;static COLD_ROOM_LIGHT_K=4e3;static windowLuminance={value:0};static get WINDOW_VARIETY_GLSL(){const t=n=>`vec3(${n.map(s=>s.toFixed(4)).join(", ")})`,e=zc.ofTemperature(wt.ROOM_LIGHT_K),i=zc.ofTemperature(wt.COLD_ROOM_LIGHT_K);return`(mix(0.35, 2.0, fract(vLitRank * 97.13) * fract(vLitRank * 97.13)) * mix(${t(e)}, ${t(i)}, step(0.86, fract(vLitRank * 53.71))))`}static setWindowLuminance(t){wt.windowLuminance.value=wt.WINDOW_LUMINANCE_CD_M2*t}static setLitWindowShare(t){wt.litWindowShare.value=Math.max(0,Math.min(1,t))}static build(t,e){const i=wt.hasFacade(t)?wt.buildFacade(t):t.kind==="building"?kM(t.floors??bd,t.windows,t.observerSide,t.occupiedFloor,t.observerFacing):t.kind==="tree"?FM():t.kind==="shrub"?UM():t.kind==="bridge"?sC(t):t.kind==="wire"?rC(t):t.kind==="wall"?zi.build(t):t.kind==="crop"?BM():t.kind==="terrace"?fC():t.kind==="mound"?HM():t.kind==="streetlight"?GM(e,t.lamp?.mount,t.lamp):t.kind==="trafficlight"?pe.trafficLight(ee.isPedestrian(t.lights)):t.kind==="crossing"?pe.crossing(wt.sizeOf(t).widthM,wt.sizeOf(t).lengthM):t.kind==="roadsign"?pe.roadSign(t.sign):t.kind==="vehicle"?VM(e,t.windows,t.observerSide,t.observerFacing):t.kind==="aircraft"?KM():t.kind==="entity"?$M():Pm();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Ie;return t.kind==="building"&&t.roof&&this.addRoof(s,t),i.name=wt.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*A0),this.addLights(s,t.lights),wt.fitLights(s,t,t.sizeM??{}),s}static scaleFor(t){const e=t.sizeM;if(!e||wt.hasFacade(t)||t.kind==="bridge"||t.kind==="wire"||t.kind==="terrace"||t.kind==="wall"||t.kind==="crossing")return new R(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new R(e.widthM===void 0?1:D0(e.widthM,i.widthM),e.heightM===void 0?1:D0(t.kind==="building"?this.wallHeightOf(t,e.heightM):e.heightM,i.heightM),e.lengthM===void 0?1:D0(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??bd)+1):0;if(t==="bridge")return ri.NATURAL_SIZE;if(t==="wire")return oo.NATURAL_SIZE;if(t==="terrace"||t==="wall")return{widthM:1,lengthM:1,heightM:1};if(t==="crossing")return{widthM:6,lengthM:2.5,heightM:pe.CROSSING_LIFT_M};const n=`${t}:${i}`,s=WM.get(n);if(s)return s;const r=t==="building"?kM(i-1,void 0,void 0,void 0):t==="tree"?FM():t==="shrub"?UM():t==="crop"?BM():t==="mound"?HM():t==="streetlight"?GM(!1):t==="trafficlight"?pe.trafficLight(!1):t==="roadsign"?pe.roadSign(void 0):t==="vehicle"?VM(!1,void 0,void 0):t==="aircraft"?KM():t==="entity"?$M():Pm(),o=new nn().setFromObject(r),c={widthM:o.max.x-o.min.x,heightM:o.max.y-o.min.y,lengthM:o.max.z-o.min.z};return this.dispose(r),WM.set(n,c),c}static usesModel(t){return wd(t)!==void 0&&!(t.observerSide!==void 0&&Vc(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),r=new Ie;r.name=wt.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*A0,i.updateMatrixWorld(!0);const o=new nn().setFromObject(i),c={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},l=e.kind==="tree"&&e.sizeM?.heightM!==void 0?{heightM:e.sizeM.heightM}:e.sizeM,h=XM(l,c)??XM(n.depictedSizeM,c)??1;i.scale.multiplyScalar(h);const u=o.getCenter(new R).multiplyScalar(h);i.position.x-=u.x,i.position.z-=u.z,i.position.y-=e.kind==="aircraft"?u.y:o.min.y*h,i.traverse(d=>{d instanceof xt&&(d.castShadow=!0,d.receiveShadow=!0)}),r.add(i),e.kind==="tree"&&r.add(wt.trunkShadow(c.heightM*h)),s.parent?(s.parent.add(r),s.removeFromParent()):t.add(r),this.dispose(s),wt.fitLights(t,e,{widthM:c.widthM*h,heightM:c.heightM*h,lengthM:c.lengthM*h})}static fitLights(t,e,i){const n=Sd.byId(Ec.rigOf(e)||void 0)?.referenceSizeM;if(!n||!e.lights)return;const s=(h,u)=>h===void 0||u===0?1:h/u,r=s(i.widthM,n.widthM),o=s(i.heightM,n.heightM),c=s(i.lengthM,n.lengthM),l=new Map(e.lights.map(h=>[h.id,h.offsetM]));t.traverse(h=>{const u=h.userData.lightId,d=u===void 0?void 0:l.get(u);d&&h.position.set(d.x*r,d.y*o,d.z*c)})}static trunkShadow(t){wt.trunkProxy??={geometry:new xn(1,1.15,1,8),material:new Cn({colorWrite:!1,depthWrite:!1})};const e=new xt(wt.trunkProxy.geometry,wt.trunkProxy.material),i=Math.min(.3,Math.max(.12,t*.035)),n=t*.45;return e.scale.set(i,n,i),e.position.y=n/2,e.castShadow=!0,e.receiveShadow=!1,e.userData.sharedModel=!0,e.name="trunk-shadow",e}static trunkProxy;static sizeOf(t){const e=this.naturalSize(t.kind,t.floors);return{widthM:t.sizeM?.widthM??e.widthM,lengthM:t.sizeM?.lengthM??e.lengthM,heightM:t.sizeM?.heightM??e.heightM}}static addLights(t,e){for(const i of e??[]){const n=KD(i.color),s=ee.figureOf(i),r=s?pe.pedestrianFigure(s,1.8*(i.radiusM??T0)):new Ti(i.radiusM??T0,8,6),o=Le(t,r,n,i.offsetM.y,!0);o.position.set(i.offsetM.x,i.offsetM.y,i.offsetM.z),o.userData={emissive:!0,lightId:i.id,lightColor:n},o.visible=!1;const c=o.material;mx.apply(c),c.transparent=!0,c.depthWrite=!1,c.fog=!1}}static setLights(t,e,i,n,s=0,r=1,o=VD,c=[1,1,1],l){if(!e||e.length===0)return;const h=new Map(e.map(d=>[d.id,d]));let u;l&&e.some(d=>d.beamDeg!==void 0)&&(t.updateWorldMatrix(!0,!1),u=t.worldToLocal(wt.eyeScratch.copy(l)));for(const d of t.children){if(!(d instanceof xt))continue;const f=d.userData.lightId;if(!f)continue;const p=h.get(f);if(!p)continue;const v=s>0?Q2(p,i,i+s):Cw(p,i)?1:0,m=u&&p.beamDeg!==void 0?wt.beamShare(p.beamDeg,d.position,u):1;d.visible=v>0&&m>0;const g=p.radiusM??T0,y=Math.max(1,n*o/g),x=g*y,M=r/(Math.PI*x*x),w=d.material,S=d.userData.lightColor;if(S){const _=v*m*WD*(p.intensity??1)*M,b=[S[0]*_*c[0],S[1]*_*c[1],S[2]*_*c[2]],A=Math.min(1,LM/Math.max(b[0],b[1],b[2],1e-30));w.color.setRGB(b[0]*A,b[1]*A,b[2]*A)}d.scale.setScalar(y)}}static eyeScratch=new R;static beamShare(t,e,i){const n=i.x-e.x,s=i.y-e.y,r=i.z-e.z,o=Math.hypot(n,s,r);if(o===0)return 1;const c=-r/o;if(c<=0)return 0;const l=Math.log(.5)/Math.log(Math.cos(t*Math.PI/180));return Math.pow(c,l)}static setLit(t,e,i,n=1,s){const[r,o,c]=e==="streetlight"?[XD*wt.lampShare(s),YD,wt.lampHue(s)]:[$D,qD,Hx],l=i?r*n/(Math.PI*o*o):0,h=Math.min(1,LM/Math.max(c[0]*l,c[1]*l,c[2]*l,1e-30)),u=[c[0]*l*h,c[1]*l*h,c[2]*l*h];t.traverse(d=>{const f=d.userData;!(d instanceof xt)||!f.emissive||f.lightId||(d.material instanceof vs?d.material.emissive.setRGB(...u):d.material.color.setRGB(...u))})}static REFERENCE_LUMENS=1e4;static lampShare(t){return t?.lumens?t.lumens/wt.REFERENCE_LUMENS:1}static lampHue(t){return t?.colorTemperatureK?zc.ofTemperature(t.colorTemperatureK):JD}static dispose(t){t.traverse(e=>{if(!(e instanceof xt))return;if(e.userData.sharedModel){for(const n of e.userData.tintedMaterials??[])n.dispose();return}e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const O0="https://ufoathome.org/models/index.json";class jl{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??vC()}async entries(t){const e=await this.load();return t?e.filter(i=>[i.kind].flat().includes(t)):e}async entry(t){return(await this.load()).find(e=>e.id===t)}load(){if(this.loading)return this.loading;if(!this.sharing)return this.loading=this.fetchFirstAvailable();const t=this.indexUrls.join(`
|
|
8426
|
-
`);let e=jl.shared.get(t);return e||(e=this.fetchFirstAvailable(),jl.shared.set(t,e),e.then(i=>{i.length===0&&jl.shared.delete(t)})),this.loading=e}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function vC(){const a=`?v=${encodeURIComponent("0.127.
|
|
8443
|
+
`);let e=jl.shared.get(t);return e||(e=this.fetchFirstAvailable(),jl.shared.set(t,e),e.then(i=>{i.length===0&&jl.shared.delete(t)})),this.loading=e}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function vC(){const a=`?v=${encodeURIComponent("0.127.2")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==O0?[t,O0]:[O0]).map(e=>e+a)}const MC=[{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 jl}];async function P0(a){const{GLTFLoader:t}=await Xe(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-DjN5_ISf.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(a,s=>i(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${a}: ${s instanceof Error?s.message:String(s)}`)))})}const qx=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class ts{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(t,e){this.mesh=new xt(new On(2,2),new De({uniforms:{uColor:{value:new nt(0,0,0)},uRadius:{value:1}},vertexShader:ts.VERTEX,fragmentShader:ts.FRAGMENT,transparent:!0,depthWrite:!1,blending:$i,toneMapped:!1})),this.mesh.name=t,this.mesh.frustumCulled=!1,this.mesh.renderOrder=e,this.mesh.visible=!1}shine(t,e,i){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.material.uniforms.uRadius.value=e,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(t,e,i,n){const s=Math.max(t,n*ts.MIN_ANGLE_RAD),r=ts.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(ts.MAX_SHARE,e/r)}}static conserving(t){return Math.sqrt(t/(ts.MAX_SHARE*ts.FILL*Math.PI))}static VERTEX=`
|
|
8427
8444
|
uniform float uRadius;
|
|
8428
8445
|
varying vec2 vOffset;
|
|
8429
8446
|
void main() {
|
|
@@ -9121,5 +9138,5 @@ void main() {
|
|
|
9121
9138
|
}
|
|
9122
9139
|
`;function A2(a){const e=document.createElement("canvas");e.width=128,e.height=128;const i=e.getContext("2d"),n=128/2-2,s=128/2,r=128/2,o="#010101",c="#f4f1e2";i.fillStyle=o,i.beginPath(),i.arc(s,r,n,0,Math.PI*2),i.fill();const l=Xs(a.illuminatedFraction,0,1),h=a.phaseFraction<.5,u=n*Math.abs(1-2*l),d=l<.5;return i.save(),i.beginPath(),i.arc(s,r,n,0,Math.PI*2),i.clip(),i.fillStyle=c,i.beginPath(),h?(i.arc(s,r,n,-Math.PI/2,Math.PI/2,!1),i.ellipse(s,r,u,n,0,Math.PI/2,-Math.PI/2,d)):(i.arc(s,r,n,Math.PI/2,-Math.PI/2,!1),i.ellipse(s,r,u,n,0,-Math.PI/2,Math.PI/2,d)),i.fill(),i.restore(),new Gr(e)}function E6(a){const t=document.createElement("canvas");t.width=128,t.height=128;const e=t.getContext("2d");return e.fillStyle="rgba(0, 0, 0, 0.55)",e.beginPath(),e.arc(64,64,60,0,Math.PI*2),e.fill(),e.fillStyle="#ffffff",e.font="bold 52px sans-serif",e.textAlign="center",e.textBaseline="middle",e.fillText(a,64,68),new Gr(t)}function K0(a){let t=a;return function(){t|=0,t=t+1831565813|0;let i=Math.imul(t^t>>>15,1|t);return i=i+Math.imul(i^i>>>7,61|i)^i,((i^i>>>14)>>>0)/4294967296}}class Zd{constructor(t,e){this.source=t,this.create=e}scene;wanted;pumping=!1;disposed=!1;static PATIENCE_FRAMES=600;static SCENE_WIDTH_PX=480;paint(t,e){this.disposed||(this.wanted={t,canvas:e},this.pumping||this.pump())}recordingChanged(t){this.scene&&(this.scene.sightingData=t)}dispose(){this.disposed=!0,this.scene?.remove(),this.scene=void 0}ensureScene(){if(this.scene)return this.scene;const t=this.create();return t.setAttribute("max-pixel-ratio","1"),t.setAttribute("always-live",""),Object.assign(t.style,{position:"fixed",left:"-10000px",top:"0",width:`${Zd.SCENE_WIDTH_PX}px`,visibility:"hidden",pointerEvents:"none"}),document.body.appendChild(t),t.documentUrl=this.source.documentUrl,t.accountInTheRound=this.source.accountInTheRound,t.sightingData=this.source.sightingData,this.scene=t,t}async pump(){this.pumping=!0;try{for(;this.wanted&&!this.disposed;){const{t,canvas:e}=this.wanted;this.wanted=void 0;const i=this.ensureScene();i.interpretation!==this.source.interpretation&&(i.interpretation=this.source.interpretation),i.compareAccount!==this.source.compareAccount&&(i.compareAccount=this.source.compareAccount),i.showAt(t);for(let n=0;n<Zd.PATIENCE_FRAMES&&!this.wanted&&!this.disposed&&(await new Promise(s=>requestAnimationFrame(()=>s())),!this.wanted);n++)if(i.snapshotTo(e)){e.dataset.ready="true";break}}}finally{this.pumping=!1}}}const Z0=7.5,J0=9;class Ys{static cache=new Map;static load(t){let e=Ys.cache.get(t);return e||(e=fetch(t).then(i=>i.arrayBuffer()).then(i=>Ys.parse(i)),Ys.cache.set(t,e)),e}static upTo(t,e){const i=t.filter((r,o)=>o===0||t[o-1].magnitudeLimit<e);if(i.length<=1)return Ys.load(t[0].url);const n=i.map(r=>r.url).join(`
|
|
9123
9140
|
`);let s=Ys.cache.get(n);return s||(s=Promise.all(i.map(r=>Ys.load(r.url))).then(r=>r.reduce((o,c)=>Ys.concat(o,c))),Ys.cache.set(n,s)),s}static parse(t){const e=t.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=e*Float32Array.BYTES_PER_ELEMENT;return{count:e,ra:new Float32Array(t,0*i,e),dec:new Float32Array(t,1*i,e),mag:new Float32Array(t,2*i,e),ci:new Float32Array(t,3*i,e)}}static concat(t,e){const i=(n,s)=>{const r=new Float32Array(n.length+s.length);return r.set(n,0),r.set(s,n.length),r};return{count:t.count+e.count,ra:i(t.ra,e.ra),dec:i(t.dec,e.dec),mag:i(t.mag,e.mag),ci:i(t.ci,e.ci)}}}class Be{constructor(t){if(this.heights=t,t.length!==Be.WIDTH*Be.HEIGHT)throw new Error(`a lunar relief has ${Be.WIDTH*Be.HEIGHT} samples, not ${t.length}`)}static SAMPLES_PER_DEGREE=16;static WIDTH=360*Be.SAMPLES_PER_DEGREE;static HEIGHT=180*Be.SAMPLES_PER_DEGREE;static UNIT_KM=.1;static REFERENCE_RADIUS_KM=1737.4;static BAND_FROM_DEG=74;static BAND_TO_DEG=106;heightKm(t,e){const i=Be.SAMPLES_PER_DEGREE,n=(e%360+360)%360*i-.5,s=(90-t)*i-.5,r=Math.floor(n),o=Math.floor(s),c=n-r,l=s-o,h=(f,p)=>{const v=(f%Be.WIDTH+Be.WIDTH)%Be.WIDTH,m=Math.min(Be.HEIGHT-1,Math.max(0,p));return this.heights[m*Be.WIDTH+v]},u=h(r,o)*(1-c)+h(r+1,o)*c,d=h(r,o+1)*(1-c)+h(r+1,o+1)*c;return(u*(1-l)+d*l)*Be.UNIT_KM}static inBand(t,e){const i=Math.PI/180,n=Math.acos(Math.cos(t*i)*Math.cos(e*i))*180/Math.PI;return n>=Be.BAND_FROM_DEG&&n<=Be.BAND_TO_DEG}static withBump(t,e,i,n=.4){const s=new Int8Array(Be.WIDTH*Be.HEIGHT),r=Be.SAMPLES_PER_DEGREE,o=Math.ceil(n*r),c=Math.floor(e*r),l=Math.floor((90-t)*r);for(let h=-o;h<=o;h++)for(let u=-o;u<=o;u++)Math.hypot(u,h)<=o&&(s[(l+h)*Be.WIDTH+(c+u+Be.WIDTH)%Be.WIDTH]=Math.round(i/Be.UNIT_KM));return new Be(s)}static smooth(){return new Be(new Int8Array(Be.WIDTH*Be.HEIGHT))}}class hs{static SAMPLES=5760;static SEARCH_FROM_DEG=87;static SEARCH_TO_DEG=90.2;static SEARCH_STEP_DEG=.0625;static profile(t,e,i,n=hs.SAMPLES){const{s,u:r,w:o,distanceKm:c}=hs.frame(t,e),l=Math.PI/180,h=new Float32Array(n),u=Be.REFERENCE_RADIUS_KM;for(let d=0;d<n;d++){const f=d/n*2*Math.PI,p=Math.cos(f),v=Math.sin(f),m=p*r[0]+v*o[0],g=p*r[1]+v*o[1],y=p*r[2]+v*o[2];let x=0;for(let M=hs.SEARCH_FROM_DEG;M<=hs.SEARCH_TO_DEG;M+=hs.SEARCH_STEP_DEG){const w=Math.cos(M*l),S=Math.sin(M*l),_=w*s[0]+S*m,b=w*s[1]+S*g,A=w*s[2]+S*y,D=Math.asin(Math.max(-1,Math.min(1,A)))/l,I=Math.atan2(b,_)/l,O=u+i.heightKm(D,I),N=Math.atan2(O*S,c-O*w);N>x&&(x=N)}h[d]=x/l}return{radiusDeg:h,meanRadiusDeg:Math.asin(u/c)/l}}static frame(t,e){const i=new zr(e.lat,e.lng,e.elevationM),n=Br(t),s=ym(t,i,!1),r=new Re(s.x-n.x,s.y-n.y,s.z-n.z,n.t),o=Math.hypot(r.x,r.y,r.z)*hs.AU_KM,c=hs.bodyFixed(t),l=c(r),h=Math.hypot(l[0],l[1],l[2]),u=[l[0]/h,l[1]/h,l[2]/h],d=KI(t,i),f=Tg(d),p=kr(d,new Re(-r.x,-r.y,-r.z,n.t)),v=Math.asin(p.z/Math.hypot(p.x,p.y,p.z)),m=Math.atan2(-p.y,p.x),g=new Re(-Math.sin(v)*Math.cos(m),Math.sin(v)*Math.sin(m),Math.cos(v),n.t),y=new Re(-Math.sin(m),-Math.cos(m),0,n.t);return{s:u,u:c(kr(f,g)),w:c(kr(f,y)),distanceKm:o}}static surfacePoint(t,e,i,n){const{s,u:r,w:o}=hs.frame(t,e),c=Math.PI/180,l=[0,1,2].map(u=>Math.cos(i*c)*r[u]+Math.sin(i*c)*o[u]),h=[0,1,2].map(u=>Math.cos(n*c)*s[u]+Math.sin(n*c)*l[u]);return{latDeg:Math.asin(h[2])/c,lonDeg:Math.atan2(h[1],h[0])/c}}static radiusAt(t,e){const i=t.radiusDeg.length,n=(e/360*i%i+i)%i,s=Math.floor(n),r=n-s;return t.radiusDeg[s]*(1-r)+t.radiusDeg[(s+1)%i]*r}static uncoveredFraction(t,e,i){const n=t.radiusDeg.length,s=i.upDeg*i.upDeg+i.rightDeg*i.rightDeg;let r=0;for(let o=0;o<n;o++){const c=o/n*2*Math.PI,l=Math.cos(c),h=Math.sin(c),u=l*i.upDeg+h*i.rightDeg,d=u*u-s+e*e;if(d<=0)continue;const f=Math.sqrt(d),p=u+f;if(p<=0)continue;const v=Math.max(0,u-f),m=Math.max(v,t.radiusDeg[o]);p>m&&(r+=.5*(p*p-m*m))}return Math.min(1,Math.max(0,r*(2*Math.PI/n)/(Math.PI*e*e)))}static AU_KM=1495978707e-1;static bodyFixed(t){const e=uD(ut.Moon,t),i=Math.PI/180,n=e.ra*15*i,s=e.dec*i,r=e.spin*i,o=(l,[h,u,d])=>[Math.cos(l)*h+Math.sin(l)*u,-Math.sin(l)*h+Math.cos(l)*u,d],c=(l,[h,u,d])=>[h,Math.cos(l)*u+Math.sin(l)*d,-Math.sin(l)*u+Math.cos(l)*d];return l=>o(r,c(Math.PI/2-s,o(Math.PI/2+n,[l.x,l.y,l.z])))}static subObserverPoint(t,e){const i=new zr(e.lat,e.lng,e.elevationM),n=Br(t),s=ym(t,i,!1),r=hs.bodyFixed(t)(new Re(s.x-n.x,s.y-n.y,s.z-n.z,n.t)),o=Math.hypot(r[0],r[1],r[2]);return{latDeg:Math.asin(r[2]/o)*180/Math.PI,lonDeg:Math.atan2(r[1],r[0])*180/Math.PI}}}class Ql{static cache=new Map;static load(t){let e=Ql.cache.get(t);return e||(e=Ql.fetchRelief(t).catch(()=>{}),Ql.cache.set(t,e)),e}static async fetchRelief(t){const e=await fetch(t);if(!e.ok)return;let i=new Uint8Array(await e.arrayBuffer());if(i[0]===31&&i[1]===139){if(typeof DecompressionStream>"u")return;const n=new Blob([i]).stream().pipeThrough(new DecompressionStream("gzip"));i=new Uint8Array(await new Response(n).arrayBuffer())}return new Be(new Int8Array(i.buffer,i.byteOffset,i.length))}}class Jd{static ID="color-vision";static MATRICES={protan:[.152286,1.052583,-.204868,.114503,.786281,.099216,-.003882,-.048116,1.051998],deutan:[.367322,.860646,-.227968,.280085,.672501,.047413,-.01182,.04294,.968881],tritan:[1.255528,-.076749,-.178779,-.078411,.930809,.147602,.004733,.691367,.3039]};id=Jd.ID;label="Colour vision";hint="How colours look to someone whose cones differ, from Machado et al. 2009. Only recolours: it does not change brightness or what the eye can resolve.";sources=["Machado, Oliveira, Fernandes, A Physiologically-based Model for Simulation of Color Vision Deficiency, IEEE TVCG 15(6), 2009"];settings=[{id:"type",label:"Type",kind:"choice",default:"normal",choices:[{id:"normal",label:"Typical"},{id:"protan",label:"Protan (red-weak or red-blind)"},{id:"deutan",label:"Deutan (green-weak or green-blind)"},{id:"tritan",label:"Tritan (blue-weak or blue-blind)"}]},{id:"severity",label:"Severity",kind:"number",default:100,min:0,max:100,step:5,unit:"%"}];perceive(t){const e=Jd.MATRICES[String(t.type)];if(!e)return Wn.NONE;const i=Number(t.severity??100),n=Math.max(0,Math.min(100,Number.isFinite(i)?i:100))/100;return{colorMatrix:e.map((r,o)=>Wn.IDENTITY[o]+(r-Wn.IDENTITY[o])*n),contrastGain:1}}}class Pg{static ID="fatigue";id=Pg.ID;label="Fatigue";hint="Stated only: sleep loss has not been shown to change what a healthy eye receives, so the picture is unchanged. It bears on attention and memory, not on vision.";sources=["Studies of contrast sensitivity during prolonged sleep deprivation (60 hours, naval officers): no significant change"];settings=[{id:"hoursAwake",label:"Awake for",kind:"number",default:0,min:0,max:72,step:1,unit:"h"}];perceive(t){return Wn.NONE}}class Ga{static ID="intoxication";static MEASURED_LEVEL=.08;static MEASURED_LOSS_DB=.9;static MAX_EFFECT_LEVEL=.1;static MAX_LEVEL=.5;id=Ga.ID;label="Alcohol";hint="Lowers contrast sensitivity by about 0.9 dB at 0.08 % blood alcohol (one controlled study, results vary), drawn up to 0.1 % at most: a higher level is recorded but shown as 0.1 %, since nothing was measured past it. Double vision, narrowed field and other drugs are not modelled: no source quantifies them.";sources=["Frontiers in Neuroscience, 2022, doi:10.3389/fnins.2022.873671 (contrast sensitivity at about 0.08 % blood alcohol)"];settings=[{id:"bloodAlcohol",label:"Blood alcohol",kind:"number",default:0,min:0,max:Ga.MAX_LEVEL,step:.01,unit:"%",also:{unit:"g/L",factor:10,digits:1}}];perceive(t){const e=Number(t.bloodAlcohol??0),i=Math.max(0,Math.min(Ga.MAX_EFFECT_LEVEL,Number.isFinite(e)?e:0));if(i===0)return Wn.NONE;const n=i/Ga.MEASURED_LEVEL*Ga.MEASURED_LOSS_DB;return{colorMatrix:Wn.IDENTITY,contrastGain:10**(-n/20)}}}class th{static ALL=[new Jd,new Ga,new Pg];static byId(t){return th.ALL.find(e=>e.id===t)}static perceptionOf(t){return th.ALL.reduce((e,i)=>Wn.combine(e,i.perceive(t?.[i.id]??{})),Wn.NONE)}static compact(t){const e={};for(const i of th.ALL){const n=t[i.id]??{},s=Object.fromEntries(i.settings.filter(r=>n[r.id]!==void 0&&n[r.id]!==r.default).map(r=>[r.id,n[r.id]]));Object.keys(s).length>0&&(e[i.id]=s)}return Object.keys(e).length>0?e:void 0}}class jd{constructor(t){this.names=t}body(t,e){return this.names?.bodies[t]??e}star(t){return this.names?.stars[t.name]??t.name}comet(t){return this.names?.comets[t.id]??t.name}nova(t){return this.names?.novae[t.id]??t.name}satelliteClass(t){return this.names?.satelliteClasses[t.id]??t.name}shower(t){return this.names?.showers[t.id]??t.name}lightRig(t){return this.names?.lightRigs[t.id]??t.name}instrument(t){return this.names?.instruments[t.id]??t.name}decorKind(t,e){return this.names?.decorKinds[t]??e}point(t){return fo.point(t,this.names?.compassPoints)}towards(t){return fo.towards(t,this.names)}}class Lg{constructor(t,e){this.element=t,this.onChange=e,t.addEventListener("error",()=>{this.url=void 0,this.release()})}shown=!1;url;get up(){return this.shown}show(t,e,i=!0){const n=Lg.resolve(t,e);if(this.url=n,!n||!i){this.release();return}this.element.src=n,this.element.hidden=!1;const s=this.shown;this.shown=!0,s||this.onChange()}release(){this.shown&&(this.shown=!1,this.element.hidden=!0,this.element.removeAttribute("src"),this.onChange())}restore(){this.url&&this.show(this.url)}static resolve(t,e){if(!(typeof t!="string"||t.trim()===""))try{const i=new URL(t.trim(),e??location.href);return i.protocol==="https:"||i.protocol==="http:"?i.href:void 0}catch{return}}}const _6={halo22:"22° halo — a ring round the Sun, from light bent through hexagonal ice crystals in high cirrus; its inner edge is red, at 21.7°",halo46:"46° halo — a rarer, fainter ring: light entering a crystal by a side face and leaving by an end face",oddRadius:"{angle}° halo — an odd-radius ring, rare and faint, made by ice crystals with pyramid ends",parhelion:"Parhelion (sundog) — a bright coloured spot beside the Sun at its own height, from flat plates falling level; red toward the Sun",parhelion120:"120° parhelion — a faint white spot 120° from the Sun, from light reflected inside flat plates",upperTangentArc:"Upper tangent arc — a bright arc resting on top of the 22° halo, from columns lying level",lowerTangentArc:"Lower tangent arc — an arc touching the bottom of the 22° halo, from columns lying level",circumzenithal:"Circumzenithal arc — a vivid band of colour near the zenith, from light entering the top face of flat plates (only with the Sun under 32°)",circumhorizontal:"Circumhorizontal arc — a band of colour low in the sky, from light entering the side face of flat plates (only with the Sun over 58°)",parhelicCircle:"Parhelic circle — a white circle round the whole sky at the Sun's own height, from reflections on the vertical faces of flat plates",pillar:"Light pillar — a shaft of light standing above the Sun, from reflections off slightly tilted flat plates",subsun:"Subsun — a mirror image of the Sun below the horizon, from reflections off the flat faces of plates"},A6=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,T6=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,R6=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,I6=20,D6=1;class C6{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",t);return}}ho.unlock(this.context)}setAmbient(t,e,i){if(this.requested={type:t,intensity:e,windSpeed:i},!this.context)return;this.paused&&(t="none",e=0,i=0);const n=t==="rain"||t==="hail"?t:"none";if(this.ambientVolume=n==="hail"?Math.min(1,e*1.3+.2):n==="rain"?e:0,n!==this.ambientKey){this.ambientKey=n;const r=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,n!=="none"&&this.startLoop(A6,this.ambientVolume).then(o=>this.applyIfCurrent(o,r,()=>this.ambientToken,c=>{this.ambientSource=c?.source,this.ambientGain=c?.gain,c&&(c.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(i/I6,1);const s=i>D6;if(s!==this.windActive){this.windActive=s;const r=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,s&&this.startLoop(T6,this.windVolume).then(o=>this.applyIfCurrent(o,r,()=>this.windToken,c=>{this.windSource=c?.source,this.windGain=c?.gain,c&&(c.gain.gain.value=this.windVolume)}))}else this.windGain&&(this.windGain.gain.value=this.windVolume)}setPaused(t){if(t===this.paused)return;this.paused=t;const{type:e,intensity:i,windSpeed:n}=this.requested;this.setAmbient(e,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(R6,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear()}applyIfCurrent(t,e,i,n){if(e!==i()){t?.source.stop();return}n(t)}async startLoop(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n,s.loop=!0;const r=i.createGain();return r.gain.value=e,s.connect(r).connect(this.output(i)),s.start(),{source:s,gain:r}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n;const r=i.createGain();r.gain.value=e,s.connect(r).connect(this.output(i)),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(t){const e=this.context;if(!e)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}stopSource(t,e){try{t?.stop()}catch{}t?.disconnect(),e?.disconnect()}}class Ir{constructor(t){this.elements=t;const{eccentricity:e,perihelionAu:i}=t,[n,s]=this.perifocalAxes(),r=Math.sqrt(Ir.SUN_GM_AU3_PER_DAY2*(1+e)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,r),this.inverseSemiMajorAxis=(1-e)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(t){const e=t-this.elements.perihelionJd,i=this.universalAnomaly(e),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,r=1-i*i/s*Ir.stumpffC(n),o=e-i*i*i/Math.sqrt(Ir.SUN_GM_AU3_PER_DAY2)*Ir.stumpffS(n);return{x:r*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:r*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:r*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(t){const e=this.positionAt(t);return Math.hypot(e.x,e.y,e.z)}universalAnomaly(t){if(t===0)return 0;const e=Math.sign(t),i=Math.sqrt(Ir.SUN_GM_AU3_PER_DAY2)*Math.abs(t),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*Ir.stumpffS(c)+l*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let r=0;for(let o=0;o<Ir.MAX_ITERATIONS&&s-r>1e-13*Math.max(1,s);o++){const c=(r+s)/2;n(c)<i?r=c:s=c}return e*(r+s)/2}perifocalAxes(){const t=this.elements.ascendingNodeDeg*Math.PI/180,e=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(t),s=Math.sin(t),r=Math.cos(e),o=Math.sin(e),c=Math.cos(i),l=Math.sin(i);return[{x:n*r-s*o*c,y:s*r+n*o*c,z:o*l},{x:-n*o-s*r*c,y:-s*o+n*r*c,z:r*l}]}scale(t,e){return{x:t.x*e,y:t.y*e,z:t.z*e}}static stumpffC(t){if(Math.abs(t)<1e-6)return 1/2-t/24+t*t/720;if(t>0)return(1-Math.cos(Math.sqrt(t)))/t;const e=Math.sqrt(-t);return(Math.cosh(e)-1)/-t}static stumpffS(t){if(Math.abs(t)<1e-6)return 1/6-t/120+t*t/5040;if(t>0){const i=Math.sqrt(t);return(i-Math.sin(i))/(i*i*i)}const e=Math.sqrt(-t);return(Math.sinh(e)-e)/(e*e*e)}}const Qx=[{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 O6{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(t){const e=this.julianDayOf(t);return Qx.filter(i=>Math.abs(e-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(t,e){return this.aroundDate(t).map(i=>this.appearanceOf(i,t,e)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(t,e,i){const n=Ye(e),s=this.earthPositionAt(n),r=this.apparentPositionOf(t,2451545+n.tt,s),o=this.subtract(r,s),c=this.length(r),l=this.length(o),h=this.tailEndAt(t,r,s,c,n,e,i),u=this.horizontalOf(o,n,e,i);return{apparition:t,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(t,c,l)}}static magnitudeAt(t,e,i){const n=t.absoluteMagnitude+5*Math.log10(i)+2.5*t.activityExponent*Math.log10(e);return Math.max(n,t.peakMagnitude)}static tailEndAt(t,e,i,n,s,r,o){if(t.tailLengthAu===void 0)return{};const c=1+t.tailLengthAu/n,l=this.subtract({x:e.x*c,y:e.y*c,z:e.z*c},i),h=this.subtract(e,i);return{tailEnd:this.horizontalOf(l,s,r,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(t,e,i){const n=this.orbitOf(t);let s=n.positionAt(e);for(let r=0;r<2;r++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(e-o)}return s}static horizontalOf(t,e,i,n){const s=kr(XI(),new Re(t.x,t.y,t.z,e)),r=kr(kx(e),s),o=ym(e,new zr(n.lat,n.lng,n.elevationM),!0),c=new Re(r.x-o.x,r.y-o.y,r.z-o.z,e),l=Sf(c);return Dg(l.ra,l.dec,i,n)}static earthPositionAt(t){return kr(WI(),ba(ut.Earth,t))}static julianDayOf(t){return 2451545+Ye(t).tt}static orbitOf(t){const e=this.orbits.get(t.id);if(e)return e;const i=new Ir(t.orbit);return this.orbits.set(t.id,i),i}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}static length(t){return Math.hypot(t.x,t.y,t.z)}static angleBetween(t,e){const i=(t.x*e.x+t.y*e.y+t.z*e.z)/(this.length(t)*this.length(e)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const j0=[{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 T2{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(t){const e=this.julianDayOf(t);return j0.filter(i=>this.magnitudeAt(i,e)!==void 0)}static appearancesAt(t,e){const i=this.julianDayOf(t),n=[];for(const s of j0){const r=this.magnitudeAt(s,i);r!==void 0&&n.push({outburst:s,position:Rs.ofJ2000(s.raHours,s.decDeg,t,e),magnitude:r})}return n.sort((s,r)=>s.magnitude-r.magnitude)}static brightestAt(t,e){return this.appearancesAt(t,e)[0]}static byId(t){return j0.find(e=>e.id===t)}static magnitudeAt(t,e){const i=t.lightCurve,n=e-t.startJd;if(i.length===0||n<i[0][0]||n>i[i.length-1][0])return;let s=1;for(;s<i.length-1&&i[s][0]<n;)s++;const[r,o]=i[s-1]??i[0],[c,l]=i[s]??i[0];if(c===r)return o;const h=Math.min(1,Math.max(0,(n-r)/(c-r)));return o+h*(l-o)}static julianDayOf(t){return t.getTime()/864e5+this.UNIX_EPOCH_JD}}const P6=[{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}],Qd=6.5;class Q0{static activeAt(t){return P6.flatMap(e=>{const i=this.nearness(e,t);return i<=0?[]:[{shower:e,zhr:e.peakZhr*i,nearness:i}]})}static nearness(t,e){const i=this.dayOfYear(e),n=this.dayOfYear(this.asDate(t.start)),s=this.dayOfYear(this.asDate(t.peak)),r=this.dayOfYear(this.asDate(t.end)),o=this.wrappedDelta(i,s),c=this.wrappedDelta(s,n),l=this.wrappedDelta(r,s);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(t,e,i,n=Qd){if(e<=0)return 0;const s=Qd-n;return t*Math.sin(e*Math.PI/180)/Math.pow(i,s)}static radiantPosition(t,e,i){return Rs.ofJ2000(t.radiantRaHours,t.radiantDecDeg,e,i)}static dayOfYear(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Math.floor((Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())-e)/864e5)+1}static asDate(t){return new Date(Date.UTC(2001,t.month-1,t.day))}static wrappedDelta(t,e){const i=t-e;return i>182?i-365:i<-182?i+365:i}}class Ei{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(t,e){const i=Ye(t),n=new yf(0,wI(t).elon-90,1),s=kr(ZI(i),Ig(n,i)),r=Sf(s);return Dg(r.ra,r.dec,t,e)}static observedRatePerHour(t,e=Qd){const i=Ei.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(t*Math.PI/180)),n=Qd-e;return(Ei.QUIET_RATE_PER_HOUR+i)/Math.pow(Ei.POPULATION_INDEX,n)}static schedule(t){const e=new Ef(t.seed^1542469173);return po.schedule(t).map(i=>{const n=Ei.toCartesian({altitudeDeg:Math.asin(e.next())*180/Math.PI,azimuthDeg:e.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,r=Ei.turnAround(n,e.between(0,360)),o={x:n.x*Math.cos(s)+r.x*Math.sin(s),y:n.y*Math.cos(s)+r.y*Math.sin(s),z:n.z*Math.cos(s)+r.z*Math.sin(s)};return{...i,radiant:Ei.toHorizontal(o),bearingDeg:Ei.bearingFrom(o,n)}})}static turnAround(t,e){const[i,n]=Ei.basisAround(t),s=e*Math.PI/180;return{x:i.x*Math.cos(s)+n.x*Math.sin(s),y:i.y*Math.cos(s)+n.y*Math.sin(s),z:i.z*Math.cos(s)+n.z*Math.sin(s)}}static bearingFrom(t,e){const[i,n]=Ei.basisAround(t),s=t.x*e.x+t.y*e.y+t.z*e.z,r=Ei.normalise({x:e.x-t.x*s,y:e.y-t.y*s,z:e.z-t.z*s});return(Math.atan2(r.x*n.x+r.y*n.y+r.z*n.z,r.x*i.x+r.y*i.y+r.z*i.z)*180/Math.PI%360+360)%360}static basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=Ei.normalise(Ei.cross(t,e));return[i,Ei.normalise(Ei.cross(t,i))]}static toHorizontal(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,t.y/e)))*180/Math.PI,azimuthDeg:(Math.atan2(t.x,-t.z)*180/Math.PI%360+360)%360}}static appearanceOf(t){const e=Ei.toCartesian(t.radiant??{altitudeDeg:90,azimuthDeg:0}),i=Ei.turnAround(e,t.bearingDeg),n=t.fromRadiantDeg*Math.PI/180;return Ei.toHorizontal({x:e.x*Math.cos(n)+i.x*Math.sin(n),y:e.y*Math.cos(n)+i.y*Math.sin(n),z:e.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180,n=Math.cos(e);return{x:n*Math.sin(i),y:Math.sin(e),z:-n*Math.cos(i)}}static cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}static normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}static TYPICAL_VELOCITY_KM_S=40}const R2="https://ufoathome.org/tle/index.json";class pn{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??pn.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/tle/index.json",location.href).href),t.includes(R2)||t.push(R2),t}static FIRST_SNAPSHOT="2021-02-22";async covers(t){const e=Date.parse(`${pn.FIRST_SNAPSHOT}T00:00:00Z`)-pn.MAX_ELEMENT_AGE_DAYS*pn.DAY_MS;if(t.getTime()<e)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>t.getTime()>=Date.parse(n.from)-pn.MAX_ELEMENT_AGE_DAYS*pn.DAY_MS&&t.getTime()<=Date.parse(n.to)+pn.MAX_ELEMENT_AGE_DAYS*pn.DAY_MS):!1}async at(t){const e=await this.loadIndex();if(!e)return;const{index:i,base:n}=e,s=[],r=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,t,i,n);s.push(...c),r.push(this.coverageOf(o,t,i,c.length>0))}return{objects:s,coverage:r,credit:i.credit,creditUrl:i.source}}async kindAt(t,e,i,n){const s=e.getTime(),r=i.binDays*pn.DAY_MS,o=Math.floor(s/r),c=s-o*r<r/2?o-1:o+1,l=new Set(i.kinds[t].bins),h=[o,c].map(v=>new Date(v*r).toISOString().slice(0,10)).filter(v=>l.has(v));if(h.length===0)return[];const[u,...d]=await Promise.all([this.json(new URL(`objects-${t}.json`,n).href),...h.map(v=>this.binary(new URL(`${t}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of pn.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)/pn.DAY_MS;if(m>pn.MAX_ELEMENT_AGE_DAYS)continue;const g=u[v.norad]??{name:String(v.norad)};g.launch&&Date.parse(`${g.launch}T00:00:00Z`)>s||p.push({norad:v.norad,name:g.name,kind:t,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(t,e,i,n){const{from:s,to:r}=i.kinds[t],o=e.getTime(),c=pn.MAX_ELEMENT_AGE_DAYS*pn.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(r)+c?"after":"gap";return{kind:t,status:l,from:s,to:r}}static decode(t,e){const i=new DataView(t),n=[];for(let s=0;s+e<=t.byteLength;s+=e)n.push({norad:i.getUint32(s,!0),epochMs:i.getFloat64(s+4,!0),bstar:i.getFloat32(s+12,!0),inclinationDeg:i.getFloat32(s+16,!0),raanDeg:i.getFloat32(s+20,!0),eccentricity:i.getFloat32(s+24,!0),argOfPerigeeDeg:i.getFloat32(s+28,!0),meanAnomalyDeg:i.getFloat32(s+32,!0),meanMotion:i.getFloat64(s+36,!0)});return n}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;return{index:await e.json(),base:t}}catch{}})(),this.index}json(t){return this.cached(t,async e=>e.json())}binary(t){return this.cached(t,async e=>e.arrayBuffer())}cached(t,e){let i=this.files.get(t);return i||(i=this.fetchImpl(t).then(n=>{if(!n.ok)throw new Error(`${t}: ${n.status}`);return e(n)}),i.catch(()=>this.files.delete(t)),this.files.set(t,i)),i}}class L6{lowerM;upperM;add(t,e){if(!(t<=0)){if(e.behindM!==void 0){const i=qe.sizeMAt(e.behindM,t);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(e.inFrontM!==void 0){const i=qe.sizeMAt(e.inFrontM,t);this.upperM=this.upperM===void 0?i:Math.min(this.upperM,i)}}}get sizeRange(){return{minM:this.lowerM,maxM:this.upperM}}get empty(){return this.lowerM===void 0&&this.upperM===void 0}get contradictory(){return this.lowerM!==void 0&&this.upperM!==void 0&&this.lowerM>this.upperM}distanceRangeAt(t){return t<=0?{}:{minM:this.lowerM===void 0?void 0:qe.distanceMAt(this.lowerM,t),maxM:this.upperM===void 0?void 0:qe.distanceMAt(this.upperM,t)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class go{static DEG_PER_SECOND=360/86164.0905;static degOver(t){return Math.max(0,t)*go.DEG_PER_SECOND}static instants(t,e){if(!(e>0))return 1;const i=go.degOver(t)/e;return i<1?1:Math.min(go.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class cn{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 go.DEG_PER_SECOND*3600}static graspOf(t,e={}){if(t.visualAid)return cn.visualAidGrasp(t,e.focalLengthMm);const i=e.exposureSeconds??t.exposureSeconds,n=e.fNumber??t.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return cn.EYE;const s=e.focalLengthMm??t.frame?.focalLengthMm??cn.UNKNOWN_CAMERA_FOCAL_MM,r=s/n,o=cn.resolutionArcsec(t,s,r);return{apertureMm:r,exposureSeconds:Math.min(i,cn.trailLimitedSeconds(o)),resolutionArcsec:o}}static visualAidGrasp(t,e){const i=t.visualAid,n=cn.EYE,s=e??t.frame?.focalLengthMm,r=i.magnification??(s!==void 0&&i.eyepieceFocalMm?s/i.eyepieceFocalMm:1),o=Math.min(i.apertureMm,n.apertureMm*r);return{apertureMm:Math.max(o,n.apertureMm),exposureSeconds:n.exposureSeconds,resolutionArcsec:n.resolutionArcsec/Math.max(1,Math.min(r,i.apertureMm/n.apertureMm))}}static resolutionArcsec(t,e,i){const s=(t.detailUm??cn.UNKNOWN_CAMERA_DETAIL_UM)/1e3/e*cn.ARCSEC_PER_RADIAN,r=1.22*cn.WAVELENGTH_M/(i/1e3)*cn.ARCSEC_PER_RADIAN;return Math.max(s,r)}static trailLimitedSeconds(t){return t/cn.skyDriftArcsecPerSecond}static gainOverEye(t,e={}){const i=cn.graspOf(t,e),n=cn.EYE,s=(i.apertureMm/n.apertureMm)**2,r=i.exposureSeconds/n.exposureSeconds,o=(n.resolutionArcsec/i.resolutionArcsec)**2;return 1.25*Math.log10(s*r*o)}static gainFor(t,e){const i=e.fieldOfViewDeg===void 0?void 0:Li.focalLengthMmFor(t,e.fieldOfViewDeg);return cn.gainOverEye(t,{fNumber:e.fNumber,focalLengthMm:i,exposureSeconds:e.exposureSeconds})}}const I2=111320,Rl=Math.PI/180,N6=1.02,k6=1;class eh{static of(t,e){const i=eh.sightings(t,e);if(i.length<2)return;const n=eh.baseline(i);if(!n)return;const{near:s,far:r,closedM:o}=n,c=Math.tan(r.widthDeg/2*Rl)===0?0:Math.tan(s.widthDeg/2*Rl)/Math.tan(r.widthDeg/2*Rl);if(c<N6)return;const l=o/(c-1),h=qe.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:qe.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:r.t,toT:s.t,closedM:o}}static sightings(t,e){return t.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===e)?.shape,s=n?.angular?.widthDeg,r=ei(t,i.t);return s===void 0||s<=0||r?.lat===void 0||r.lng===void 0?[]:[{t:i.t,widthDeg:s,lat:r.lat,lng:r.lng,sightAzimuthDeg:n?.aim?.azimuthDeg??r.headingDeg}]}).sort((i,n)=>i.t-n.t)}static baseline(t){let e;for(const i of t)for(const n of t){if(i.t>=n.t)continue;const s=eh.closedAlongSight(i,n),[r,o,c]=s>=0?[n,i,s]:[i,n,-s];c<k6||r.widthDeg<=o.widthDeg||(!e||c>e.closedM)&&(e={near:r,far:o,closedM:c})}return e}static closedAlongSight(t,e){const i=(e.lat-t.lat)*I2,n=(e.lng-t.lng)*I2*Math.cos(t.lat*Rl),s=(t.sightAzimuthDeg??0)*Rl;return i*Math.cos(s)+n*Math.sin(s)}}class En{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(t){if(t.statedM!==void 0&&t.statedM>0)return{distanceM:En.atLeastNearest(t.statedM),basis:"stated"};if(t.hypothesisM!==void 0&&t.hypothesisM>0)return{distanceM:En.atLeastNearest(t.hypothesisM),basis:"hypothesis"};if(t.derivedM!==void 0&&t.derivedM>0)return{distanceM:En.atLeastNearest(t.derivedM),basis:"derived"};const e=En.largest(t.range?.minM,t.crossing?.behindM),i=En.smallest(t.range?.maxM,t.crossing?.inFrontM),n=e===void 0?void 0:e*En.MARGIN,s=i===void 0?void 0:i/En.MARGIN;return n!==void 0&&s!==void 0?{distanceM:En.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:En.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<En.CONVENTIONAL_M?{distanceM:En.atLeastNearest(s),basis:"bounded"}:{distanceM:En.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(t){return Math.max(En.NEAREST_M,t)}static largest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.max(...e)}static smallest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.min(...e)}}const tp=Math.PI/180;class Kt{constructor(t,e,i){this.body=t,this.ground=e,this.eyeAt=i;const n=[...t.track].sort((s,r)=>s.t-r.t);this.keys=this.place(n,i);for(const s of n)Kt.collect(this.motionKeys,s.t,s.motions),Kt.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,transparency:0,haloScale:1};keys;motionKeys=new Map;lightKeys=new Map;static collect(t,e,i){for(const[n,s]of Object.entries(i??{})){const r=t.get(n)??[];r.push({t:e,value:s}),t.set(n,r)}}motionsAt(t){return Kt.channelsAt(this.motionKeys,t,0)}lightsAt(t){return this.lightKeys.size>0?Kt.channelsAt(this.lightKeys,t,void 0):void 0}static channelsAt(t,e,i){const n={};for(const[s,r]of t){let o=r.length-1;for(;o>=0&&r[o].t>e;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const c=r[o],l=r[Math.min(o+1,r.length-1)],h=l===c||l.t===c.t?0:Math.min(1,(e-c.t)/(l.t-c.t));n[s]=Kt.lerp(c.value,l.value,h)}return n}static eyeOf(t,e,i){const n=ei(t,0),s=ei(t,e),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?ue(s.lat,s.lng,n.lat,n.lng):void 0,c=o?o.x:0,l=o?-o.z:0;return{eastM:c,northM:l,upM:i.heightAt(c,l)+Kt.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(t,e,i,n){const s=Kt.directionOf(e,i),r=l=>t.upM+s.upM*l-n.heightAt(t.eastM+s.eastM*l,t.northM+s.northM*l);let o=0,c=0;for(;c<Kt.MAX_RANGE_M;){if(c=o+Math.max(.5,o*.01),r(c)<=0){for(let l=0;l<30;l++){const h=(o+c)/2;r(h)<=0?c=h:o=h}return c}o=c}}static directionOf(t,e){const i=t*tp,n=e*tp;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(t){const e=this.keys;if(e.length===0||t<e[0].t)return;let i=e.length-1;for(;i>0&&e[i].t>t;)i--;const n=e[i];if(!n.present)return;const s=e[Math.min(i+1,e.length-1)],r=s===n||s.t===n.t?0:Math.min(1,(t-n.t)/(s.t-n.t)),o=this.body.withObserver&&n.carried&&s.carried?this.eyeAt(t):void 0,c=o?o.eastM+Kt.lerp(n.carried.eastM,s.carried.eastM,r):Kt.lerp(n.eastM,s.eastM,r),l=o?o.northM+Kt.lerp(n.carried.northM,s.carried.northM,r):Kt.lerp(n.northM,s.northM,r),h={widthM:Kt.lerp(n.sizeM.widthM,s.sizeM.widthM,r),lengthM:Kt.lerp(n.sizeM.lengthM,s.sizeM.lengthM,r),heightM:Kt.lerp(n.sizeM.heightM,s.sizeM.heightM,r)},u={headingDeg:Kt.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,r),pitchDeg:Kt.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,r),rollDeg:Kt.lerp(n.attitude.rollDeg,s.attitude.rollDeg,r)};let d;if(o)d=o.upM+Kt.lerp(n.carried.upM,s.carried.upM,r);else if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const f=Kt.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,r);d=this.groundUnderFootprint(c,l,h,u.headingDeg)+f+h.heightM/2}else d=Kt.lerp(this.centreUpOf(n),this.centreUpOf(s),r);return{id:this.body.id,model:this.body.model,explains:this.body.explains??[],outlineNode:this.body.outlineNode,eastM:c,northM:l,upM:d,sizeM:h,attitude:u,appearance:{color:Kt.lerpColor(n.appearance.color,s.appearance.color,r),albedo:Kt.lerp(n.appearance.albedo,s.appearance.albedo,r),luminanceCdM2:Kt.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,r),transparency:Kt.lerp(n.appearance.transparency,s.appearance.transparency,r),haloScale:Kt.lerp(n.appearance.haloScale,s.appearance.haloScale,r)},flame:Kt.flameBetween(n.flame,s.flame,r),motions:this.motionsAt(t),lights:this.lightsAt(t),throwsFlame:this.body.track.some(f=>f.flame!==void 0&&f.flame.luminanceCdM2>0)}}static flameBetween(t,e,i){if(!t||t.luminanceCdM2<=0)return i>=1&&e&&e.luminanceCdM2>0?e:void 0;const n=t,s=e??t,r={...i<1?n:s,lengthM:Kt.lerp(n.lengthM,s.lengthM,i),widthM:Kt.lerp(n.widthM,s.widthM,i),luminanceCdM2:Kt.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return r.luminanceCdM2>0?r:void 0}centreUpOf(t){return"upM"in t.vertical?t.vertical.upM:this.groundUnderFootprint(t.eastM,t.northM,t.sizeM,t.attitude.headingDeg)+t.vertical.aboveGroundM+t.sizeM.heightM/2}groundUnderFootprint(t,e,i,n){const s=n*tp,r={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(t,e);for(const[l,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const u=l*i.widthM/2,d=h*i.lengthM/2;c=Math.max(c,this.ground.heightAt(t+r.eastM*u+o.eastM*d,e+r.northM*u+o.northM*d))}return c}place(t,e){const i=[];let n;for(const s of t){const r=s.sizeM??n?.sizeM??Kt.DEFAULT_SIZE,o={headingDeg:s.attitude?.headingDeg??n?.attitude.headingDeg??0,pitchDeg:s.attitude?.pitchDeg??n?.attitude.pitchDeg??0,rollDeg:s.attitude?.rollDeg??n?.attitude.rollDeg??0},c={color:s.appearance?.color??n?.appearance.color??Kt.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??Kt.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??Kt.DEFAULT_APPEARANCE.luminanceCdM2,transparency:s.appearance?.transparency??n?.appearance.transparency??Kt.DEFAULT_APPEARANCE.transparency,haloScale:s.appearance?.haloScale??n?.appearance.haloScale??Kt.DEFAULT_APPEARANCE.haloScale},l=this.positionOf(s,r,e)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s,r)??n.vertical});if(!l)continue;const h=s.flame??n?.flame,u=s.present??n?.present??!0;if(n={t:s.t,...l,sizeM:r,attitude:o,appearance:c,flame:h,present:u},this.body.withObserver&&s.azimuthDeg!==void 0&&s.distanceM!==void 0){const d=Kt.directionOf(s.azimuthDeg,s.altitudeDeg??0);n.carried={eastM:d.eastM*s.distanceM,northM:d.northM*s.distanceM,upM:d.upM*s.distanceM}}i.push(n)}return i}verticalOf(t,e){if(t.onGround)return{aboveGroundM:0};if(t.altitudeAboveGroundM!==void 0)return{aboveGroundM:t.altitudeAboveGroundM};if(t.altitudeM!==void 0)return{upM:t.altitudeM+e.heightM/2}}positionOf(t,e,i){if(t.eastM!==void 0&&t.northM!==void 0)return{eastM:t.eastM,northM:t.northM,vertical:this.verticalOf(t,e)??{aboveGroundM:0}};if(t.azimuthDeg===void 0||t.altitudeDeg===void 0)return;const n=i(t.t);if(!n)return;const s=t.distanceM??(t.onGround?Kt.lineOfSightMeetsGround(n,t.azimuthDeg,t.altitudeDeg,this.ground):void 0);if(s===void 0)return;const r=Kt.directionOf(t.azimuthDeg,t.altitudeDeg),o=n.eastM+r.eastM*s,c=n.northM+r.northM*s;return{eastM:o,northM:c,vertical:this.verticalOf(t,e)??{upM:n.upM+r.upM*s}}}static lerp(t,e,i){return t+(e-t)*i}static lerpColor(t,e,i){const n=Kt.rgbOf(t),s=Kt.rgbOf(e);return!n||!s?i<1?t:e:"#"+n.map((r,o)=>Math.round(Kt.lerp(r,s[o],i)).toString(16).padStart(2,"0")).join("")}static rgbOf(t){const e=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(t);if(!e)return;const i=e[1].length===3?e[1].replace(/./g,"$&$&"):e[1];return[0,2,4].map(n=>parseInt(i.slice(n,n+2),16))}static lerpAngle(t,e,i){const n=((e-t)%360+540)%360-180;return((t+n*i)%360+360)%360}}class Ee{static A=6378137;static E2=.00669437999014;static DEG=Math.PI/180;static STANDARD_DISTANCE_KM=100;static DEFAULT_COLOR="#ffb347";static DEFAULT_TRAIN_S=1.5;static FADE_MS=600;static TRAIN_POINTS=8;static leadAt(t,e){const i=t.track;if(i.length<2||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-2&&i[n+1].t<e;)n++;const s=i[n],r=i[n+1],o=r.t-s.t,c=o>0?(e-s.t)/o:0,[l,h]=Ee.alongGreatCircle(s,r,c);return{lat:l,lng:h,heightM:(s.altitudeKm+(r.altitudeKm-s.altitudeKm)*c)*1e3}}static viewsAt(t,e,i){const n=[];for(const s of t){const r=s.track[0]?.t??0,o=s.track[s.track.length-1]?.t??0;s.fragments.forEach((c,l)=>{const h=c.fromT??r,u=c.untilT??o;if(e<h||e>u)return;const d=(c.lagS??0)*1e3,f=Ee.leadAt(s,e-d);if(!f)return;const p=Ee.seenFrom(i,f);if(p.altitudeDeg<0)return;const v=Math.min(Ee.FADE_MS,(u-h)/4),m=v>0?Math.min(1,(e-h)/v,(u-e)/v):1,g=-2.5*Math.log10(Math.max(m,.001)),y=c.absoluteMagnitude+5*Math.log10(p.distanceKm/Ee.STANDARD_DISTANCE_KM)+g,x=[p],M=(c.trainS??Ee.DEFAULT_TRAIN_S)*1e3;for(let w=1;w<=Ee.TRAIN_POINTS;w++){const S=Math.min(M*w/Ee.TRAIN_POINTS,e-h),_=Ee.leadAt(s,e-d-S);if(!_||(x.push(Ee.seenFrom(i,_)),S>=e-h))break}n.push({reentryId:s.id,fragmentId:c.id??String(l),head:p,magnitude:y,color:c.color??Ee.DEFAULT_COLOR,train:x})})}return n}static seenFrom(t,e){const i=Ee.ecef(t),n=Ee.ecef(e),s=n[0]-i[0],r=n[1]-i[1],o=n[2]-i[2],c=t.lat*Ee.DEG,l=t.lng*Ee.DEG,h=-Math.sin(l)*s+Math.cos(l)*r,u=-Math.sin(c)*Math.cos(l)*s-Math.sin(c)*Math.sin(l)*r+Math.cos(c)*o,d=Math.cos(c)*Math.cos(l)*s+Math.cos(c)*Math.sin(l)*r+Math.sin(c)*o,f=Math.hypot(h,u,d);return{altitudeDeg:Math.asin(d/f)/Ee.DEG,azimuthDeg:(Math.atan2(h,u)/Ee.DEG+360)%360,distanceKm:f/1e3}}static ecef(t){const e=t.lat*Ee.DEG,i=t.lng*Ee.DEG,n=Math.sin(e),s=Ee.A/Math.sqrt(1-Ee.E2*n*n);return[(s+t.heightM)*Math.cos(e)*Math.cos(i),(s+t.heightM)*Math.cos(e)*Math.sin(i),(s*(1-Ee.E2)+t.heightM)*n]}static alongGreatCircle(t,e,i){const n=h=>{const u=h.lat*Ee.DEG,d=h.lng*Ee.DEG;return[Math.cos(u)*Math.cos(d),Math.cos(u)*Math.sin(d),Math.sin(u)]},s=n(t),r=n(e),o=Math.max(-1,Math.min(1,s[0]*r[0]+s[1]*r[1]+s[2]*r[2])),c=Math.acos(o);let l;if(c<1e-12)l=s;else{const h=Math.sin((1-i)*c)/Math.sin(c),u=Math.sin(i*c)/Math.sin(c);l=[s[0]*h+r[0]*u,s[1]*h+r[1]*u,s[2]*h+r[2]*u]}return[Math.atan2(l[2],Math.hypot(l[0],l[1]))/Ee.DEG,Math.atan2(l[1],l[0])/Ee.DEG]}}class we{static EARTH_RADIUS_KM=6371;static SHADOW_RADIUS_KM=we.EARTH_RADIUS_KM+15;static PENUMBRA_KM=10;static SUN_ILLUMINANCE_LUX=127e3;static RAYLEIGH_PER_M=[58e-7,135e-7,331e-7];static SCALE_HEIGHT_M=8e3;static OZONE_GRAZING_DEPTH=[2.4,1.8,.24];static ANISOTROPY=.7;static ALBEDO=.99;static DEFAULTS={exhaustKgPerS:273,condensedShare:.1,particleRadiusUm:.5,expansionKmPerS:.15,initialRadiusKm:.5,lifetimeS:420,collarShare:.85,collarExpansionKmPerS:2.5,collarLifetimeS:20};static PROPELLANTS={"rp1-lox":{condensedShare:.1,particleRadiusUm:.5},"methane-lox":{condensedShare:.14,particleRadiusUm:.5},"hydrogen-lox":{condensedShare:.2,particleRadiusUm:.5},hypergolic:{condensedShare:.1,particleRadiusUm:.4},solid:{condensedShare:.33,particleRadiusUm:.8}};static G0=9.80665;static COLLAR_SPREAD_OF_EXHAUST_VELOCITY=.735;static plumeOf(t){const e={},i=t.vehicle?.engine;if(i){const n=i.specificImpulseS===void 0?void 0:i.specificImpulseS*we.G0;i.thrustKN!==void 0&&n&&(e.exhaustKgPerS=i.thrustKN*1e3/n),n&&(e.collarExpansionKmPerS=n/1e3*we.COLLAR_SPREAD_OF_EXHAUST_VELOCITY),i.propellant&&Object.assign(e,we.PROPELLANTS[i.propellant])}return{...we.DEFAULTS,...e,...t.plume}}static PUFF_EVERY_S=.5;static MAX_PUFFS=320;static DEG=Math.PI/180;static sunDirectionAt(t){const e=new zr(0,0,-6378137),i=jc(ut.Sun,t,e,!0,!0),n=(i.ra-Sx(t))*15*we.DEG,s=i.dec*we.DEG;return[Math.cos(s)*Math.cos(n),Math.cos(s)*Math.sin(n),Math.sin(s)]}static viewsAt(t,e,i,n){const s=[];for(const r of t){const o=we.plumeOf(r),c=r.track[0]?.t??0,l=r.track[r.track.length-1]?.t??0,h=r.burnFromT??c,u=Math.min(r.burnUntilT??l,e);if(u<=h)continue;const d=Math.max(we.PUFF_EVERY_S*1e3,(u-h)/we.MAX_PUFFS),f=o.particleRadiusUm*1e-6,p=6/(4*917*f),v=o.exhaustKgPerS*(d/1e3)*o.condensedShare,m=[{share:1-o.collarShare,expansionKmPerS:o.expansionKmPerS,lifetimeS:o.lifetimeS},{share:o.collarShare,expansionKmPerS:o.collarExpansionKmPerS,lifetimeS:o.collarLifetimeS}];for(let g=u;g>=h;g-=d){const y=(e-g)/1e3;if(y>o.lifetimeS)break;const x=Ee.leadAt({id:r.id,track:r.track,fragments:[]},g);if(!x)continue;const M=Ee.seenFrom(i,x);if(M.altitudeDeg<0)continue;const w=we.sunlightAt(x,n);if(w.lit<=0)continue;const S=Ee.leadAt({id:r.id,track:r.track,fragments:[]},Math.max(c,g-d)),_=S?we.distanceKm(x,S):0,b=we.scatteringPhase(i,x,n);for(const A of m){if(A.share<=0||y>A.lifetimeS)continue;const D=o.initialRadiusKm+A.expansionKmPerS*y+_/2,I=3*v*A.share*p/(2*Math.PI*(D*1e3)**2),O=Math.max(0,1-(y/A.lifetimeS)**2),N=we.SUN_ILLUMINANCE_LUX*we.ALBEDO*b*I*O*w.lit;N<=0||s.push({launchId:r.id,centre:M,radiusDeg:Math.atan2(D,M.distanceKm)/we.DEG,luminanceCdM2:N,sunTransmittance:w.transmittance,lit:w.lit,ageS:y})}}}return s}static sunlightAt(t,e){const i=we.earthCentred(t),n=i[0]*e[0]+i[1]*e[1]+i[2]*e[2];if(n>=0)return{lit:1,transmittance:[1,1,1]};const s=Math.hypot(i[0]-n*e[0],i[1]-n*e[1],i[2]-n*e[2]),r=we.PENUMBRA_KM,o=Math.min(1,Math.max(0,(s-(we.SHADOW_RADIUS_KM-r/2))/r));if(o<=0)return{lit:0,transmittance:[0,0,0]};const c=Math.max(0,(s-we.EARTH_RADIUS_KM)*1e3),l=Math.exp(-c/we.SCALE_HEIGHT_M),h=Math.sqrt(2*Math.PI*we.EARTH_RADIUS_KM*1e3*we.SCALE_HEIGHT_M),u=Math.exp(-(((c/1e3-25)/15)**2)),d=[0,1,2].map(f=>Math.exp(-we.RAYLEIGH_PER_M[f]*l*h-we.OZONE_GRAZING_DEPTH[f]*u));return{lit:o,transmittance:d}}static scatteringPhase(t,e,i){const n=we.earthCentred(t),s=we.earthCentred(e),r=[n[0]-s[0],n[1]-s[1],n[2]-s[2]],o=Math.hypot(r[0],r[1],r[2])||1,c=-(r[0]*i[0]+r[1]*i[1]+r[2]*i[2])/o,l=we.ANISOTROPY;return(1-l*l)/(4*Math.PI*(1+l*l-2*l*c)**1.5)}static distanceKm(t,e){const i=we.earthCentred(t),n=we.earthCentred(e);return Math.hypot(i[0]-n[0],i[1]-n[1],i[2]-n[2])}static earthCentred(t){const e=t.lat*we.DEG,i=t.lng*we.DEG,n=we.EARTH_RADIUS_KM+t.heightM/1e3;return[n*Math.cos(e)*Math.cos(i),n*Math.cos(e)*Math.sin(i),n*Math.sin(e)]}}class Ng{static FIRST_DAY="2022-01-01";static mayCover(t){return new Date(t).toISOString().slice(0,10)>=Ng.FIRST_DAY}}class U6{constructor(t,e,i){this.citation=t,this.covers=e,this.load=i}loading;mayCover(t){return this.covers(t)}async between(t,e,i,n){try{return await(await this.provider()).between(t,e,i,n)}catch{return{status:"failed"}}}async describe(t,e){try{return await(await this.provider()).describe?.(t,e)}catch{return}}provider(){if(!this.loading){const t=this.load();this.loading=t,t.catch(()=>{this.loading===t&&(this.loading=void 0)})}return this.loading}}const F6="Aircraft positions: adsb.lol feeders and contributors, Open Database License 1.0 (https://www.adsb.lol/docs/open-data/historical/)",z6=[{id:"adsb-lol",name:"adsb.lol",credit:"adsb.lol feeders and contributors, ODbL 1.0",creditUrl:"https://www.adsb.lol/docs/open-data/historical/",create:()=>new U6(F6,a=>Ng.mayCover(a),async()=>new(await Xe(async()=>{const{AdsbLolArchiveProvider:a}=await import("./AdsbLolArchiveProvider-DvCD0VGc.js");return{AdsbLolArchiveProvider:a}},[],import.meta.url)).AdsbLolArchiveProvider)}];class _n{static MAX_GAP_S=60;static FT_TO_M=.3048;static EARTH_RADIUS_KM=6371;static seenFrom(t,e,i){const n=_n.positionAt(t,i);if(!n)return;const s=Ee.seenFrom(e,n.geo);if(!(s.altitudeDeg<0))return{track:t,sky:s,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg,angularRateDegPerS:_n.angularRate(t,e,i)}}static viewsAt(t,e,i){return t.flatMap(n=>_n.seenFrom(n,e,i)??[])}static groundDistanceKm(t,e){const i=Math.PI/180,n=Math.sin((e.lat-t.lat)*i/2)**2+Math.cos(t.lat*i)*Math.cos(e.lat*i)*Math.sin((e.lng-t.lng)*i/2)**2;return 2*_n.EARTH_RADIUS_KM*Math.asin(Math.min(1,Math.sqrt(n)))}static wrapLongitude(t){return((t+180)%360+360)%360-180}static positionAt(t,e){const i=t.points;if(i.length===0||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-1&&i[n+1].t<=e;)n++;const s=i[n],r=i[n+1]??s,o=r.t-s.t;if(o>_n.MAX_GAP_S*1e3)return;const c=o>0?(e-s.t)/o:0,l=s.altitudeFt+(r.altitudeFt-s.altitudeFt)*c,h=(r.lng-s.lng+540)%360-180;return{geo:{lat:s.lat+(r.lat-s.lat)*c,lng:_n.wrapLongitude(s.lng+h*c),heightM:l*_n.FT_TO_M},altitudeFt:l,groundSpeedKt:s.groundSpeedKt,trackDeg:s.trackDeg}}static angularRate(t,e,i){const n=_n.positionAt(t,i-500),s=_n.positionAt(t,i+500);if(!n||!s)return;const r=_n.unit(Ee.seenFrom(e,n.geo)),o=_n.unit(Ee.seenFrom(e,s.geo)),c=Math.min(1,Math.max(-1,r[0]*o[0]+r[1]*o[1]+r[2]*o[2]));return Math.acos(c)*180/Math.PI}static unit(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180;return[Math.cos(e)*Math.sin(i),Math.cos(e)*Math.cos(i),Math.sin(e)]}}const D2="https://ufoathome.org/fireballs/index.json";class er{static FIRST_MONTH="2018-12";static STRIKING_MAGNITUDE=-1;static COLOR="#eef2ff";static TRAIN_S=.3;fetchImpl;indexUrls;index;months=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??er.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/fireballs/index.json",location.href).href),t.includes(D2)||t.push(D2),t}static mayCover(t){return new Date(t).toISOString().slice(0,7)>=er.FIRST_MONTH}async credit(){return(await this.loadIndex())?.index.credit}async between(t,e){if(!er.mayCover(e))return;const i=await this.loadIndex();if(!i)return;const n=new Set([new Date(t).toISOString().slice(0,7),new Date(e).toISOString().slice(0,7)]);return[...n].some(r=>r>=i.index.from&&r<=i.index.to)?(await Promise.all([...n].filter(r=>i.index.months.includes(r)).map(r=>this.monthOf(r,i.base)))).flat().filter(r=>r.t>=t&&r.t<=e):void 0}static seenFrom(t,e){const i=er.peakFraction(t),n={lat:t.from[0]+(t.to[0]-t.from[0])*i,lng:t.from[1]+(t.to[1]-t.from[1])*i,heightM:t.peakHeightKm*1e3},s=Ee.seenFrom(e,n);if(!(s.altitudeDeg<0))return{record:t,peak:s,magnitude:t.peakMagnitude+5*Math.log10(s.distanceKm/Ee.STANDARD_DISTANCE_KM)}}static asReentry(t,e){const i=t.t-e,n=i+Math.max(t.durationS,.1)*1e3;return{id:`gmn-${t.id}`,track:[{t:i,lat:t.from[0],lng:t.from[1],altitudeKm:t.from[2]},{t:n,lat:t.to[0],lng:t.to[1],altitudeKm:t.to[2]}],fragments:[{absoluteMagnitude:t.peakMagnitude,color:er.COLOR,trainS:er.TRAIN_S}]}}static peakFraction(t){const e=t.from[2]-t.to[2];return Math.abs(e)<1e-6?.5:Math.min(1,Math.max(0,(t.from[2]-t.peakHeightKm)/e))}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}monthOf(t,e){let i=this.months.get(t);return i||(i=this.fetchImpl(new URL(`${t}.json`,e).href).then(n=>n.ok?n.json():[]).catch(()=>[]),this.months.set(t,i)),i}}const oc=Math.PI/180,Il=180/Math.PI;class wi{constructor(t){this.timeline=t}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(t,e,i,n){const s=[];for(const r of e){const o=wi.projectionOf(r,i,n?.(r));if(o)for(const c of r.explains){const l=this.timeline.getInterpolatedShapeAt(t,c);!l||l.transparency>=1||s.push({...wi.compare(c,r.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(t,e,i,n){const s=[],r=i.aim?wi.separationDeg(i.aim,n.aim):void 0;if(r!==void 0){const l=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;r>Math.max(wi.DIRECTION_TOLERANCE_DEG,l)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,c=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!wi.withinSize(o)&&s.push("width"),c!==void 0&&!wi.withinSize(c)&&s.push("height"),{sourceId:t,bodyId:e,stated:i,predicted:n,separationDeg:r,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(t,e,i){const n=i&&i.length>0?i:wi.outlineOf(t),s=i&&i.length>0?wi.centreOf(i):t,r=wi.normalized({eastM:s.eastM-e.eastM,northM:s.northM-e.northM,upM:s.upM-e.upM});if(!r)return;const o=wi.normalized({eastM:r.northM,northM:-r.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=wi.cross(o,r);let l=1/0,h=-1/0,u=1/0,d=-1/0;for(const f of n){const p={eastM:f.eastM-e.eastM,northM:f.northM-e.northM,upM:f.upM-e.upM},v=wi.dot(p,r);if(v<=0)return;const m=Math.atan2(wi.dot(p,o),v),g=Math.atan2(wi.dot(p,c),v);l=Math.min(l,m),h=Math.max(h,m),u=Math.min(u,g),d=Math.max(d,g)}return{aim:{azimuthDeg:(Math.atan2(r.eastM,r.northM)*Il+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,r.upM)))*Il},angular:{widthDeg:(h-l)*Il,heightDeg:(d-u)*Il}}}static centreOf(t){const e=i=>(Math.min(...t.map(n=>n[i]))+Math.max(...t.map(n=>n[i])))/2;return{eastM:e("eastM"),northM:e("northM"),upM:e("upM")}}static separationDeg(t,e){const i=t.altitudeDeg*oc,n=e.altitudeDeg*oc,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((t.azimuthDeg-e.azimuthDeg)*oc);return Math.acos(Math.max(-1,Math.min(1,s)))*Il}static withinSize(t){return t<=wi.SIZE_TOLERANCE&&t>=1/wi.SIZE_TOLERANCE}static outlineOf(t){const e=t.sizeM.widthM/2,i=t.sizeM.lengthM/2,n=t.sizeM.heightM/2,s=[],r=t.model.url===void 0?t.model.id:void 0;if(r!==void 0&&r!=="box"&&qx.includes(r))for(let u=0;u<=wi.RINGS;u++){const d=u/wi.RINGS*Math.PI;for(let f=0;f<wi.SEGMENTS;f++){const p=f/wi.SEGMENTS*2*Math.PI;s.push([e*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-e,e])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=t.attitude.headingDeg*oc,l=t.attitude.pitchDeg*oc,h=t.attitude.rollDeg*oc;return s.map(([u,d,f])=>{const p=u*Math.cos(h)+f*Math.sin(h),v=-u*Math.sin(h)+f*Math.cos(h),m=d*Math.cos(l)-v*Math.sin(l),g=d*Math.sin(l)+v*Math.cos(l);return{eastM:t.eastM+p*Math.cos(c)+m*Math.sin(c),northM:t.northM-p*Math.sin(c)+m*Math.cos(c),upM:t.upM+g}})}static dot(t,e){return t.eastM*e.eastM+t.northM*e.northM+t.upM*e.upM}static cross(t,e){return{eastM:t.northM*e.upM-t.upM*e.northM,northM:t.upM*e.eastM-t.eastM*e.upM,upM:t.eastM*e.northM-t.northM*e.eastM}}static normalized(t){const e=Math.hypot(t.eastM,t.northM,t.upM);return e>1e-9?{eastM:t.eastM/e,northM:t.northM/e,upM:t.upM/e}:void 0}}fy();const B6={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},H6="{name} — mag {mag}, {alt}° above the horizon",G6="{name} — {size}, {distance} away",V6="{name} — satellite, mag {mag}, {height} km up",W6="satellites-change",X6="fireballs-change",Y6="aircraft-change",tb="rr0-confrontation",$6="{name} — mag {mag}, {alt}° below the horizontal",ep="Credits",C2="comet:",O2="nova:",P2={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",wire:"Overhead line",crop:"Crop row",terrace:"Terrace (restanque)",mound:"Stone heap",wall:"Dry-stone wall",streetlight:"Streetlight",trafficlight:"Traffic light",crossing:"Pedestrian crossing",roadsign:"Road sign",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},q6=new URL(""+new URL("lunar-relief.bin-ByThqxUn.gz",import.meta.url).href,import.meta.url).href,K6=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,Z6=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,J6=-18,j6={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Nu={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class ze extends HTMLElement{creditsButton;set ownCredits(t){this.creditsButton.hidden=!t}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",cr,lr,no]}shadow;stageElement;frameElement;sceneCanvas;busyElement;busyNote;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;holding=!1;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 pn;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;static fireballArchive=new er;fireballs;static aircraftProviders=new Map;static SOUND_LOOKBACK_MS=3e5;static NO_CONTRAILS=[];static upperAirProviders=new Map;static NO_PRESENCE=new Map;aircraftSource=z6[0];static trafficRuntimeLoading;static trafficRuntime;static loadTrafficRuntime(){return ze.trafficRuntimeLoading??=Xe(()=>import("./trafficRuntime-B6wWQINc.js"),__vite__mapDeps([2,1]),import.meta.url).then(t=>ze.trafficRuntime=t),ze.trafficRuntimeLoading.catch(()=>{ze.trafficRuntimeLoading=void 0}),ze.trafficRuntimeLoading}traffic;lastSun;get sunAltitudeDeg(){return this.sceneRenderer.sunAltitudeDeg??this.lastSun?.altitudeDeg}decorMemo;seatedMemo;starCatalogDepth=0;weatherAudio=new C6;vehicleAudio=new Vw;aircraftAudio;vehicleHearing=new _d;decorAircraftHearing;decorModelSounds=new Map;thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=t=>{if(this.sceneRenderer.setCompassHovered(!0),this.holding){this.hoverTooltip.hidden=!0;return}const e=this.ufoElement.canvasElement,i=e.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(t.clientX-i.left)/i.width*e.width,s=(t.clientY-i.top)/i.height*e.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const r=(t.clientX-i.left)/i.width*2-1,o=-((t.clientY-i.top)/i.height*2-1),c=this.pickAt(r,o);c?this.showHoverTooltip(t,t.altKey&&c.detail?c.detail():c.name):this.hoverTooltip.hidden=!0};pickAt(t,e){const i=this.naming,n=i.names,s=this.sceneRenderer.pickBodyAt(t,e);if(s)return{kind:"sky",id:s,name:this.bodyName(s)};const r=this.interpretationShown?this.sceneRenderer.pickInterpretationBodyAt(t,e):void 0,o=r?this.interpretationShown?.bodies.find(v=>v.id===r):void 0,c=o?this.said.read(o.title)||(o.model.id==="figure"?i.decorKind("entity",P2.entity):void 0):void 0;if(r!==void 0&&c)return{kind:"body",id:r,name:c};const l=this.pickDecorAt(t,e),h=l?this.ufoElement.sighting.decor.find(v=>v.id===l):void 0;if(h){const v=this.said.read(h.title)||i.decorKind(h.kind,P2[h.kind]);return{kind:"decor",id:h.id,name:v,detail:()=>this.decorTooltip(h,v)}}const u=this.trafficTooltipAt(t,e);if(u)return{kind:"traffic",name:u};const d=this.sceneRenderer.pickSatelliteAt(t,e);if(d)return{kind:"satellite",name:(n?.satelliteTooltip??V6).replace("{name}",d.name).replace("{mag}",d.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(d.heightKm).toLocaleString())};const f=this.sceneRenderer.pickOpticsAt(t,e);if(f){const v=(n?.opticsTooltips??_6)[f.id].replace("{angle}",String(Math.round(f.angleDeg??0)));return{kind:"optics",id:f.id,name:v.split(" — ")[0],detail:()=>v}}const p=this.sceneRenderer.pickStarAt(t,e);if(p){const v=p.star.mag,m=p.altitudeDeg;return{kind:"star",name:(m<0?n?.starTooltipBelow??$6:n?.starTooltip??H6).replace("{name}",i.star(p.star)).replace("{mag}",v.toLocaleString(void 0,{maximumFractionDigits:Math.abs(v)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(m))))}}}decorTooltip(t,e){const i=l=>l.toLocaleString(void 0,{maximumFractionDigits:l<10?1:0}),n=wt.sizeOf(t),s=this.sceneRenderer.decorDistanceM(t.id),r=s===void 0?"":s>=1e3?`${(s/1e3).toLocaleString(void 0,{maximumFractionDigits:1})} km`:`${i(s)} m`;return(this.naming.names?.decorTooltip??G6).replace("{name}",e).replace("{size}",`${i(n.widthM)} × ${i(n.lengthM)} × ${i(n.heightM)} m`).replace("{distance}",r)}bodyName(t){const e=t.startsWith(C2)?t.slice(C2.length):void 0,i=e?Qx.find(r=>r.id===e):void 0;if(i)return this.naming.comet(i);const n=t.startsWith(O2)?T2.byId(t.slice(O2.length)):void 0;if(n)return this.naming.nova(n);const s=B6[t];return s===void 0?t:this.naming.body(t,s)}get naming(){return this.sceneNaming}sceneNaming=new jd;namesLanguage="en";async loadSceneNames(){const t=Hm(ya.preferencesFor(this),Gm);if(t===this.namesLanguage)return;this.namesLanguage=t;const e=await iy(t);t===this.namesLanguage&&this.applySceneNaming(new jd(e))}setBusy(t,e=""){this.busyElement.hidden=!t,this.busyNote.textContent=t?e:"",this.busyElement.setAttribute("aria-label",e),this.busyElement.setAttribute("aria-busy",String(t))}renderLoaderText(t,e){let i=0;const n=(s,r)=>{s.setAttribute("aria-label",r),s.replaceChildren(),r.split(" ").forEach((o,c)=>{c>0&&s.append(" ");const l=document.createElement("span");l.className="scene-loader-word",l.setAttribute("aria-hidden","true");for(const h of o){const u=document.createElement("span");u.className="scene-loader-letter",u.style.setProperty("--i",String(i++)),u.textContent=h,l.append(u)}s.append(l),i++})};n(this.loaderNotVideo,t),i+=6,n(this.loaderNote,e)}applySceneNaming(t){this.sceneNaming=t;const e=t.names?.credits??ep;this.creditsButton.title=e,this.creditsButton.setAttribute("aria-label",e),t.names&&this.renderLoaderText(t.names.notAVideo,t.names.isASimulation),this.sceneRenderer.setCompassPoints(t.names?.compassPoints)}showHoverTooltip(t,e){this.hoverTooltip.textContent=e,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect(),n=t.clientX-i.left+12,s=n+this.hoverTooltip.offsetWidth-i.width;this.hoverTooltip.style.left=`${s>0?Math.max(0,n-s-4):n}px`,this.hoverTooltip.style.top=`${t.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(t){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),Xi.thunderDelayMs(t))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(Ih(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;applyLevel(){const t=this.ufoElement.level;this.weatherAudio.setLevel(t),this.vehicleAudio.setLevel(t),this.aircraftAudio?.setLevel(t)}handlePageGesture=()=>{this.ufoElement.playbackState==="playing"&&this.handleFirstInteraction()};unlockIfAlreadyActivated(){this.interacted||navigator.userActivation?.hasBeenActive&&this.handleFirstInteraction()}static GESTURES=["pointerdown","pointerup","touchend","click","keydown"];handleTimeUpdate=t=>{this.lastTimeMs=t.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now()),this.ufoElement.repaintChrome()};syncAnimationsToPlayback(){const t=this.ufoElement.playbackState==="playing";this.sceneRenderer.setAnimationsRunning(t,t),this.weatherAudio.setPaused(!t),this.vehicleAudio.setPaused(!t),this.aircraftAudio?.setPaused(!t),t&&this.unlockIfAlreadyActivated(),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${$w}</style>${Yw}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.frameElement=this.shadow.getElementById("frame"),this.sceneCanvas=this.shadow.getElementById("scene-canvas"),this.sceneRenderer=new Nt(this.sceneCanvas);const e=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.renderLoaderText("This is not a video","It is a real-time simulation."),this.busyElement=this.shadow.getElementById("scene-busy"),this.busyNote=this.shadow.getElementById("scene-busy-note"),this.loader=e,this.poster=new Lg(this.shadow.getElementById("scene-poster"),()=>{this.loader.style.animationDelay=!this.poster.up&&this.holding?"0s":"",this.applyHold()}),this.sceneRenderer.onFirstFrameHold=s=>{this.holding=s,this.applyHold()},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(lp),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"&&on.fill(n,this)}),this.creditsButton.title=ep,this.creditsButton.setAttribute("aria-label",ep),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.addEventListener("playrequest",()=>this.poster.release()),this.ufoElement.addEventListener(py,()=>this.poster.restore()),this.ufoElement.seekPreviewPainter=(s,r)=>this.seekPreviewOf(r).paint(s,r),this.ufoElement.addEventListener("mutedchange",()=>this.applyLevel()),this.ufoElement.ambientSound=s=>s.vehicle!==void 0||s.decor.some(r=>r.engine!==void 0)||s.weatherTrack.allKeyframes.some(r=>r.weather.precipitationType!=="none"||r.weather.windSpeed>1),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.addEventListener("traceview",s=>this.sceneRenderer.setTracesShown(s.detail.shown)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of ze.GESTURES)this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new fs(ya.preferencesFor(this))}saidTexts;traceLabelsFor;observerHeadlightsAt(t,e){const i=t.vehicle;return i?{setting:Mo.at(i.headlights??"auto",i.headlightKeyframes,e)??"auto",headingDeg:this.travelHeadingAt(t,e)}:void 0}travelHeadingAt(t,e){const i=ei(t,e);if(!i)return 0;for(const n of[400,-400]){const s=ei(t,e+n);if(!s||i.lat===void 0||i.lng===void 0||s.lat===void 0||s.lng===void 0)break;const r=ue(s.lat,s.lng,i.lat,i.lng);if(Math.hypot(r.x,r.z)<.8)continue;return(Math.atan2(r.x,-r.z)*180/Math.PI+(n<0?180:0)+360)%360}return i.headingDeg??0}routeCache;routeOf(t){const e=t.allKeyframes;if(this.routeCache?.track===t&&this.routeCache.count===e.length)return this.routeCache.route;const i=e.flatMap(s=>s.pose.lat!==void 0&&s.pose.lng!==void 0?[{lat:s.pose.lat,lng:s.pose.lng}]:[]),n=i.length>=2?i:void 0;return this.routeCache={track:t,count:e.length,route:n},n}traceLabels(t){const e=ya.preferencesFor(this).join();if(this.traceLabelsFor?.traces!==t||this.traceLabelsFor.language!==e){const i=new Map;for(const n of t){const s=this.said.read(n.title);s&&i.set(n.id,s)}this.traceLabelsFor={traces:t,language:e,labels:i}}return this.traceLabelsFor.labels}connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),this.watchVisibility(),document.addEventListener("fullscreenchange",this.handleFullscreenChange);for(const e of ze.GESTURES)document.addEventListener(e,this.handlePageGesture,!0);const t=this.getAttribute("src");t&&this.loadFromSrc(t)}watchVisibility(){this.visibilityObserver?.disconnect(),!(typeof IntersectionObserver>"u"||this.hasAttribute("always-live"))&&(this.visibilityObserver=new IntersectionObserver(t=>{if(t[t.length-1].isIntersecting){this.sceneRenderer.resume();return}this.ufoElement.pause(),this.sceneRenderer.suspend()},{rootMargin:"100px"}),this.visibilityObserver.observe(this))}visibilityObserver;disconnectedCallback(){this.visibilityObserver?.disconnect(),this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange);for(const t of ze.GESTURES)document.removeEventListener(t,this.handlePageGesture,!0);this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),this.vehicleAudio.dispose(),this.aircraftAudio?.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),(t==="star-catalog-src"||t==="deep-star-catalog-src")&&i!==e&&this.isConnected&&this.loadStars(),t==="show-compass"&&i!==e&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),t==="max-pixel-ratio"&&i!==e){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(t===cr||t===lr||t===no)&&i!==e&&this.forwardPlayerAttributes(),t===no&&this.stageElement.classList.toggle("minified",i!==null)}forwardPlayerAttributes(){for(const t of[cr,lr,no]){const e=this.getAttribute(t);e===null?this.ufoElement.removeAttribute(t):this.ufoElement.setAttribute(t,e)}}setCompassForced(t){this.sceneRenderer.setCompassForced(t)}lookToward(t){const e=ei(this.ufoElement.sighting,this.lastTimeMs);if(t.kind==="observer"||e?.lat===void 0||e.lng===void 0||e.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=ue(t.lat,t.lng,e.lat,e.lng);if(Math.hypot(i,n)<1)return this.setLookOffset(0,0);const s=(Math.atan2(i,-n)*180/Math.PI+360)%360;this.setLookOffset(((s-e.headingDeg)%360+540)%360-180,-e.pitchDeg)}setLookOffset(t,e){this.sceneRenderer.setLookOffset(t,e),this.ufoElement.setLookOffset(t,e),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(t,e){this.sceneRenderer.setIndoorLook(t,e)}setCloudRendering(t){this.sceneRenderer.setCloudRendering(t)}setWeather(t){this.sceneRenderer.setWeather(t),this.weatherAudio.setAmbient(t.precipitationType,t.precipitationIntensity*(t.precipitationAmount??1),t.windSpeed)}pickCloudAt(t,e){return this.sceneRenderer.pickCloudAt(t,e)}cloudDirectionAt(t,e){return this.sceneRenderer.cloudDirectionAt(t,e)}pickDecorAt(t,e){return this.sceneRenderer.pickDecorAt(t,e)}decorScreenBox(t){return this.sceneRenderer.decorScreenBox(t)}decorGroundPointAt(t,e,i,n=0){return this.sceneRenderer.decorGroundPointAt(t,e,i,n)}decorMetresPerNdcY(t){return this.sceneRenderer.decorMetresPerNdcY(t)}decorGrabHeightAt(t,e,i){return this.sceneRenderer.decorGrabHeightAt(t,e,i)}bodyScreenBox(t){return this.sceneRenderer.bodyScreenBox(t)}pickPlacedBodyAt(t,e){return this.sceneRenderer.pickPlacedBodyAt(t,e)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume()}async loadFromSrc(t){const e=Fl.json(t);this.holdForNewScene(e);const i=await e;this.documentUrl=new URL(t,location.href).href,this.showPoster(i.image,this.documentUrl,!this.ufoElement.playRequested),this.sightingData=i}loader;poster;showPoster(t,e,i=!0){this.poster.show(t,e,i)}applyHold(){const t=this.holding,e=this.poster.up;this.loader.hidden=!t||e,t&&(this.hoverTooltip.hidden=!0),this.ufoElement.captionHeld=t||e,this.ufoElement.controlsHeld=t||e,this.ufoElement.holdClock(t)}holdForNewScene(t){this.sceneRenderer.holdForNewScene(t)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(t){this.sceneRenderer.documentUrl=t}get sightingData(){return this.ufoElement.sightingData}set sightingData(t){this.ufoElement.sightingData=t,this.seekPreview?.recordingChanged(t),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.syncAccountHidden(),this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(t){const e=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(t.width/e);return t.height!==i&&(t.height=i),this.seekPreview??=new Zd(this,()=>document.createElement(tf))}showAt(t){this.ufoElement.currentTime=t,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(t){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const e=t.getContext("2d");return e?(e.imageSmoothingQuality="high",e.drawImage(this.sceneCanvas,0,0,t.width,t.height),!0):!1}referenceAspect(t){return this.sceneRenderer.referenceAspect(t)}screenPointOf(t){return this.sceneRenderer.screenPointOf(t)}directionAt(t,e){return this.sceneRenderer.directionAt(t,e)}referenceFailedToLoad(t){return this.sceneRenderer.referenceFailedToLoad(t)}applyReferenceView(t){this.sceneRenderer.setReferencesShown(t.shown);for(const e of this.ufoElement.sighting.references){const i=t.views?.[e.id];this.sceneRenderer.setReferenceView(e.id,{opacity:i?i.shown?i.opacity:0:t.opacity})}}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}get currentWaterAttribution(){return this.sceneRenderer.currentWaterAttribution}get currentRailwayAttribution(){return this.sceneRenderer.currentRailwayAttribution}setTerrainProviders(t){this.sceneRenderer.setTerrainProviders(t)}setDecorModelProvider(t){this.sceneRenderer.setDecorModelProvider(t)}get decorModelCredits(){return[...new Map(this.sceneRenderer.currentDecorModelCredits.map(e=>[`${e.title}|${e.author??""}|${e.license}|${e.sourceUrl??""}`,e])).values()]}applyFrameFormat(){const t=this.ufoElement.sighting.instrument,e=qe.CANVAS_HEIGHT_PX,i=Li.frameWidthPx(t,e);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${e}`)}resizeToStage(){const t=this.frameElement.getBoundingClientRect(),e=Math.max(1,Math.round(t.width)),i=Math.max(1,Math.round(t.height));this.sceneCanvas.width=e,this.sceneCanvas.height=i,this.sceneRenderer.resize(e,i)}async loadStars(){const t=[{magnitudeLimit:Z0,url:this.getAttribute("star-catalog-src")??K6},{magnitudeLimit:J0,url:this.getAttribute("deep-star-catalog-src")??Z6}],e=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=e>Z0?J0:Z0;const n=await Ys.upTo(t,e);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=J0||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const t=this.ufoElement.sighting,e=cn.gainFor(t.instrument,{fNumber:ei(t,0)?.fNumber,fieldOfViewDeg:Hn.fovOf(t,0),exposureSeconds:t.exposure});return Zu(J6,e)}updateAstronomy(t){this.ensureStarsDeepEnough(),this.applySceneAt(t);const e=Ts.windowEndingAt(t,this.exposureSeconds()),i=e.seconds,n=this.degreesPerPixelAt(t),s=go.instants(i,n),r=Math.max(s,this.ufoElement.exposureTimes(t).length,Ts.instants(this.decorWithTraffic(this.ufoElement.sighting),ei(this.ufoElement.sighting,t)?.elevationM??0,e.fromMs,i,n));if(r<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(r,o=>this.applySceneAt(e.fromMs+e.ms*o/(r-1),{sky:Math.floor(o*s/r)!==Math.floor((o-1)*s/r),stepMs:e.ms/r}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(t){const e=this.sceneCanvas.height;return e<=0?0:Hn.fovOf(this.ufoElement.sighting,t)/e}roadGradeAt(t,e){return t.observerTrack.allKeyframes.length<2?0:fc.at(t,e,this.sceneRenderer.bodyGround)}get roadGradeDeg(){return this.roadGradeAt(this.ufoElement.sighting,this.ufoElement.currentTime)}applySceneAt(t,e){const i=this.ufoElement.sighting;this.setWeather(Ih(i,t)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),e||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,t)),e||this.pushAircraftSound(i,t),this.updateMeteorShower(i,t),this.updateLightning(i,t,e!==void 0),this.sceneRenderer.setDecor(this.seatedDecor(this.decorWithTraffic(i),t)),this.sceneRenderer.setDecorPresence(this.traffic?.set?.presence??ze.NO_PRESENCE),this.sceneRenderer.setDecorSunlight(this.trafficSunlight(t)),this.sceneRenderer.setContrails(this.traffic?.contrails??ze.NO_CONTRAILS),this.sceneRenderer.setContrailSunlight(this.contrailSunlight(t));const n=ei(i,t);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=ei(i,0),r=cc(i,0),o=Na(i.event.time??{},n?.lng??Nu.lng,i.event.utcOffsetHours),c=i.weatherSource!==void 0&&o?Ww(o):void 0,l=Object.fromEntries(ed(cc(i,t)).map(D=>[D.id,w1(t,i.weatherTrack,r,s,n,D.id,D.instances?.length?void 0:c)]));this.sceneRenderer.setCloudOffset(w1(t,i.weatherTrack,r,s,n,void 0,c),l),this.sceneRenderer.setObserverPose(n?{...n,pitchDeg:n.pitchDeg+this.roadGradeAt(i,t)}:Nu),this.sceneRenderer.setLensOptics(this.lensOpticsAt(t)),this.sceneRenderer.setInstrumentGain(cn.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:Hn.fovOf(i,t),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0,Is.byId(n?.filter).opticalDensity),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setPerception(th.perceptionOf(i.account?.observerPerception)),this.sceneRenderer.setGait(He.bodyAt(i,t,this.ufoElement.steadyBody)),this.sceneRenderer.updateDecorAnchoring(ei(i,0),n,t),this.placeBodiesAt(t,e===void 0),this.sceneRenderer.updateDecorLitState(t,e?.stepMs??0),this.sceneRenderer.setObserverRoute(this.routeOf(i.observerTrack)),this.sceneRenderer.setObserverHeadlights(this.observerHeadlightsAt(i,t)),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng,()=>{this.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.sceneRenderer.setTraces(i.traces,this.traceLabels(i.traces)),this.pushPhenomenaAt(t);const h=n?.lat??Nu.lat,u=n?.lng??Nu.lng,d=Na(i.event.time??{},u,i.event.utcOffsetHours),f={lat:h,lng:u,elevationM:n?.elevationM??0};this.pushSatellitesAt(d,t,f),this.ensureFireballs(d);const p=[...this.interpretationShown?.reentries??[],...this.fireballs?.reentries??[]];this.sceneRenderer.setReentries(p.length===0?[]:Ee.viewsAt(p,t,{lat:h,lng:u,heightM:f.elevationM}));const v=this.interpretationShown?.launches??[];if(this.sceneRenderer.setLaunchPlumes(v.length===0||!d?[]:we.viewsAt(v,t,{lat:h,lng:u,heightM:f.elevationM},we.sunDirectionAt(new Date(d.getTime()+t)))),e&&!e.sky)return;if(this.sceneRenderer.setSkyUnknown(!d),!d){this.sceneRenderer.setAstronomy(j6);return}const m=new Date(d.getTime()+t),g=Math.max(1,Math.round(.25*this.degreesPerPixelAt(t)/go.DEG_PER_SECOND*1e3)),y=Math.max(1e-8,this.degreesPerPixelAt(t)*.1),x=`${Math.floor(m.getTime()/g)}|${Math.round(h/y)}|${Math.round(u/y)}|${Math.round(f.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(x===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=x;const M=bu("Sun",m,f),w=bu("Moon",m,f);let S=Ci.separationOf(M,w)<1?Ci.viewAt(m,f):void 0;if(S){const D=Ci.offsetOf(M,w,S.separationDeg);if(S.obscuration>ze.LIMB_FROM_OBSCURATION){const I=this.limbFor(m,f);I&&(S={...S,obscuration:1-hs.uncoveredFraction(I,S.sunRadiusDeg,D),limb:I})}S={...S,horizonShare:Ci.horizonShare(S,D,M.altitudeDeg,M.azimuthDeg,tr.distanceKm(m,f))}}const _={...M,magnitude:_0("Sun",m)-2.5*Math.log10(Ci.beamFraction(S))};this.lastSun={altitudeDeg:_.altitudeDeg,azimuthDeg:_.azimuthDeg};const b={...w,phase:fD(m),magnitude:_0("Moon",m),radiusDeg:tr.apparentRadiusDeg(m,f)},A=dD.map(D=>({body:D,position:bu(D,m,f),magnitude:_0(D,m)}));this.sceneRenderer.setAstronomy({sun:_,moon:b,planets:A,comet:this.cometAt(m,f),novae:T2.appearancesAt(m,f).map(({outburst:D,position:I,magnitude:O})=>({id:D.id,position:I,magnitude:O})),stars:this.starCatalog?{catalog:this.starCatalog,date:m,observer:f}:void 0,frame:{date:m,observer:f},localHour:((m.getUTCHours()+m.getUTCMinutes()/60+(i.event.utcOffsetHours??Math.round(u/15)))%24+24)%24,eclipse:S}),this.ufoElement.setSunAltitude(_.altitudeDeg)}static LIMB_FROM_OBSCURATION=.98;limbRelief;limbRequested=!1;limbCache;limbFor(t,e){if(!this.limbRelief){this.limbRequested||(this.limbRequested=!0,Ql.load(q6).then(s=>{this.limbRelief=s,this.lastSkyKey="",s&&this.isConnected&&this.updateAstronomy(this.lastTimeMs)}));return}const i=this.limbCache;if(i&&Math.abs(t.getTime()-i.atMs)<5e3&&i.lat===e.lat&&i.lng===e.lng&&i.elevationM===e.elevationM)return i.profile;const n=hs.profile(t,e,this.limbRelief);return this.limbCache={profile:n,atMs:t.getTime(),lat:e.lat,lng:e.lng,elevationM:e.elevationM},n}pushSatellitesAt(t,e,i){if(this.ensureSatellites(t),!t||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(t.getTime()+e),s=[];for(const r of this.satellites.passes.positionsAt(n,i,-1))r.magnitude!==void 0&&s.push({norad:r.object.norad,name:r.object.name,position:{altitudeDeg:r.altitudeDeg,azimuthDeg:r.azimuthDeg},magnitude:r.magnitude,heightKm:r.heightKm});this.sceneRenderer.setSatellites(s)}ensureFireballs(t){const e=this.ufoElement.sighting,i=Math.max((e.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),n=t?.getTime(),s=n===void 0?"":`${n}+${i}`;if(this.fireballs?.key===s)return;if(n===void 0||!er.mayCover(n+i)){this.fireballs={key:s,status:"outside",reentries:[]};return}const r={key:s,status:"loading",reentries:[]};this.fireballs=r,ze.fireballArchive.between(n,n+i).then(o=>{r.status=o?"ready":"unavailable",r.records=o??[],r.reentries=r.records.map(c=>er.asReentry(c,n)),!(this.fireballs!==r||!this.isConnected)&&(this.dispatchEvent(new CustomEvent(X6)),r.reentries.length>0&&this.updateAstronomy(this.lastTimeMs))})}decorWithTraffic(t){const e=this.ensureTraffic(t);if(!e||e.objects.length===0)return t.decor;const i=this.decorMemo;if(i&&i.base===t.decor&&i.traffic===e.objects)return i.merged;const n=[...t.decor,...e.objects];return this.decorMemo={base:t.decor,traffic:e.objects,merged:n},n}seatedDecor(t,e){if(!t.some(r=>r.observerKeyframes?.length))return t;const i=t.map(r=>{if(!r.observerKeyframes?.length)return"";const o=f1(r,e);return`${o.side??"-"}/${o.facing??"-"}`}).join("|"),n=this.seatedMemo;if(n&&n.base===t&&n.seats===i)return n.seated;const s=t.map(r=>{if(!r.observerKeyframes?.length)return r;const o=f1(r,e);return{...r,observerSide:o.side,observerFacing:o.facing}});return this.seatedMemo={base:t,seats:i,seated:s},s}ensureTraffic(t){const e=ei(t,0),i=e?.lng===void 0?void 0:Na(t.event.time??{},e.lng,t.event.utcOffsetHours),n=Math.max((t.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),s=i?.getTime(),r=s===void 0||e?.lat===void 0||e.lng===void 0?"":`${this.aircraftSource.id}|${s}+${n}|${e.lat.toFixed(3)},${e.lng.toFixed(3)}|${Math.round(e.elevationM??0)}`;if(this.traffic?.key===r)return this.traffic.set;if(r===""||s===void 0||e?.lat===void 0||e.lng===void 0){this.traffic={key:r,status:"outside"};return}let o=ze.aircraftProviders.get(this.aircraftSource.id);if(o||ze.aircraftProviders.set(this.aircraftSource.id,o=this.aircraftSource.create()),o.mayCover&&!o.mayCover(s+n)){this.traffic={key:r,status:"outside"};return}const c={key:r,status:"loading",startMs:s,observer:{lat:e.lat,lng:e.lng}};this.traffic=c;const l={lat:e.lat,lng:e.lng,heightM:e.elevationM??0},h=_n.MAX_GAP_S*1e3,u=ze.SOUND_LOOKBACK_MS,d={lat:e.lat,lng:e.lng,elevationM:e.elevationM??0},f=(p,v)=>p.TrafficDecor.from(c.tracks??[],l,s,p.TrafficDecor.MAX_OBJECTS,{models:v,sunElevationAt:m=>this.sunElevationAt(m,d)});o.between(l,s-u,s+n+h).then(async p=>{if(this.traffic!==c)return;if(p.status!=="found"){c.status=p.status==="outside"?"outside":"unavailable",this.announceTraffic();return}let v;try{v=await ze.loadTrafficRuntime()}catch{this.traffic===c&&(c.status="unavailable",this.announceTraffic());return}this.traffic===c&&(c.status="ready",c.tracks=p.tracks,c.set=f(v),this.startAircraftSound(c,v),this.announceTraffic(),this.describeTraffic(o,c,v,f),c.set.shown>0&&this.readUpperAir(c,v,s-u,s+n+h))})}trafficSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||i.startMs===void 0||!i.observer)return e;for(const[r,o]of n.presence){if(t<o.fromMs||t>o.untilMs)continue;const c=n.flights.get(r),l=c?_n.positionAt(c,i.startMs+t):void 0;l&&e.set(r,{heightM:l.geo.heightM,sunElevationDeg:Rn.sunElevationDeg(s,i.observer,l.geo)})}return e}trafficTooltipAt(t,e){const i=this.sceneRenderer.pickTrafficAt(t,e),n=i?this.trafficInfoAt(i):void 0;if(!n)return;const s=this.naming,r=ze.trafficRuntime;return r?.TrafficTooltip.text(n,s.names?.trafficTooltip??r.TrafficTooltip.ENGLISH,o=>s.towards(o))}trafficInfoAt(t){const e=this.traffic,i=e?.set?.flights.get(t);if(!e||!i||e.startMs===void 0||!e.observer)return;const n=ze.trafficRuntime;if(!n)return;const s=e.descriptions?.get(ds.keyOf(i)),r=ei(this.ufoElement.sighting,this.lastTimeMs),o={lat:e.observer.lat,lng:e.observer.lng,heightM:r?.elevationM??0},c=n.AmbientNoise.dbA(Ih(this.ufoElement.sighting,this.lastTimeMs)),l=n.TrafficInfos.at(i,s,o,e.startMs+this.lastTimeMs,{ambientDbA:c}),h=l&&this.contrailAt(t,this.lastTimeMs);return l&&h?{...l,contrail:h}:l}contrailAt(t,e){const i=this.traffic?.contrails?.find(s=>s.id===t);if(!i)return;let n;for(const s of i.points){if(s.tMs>e)break;n=s}return n?.forms?{persistent:n.persistent,iceRelativeHumidity:n.iceRelativeHumidity}:void 0}startAircraftSound(t,e){this.aircraftAudio??=this.newAircraftAudio(e),this.sortOutAudible(t,e)}sortOutAudible(t,e){!t.set||!t.observer||(t.audible=e.TrafficSound.candidates(t.set.flights,t.descriptions??new Map,ds.keyOf,{...t.observer,heightM:0},{ambientDbA:e.AmbientNoise.BASE_DB_A}))}pushAircraftSound(t,e){this.startDecorAircraftSound(t);const i=this.aircraftAudio;if(!i)return;const n=ze.trafficRuntime;if(!n){i.setVoices([]);return}const s=ei(t,e),r=Ih(t,e),o={ambientDbA:n.AmbientNoise.dbA(r),referenceAmplitude:n.AmbientNoise.referenceAmplitude(r)},c=this.trafficVoices(e,s,o,n),l=t.event.place?.[0],h={lat:s?.lat??l?.lat,lng:s?.lng??l?.lng};h.lat!==void 0&&h.lng!==void 0&&(this.decorAircraftHearing??=new n.DecorAircraftHearing,c.push(...this.decorAircraftHearing.voices(t,e,{lat:h.lat,lng:h.lng,heightM:s?.elevationM??0},o,u=>this.decorModelSounds.get(u.model?.id??""))),c.sort((u,d)=>d.levelDbA-u.levelDbA),c.length=Math.min(c.length,4)),i.setVoices(c,s?.headingDeg??0)}trafficVoices(t,e,i,n){const s=this.traffic,r=s?.set;if(!s||!r||!s.audible||s.startMs===void 0||!s.observer)return[];const o={lat:s.observer.lat,lng:s.observer.lng,heightM:e?.elevationM??0};return n.TrafficSound.voices(s.audible,r.flights,s.descriptions??new Map,ds.keyOf,o,s.startMs+t,i)}startDecorAircraftSound(t){const e=t.decor.filter(i=>i.kind==="aircraft"&&i.track?.some(n=>(n.altitudeM??0)>0));if(e.length!==0){for(const i of e){const n=i.model?.id;!n||i.model?.url!==void 0||this.decorModelSounds.has(n)||(this.decorModelSounds.set(n,void 0),this.sceneRenderer.entryOfDecorModel(n).then(s=>{this.decorModelSounds.set(n,s?.parameters?.sound)}))}if(this.aircraftAudio||ze.trafficRuntime){!this.aircraftAudio&&ze.trafficRuntime&&(this.aircraftAudio=this.newAircraftAudio(ze.trafficRuntime));return}ze.loadTrafficRuntime().catch(()=>{})}}newAircraftAudio(t){const e=new t.AircraftAudio;return e.setLevel(this.ufoElement.level),this.interacted&&e.resume(),e.setPaused(this.ufoElement.playbackState!=="playing"),e}announceTraffic(){this.isConnected&&(this.dispatchEvent(new CustomEvent(Y6)),this.updateAstronomy(this.lastTimeMs))}async describeTraffic(t,e,i,n){if(!t.describe||!e.set||!e.tracks)return;const s=new Set([...e.set.flights.values()].map(l=>ds.keyOf(l))),r=e.tracks.filter(l=>s.has(ds.keyOf(l))&&l.points.length>0),o=new Map,c=new Map;await Promise.all(r.map(async l=>{const h=new Date(l.points[0].t).toISOString().slice(0,10),u=await t.describe(l,h).catch(()=>{});u&&(c.set(ds.keyOf(l),u),o.set(ds.keyOf(l),i.AircraftModels.of(u)))})),!(this.traffic!==e||o.size===0)&&(e.descriptions=c,e.models=o,e.set=n(i,o),this.planContrails(e,i),this.sortOutAudible(e,i),this.announceTraffic())}async readUpperAir(t,e,i,n){if(!t.observer)return;const s=this.upperAirSource??e.UPPER_AIR_SOURCES[0];let r=ze.upperAirProviders.get(s.id);r||ze.upperAirProviders.set(s.id,r=s.create());const o=await r.between(t.observer,i,n);this.traffic!==t||o.status!=="found"||(t.air=o.samples,t.airSource=o.source,this.planContrails(t,e),this.announceTraffic())}planContrails(t,e){!t.set||!t.air||t.startMs===void 0||(t.contrails=e.AircraftContrails.plan(t.set,t.models,t.air,t.startMs))}contrailSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||!i.contrails?.length||i.startMs===void 0||!i.observer)return e;for(const r of i.contrails){const o=n.presence.get(r.id),c=n.flights.get(r.id);if(!o||!c)continue;const l=_n.positionAt(c,i.startMs+Math.min(o.untilMs,Math.max(o.fromMs,t)));l&&e.set(r.id,{heightM:l.geo.heightM,sunElevationDeg:Rn.sunElevationDeg(s,i.observer,l.geo)})}return e}sunElevationAt(t,e){const i=bu("Sun",new Date(t.t),e);return Rn.sunElevationDeg(i,e,t)}upperAirSource;setUpperAirSource(t){t.id!==this.upperAirSource?.id&&(this.upperAirSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}setAircraftSource(t){t.id!==this.aircraftSource.id&&(this.aircraftSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}get aircraftState(){const t=this.traffic?.contrails?.length?this.upperAirSource??ze.trafficRuntime?.UPPER_AIR_SOURCES[0]:void 0;return{trailCredit:t&&{credit:t.credit,creditUrl:t.creditUrl},status:this.traffic?.status??"none",total:this.traffic?.set?.total??0,shown:this.traffic?.set?.shown??0,credit:this.aircraftSource.credit,creditUrl:this.aircraftSource.creditUrl}}get fireballState(){return{status:this.fireballs?.status??"none",records:this.fireballs?.records??[]}}ensureSatellites(t){const e=t?String(t.getTime()):"";if(e===this.satellitesFor)return;this.satellitesFor=e,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!t){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=r=>{i===this.satelliteRequest&&(this.satelliteStatus=r,this.isConnected&&this.dispatchEvent(new CustomEvent(W6)))},s=ze.tleArchive;(async()=>{if(!await s.covers(t))return n("outside");const[r,o]=await Promise.all([s.at(t),Xe(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!r)return n("unavailable");this.satellites={snapshot:r,passes:new o.SatellitePasses(r.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const t=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:t?.coverage,credit:t?.credit,creditUrl:t?.creditUrl}}satellitePassesDuring(t){const e=this.satellites,i=this.ufoElement.sighting,n=ei(i,0),s=i.event.place?.[0],r=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!e||r===void 0||o===void 0)return[];const c=Na(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(t,0),4*36e5),h={lat:r,lng:o,elevationM:n?.elevationM??0},u=JSON.stringify([this.satellitesFor,c.getTime(),r,o,h.elevationM,l]);if(this.satellitePassesMemo?.key===u)return this.satellitePassesMemo.passes;const d=Math.max(10,Math.ceil(l/1e3/600)),f=e.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(t,e){const i=O6.brightestAt(t,e);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(t){const e=this.ufoElement.sighting;e!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=e);const i=e.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,r=this.projectionAt(t),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(t,p);if(!v)continue;const m={...v,bounds:{...v.bounds,x:v.bounds.x+s.x,y:v.bounds.y+s.y}};o.set(p,m);const g=v.aim?this.sceneRenderer.screenPointOf(_s.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)},y=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,x=y?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(y||v.aim)&&l.delete(p);const M=v.angular?.widthDeg??r.pxToDeg(v.bounds.width),w=this.sizeEstimateOf(p);w.add(M,x);const S=eh.of(e,p);c.set(p,En.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:S&&M>0?qe.distanceMAt(S.widthM,M):void 0,range:w.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=c.get(m);x&&c.set(p,{distanceM:x.distanceM*.999,basis:x.basis});break}this.depths=c;const h=i.sourceIds,u=[];for(const[p,v]of o)u.push({sourceId:p,shape:v,distanceM:c.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:l.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(ei(e,t)?.rollDeg??0)+He.bodyAt(e,t,this.ufoElement.steadyBody).rollDeg;this.sceneRenderer.setPhenomena(u,{projection:r,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:Li.starPointsOf(e.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(t){this.interpretationShown=t,this.ufoElement.playerTitle=t?.title,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.repaintChrome()}syncAccountHidden(){this.ufoElement.accountHidden=this.interpretationShown!==void 0&&!this.comparing}get accountInTheRound(){return this.inTheRound}set accountInTheRound(t){this.inTheRound=t}get compareAccount(){return this.comparing}set compareAccount(t){t!==this.comparing&&(this.comparing=t,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.repaintChrome())}get confrontation(){return this.confrontationReadings}groundAlong(t,e,i){const n=this.sceneRenderer.bodyGround,s=Kt.eyeOf(this.ufoElement.sighting,i,n);return s?Kt.lineOfSightMeetsGround(s,t,e,n):void 0}bodyMaskedBy(t,e){return this.sceneRenderer.bodyMaskedByDecor(t,e)}bodyReading(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=d=>Kt.eyeOf(n,d,i),r=new Kt(t,i,s).at(e),o=s(e);if(!r||!o)return;const c=r.eastM-o.eastM,l=r.northM-o.northM,h=r.upM-o.upM,u=Math.hypot(c,l);return{azimuthDeg:(Math.atan2(c,l)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,u)*180/Math.PI,distanceM:Math.hypot(u,h),eastM:r.eastM,northM:r.northM,aboveGroundM:r.upM-r.sizeM.heightM/2-i.heightAt(r.eastM,r.northM),sizeM:r.sizeM,attitude:r.attitude,appearance:r.appearance}}directionToBody(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>Kt.eyeOf(n,p,i),r=new Kt(t,i,s),o=r.at(e)?e:t.track[0]?.t,c=o===void 0?void 0:r.at(o),l=o===void 0?void 0:s(o);if(!c||!l)return;const h=c.eastM-l.eastM,u=c.northM-l.northM,d=c.upM-l.upM,f=Math.hypot(h,u);if(!(f===0&&d===0))return{azimuthDeg:(Math.atan2(h,u)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(d,f)*180/Math.PI}}placeBodiesAt(t,e){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],r=[];const o=this.sceneRenderer.bodyGround,c=p=>Kt.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new Kt(p,o,c).at(t)).filter(p=>p!==void 0));const l=cc(n,t),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,t/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(t):void 0;if(d&&(r=new wi(n.timeline).at(t,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=r,!e)return;const f=JSON.stringify(r);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(tb,{detail:r})))}setDistanceHypothesis(t,e){e===void 0||!(e>0)?this.distanceHypotheses.delete(t):this.distanceHypotheses.set(t,e),this.updateAstronomy(this.lastTimeMs)}depthOf(t){return this.depths.get(t)}sizeRangeOf(t){return this.sizeEstimateOf(t).sizeRange}distanceRangeAt(t,e){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(e,t);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(e).pxToDeg(i.bounds.width);return this.sizeEstimateOf(t).distanceRangeAt(n)}sizeContradictory(t){return this.sizeEstimateOf(t).contradictory}updateMeteorShower(t,e){this.ensureMeteorSchedule(t),this.sceneRenderer.updateMeteors(e)}updateLightning(t,e,i){if(this.ensureLightningSchedule(t),this.sceneRenderer.updateLightning(e),i)return;const n=this.lastLightningT;if(this.lastLightningT=e,n===void 0||e<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(r=>r.t>n&&r.t<=e).pop();s&&cc(t,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(t){const e=cc(t,0).precipitationIntensity,i=`${this.meteorInputsOf(t)}|${e}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=t.event.time,s=t.event.place?.[0],r=n?.year!==void 0?Na(n,s?.lng??0,t.event.utcOffsetHours):void 0,o=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,c=Math.round((r?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=Xi.schedule({durationMs:o,seed:c,intensity:e}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(t){const e=this.meteorInputsOf(t);e!==this.meteorScheduleFor&&(this.meteorScheduleFor=e,this.scheduleMeteors(t))}meteorInputsOf(t){const e=t.event.place?.[0],i=t.event.time;return JSON.stringify([e?.lat,e?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,t.event.utcOffsetHours,t.event.durationSeconds,t.timeline.duration])}scheduleMeteors(t){const e=t.event.place?.[0],i=t.event.time,n=e?.lat!==void 0&&e.lng!==void 0&&i?.year!==void 0?Na(i,e.lng,t.event.utcOffsetHours):void 0;if(!n||e?.lat===void 0||e.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:e.lat,lng:e.lng,elevationM:0},r=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(e.lat*1e3),c=Ei.schedule({ratePerHour:Ei.observedRatePerHour(Ei.apexPosition(n,s).altitudeDeg),durationMs:r,velocityKmS:Ei.TYPICAL_VELOCITY_KM_S,seed:o}),l=Q0.activeAt(n).map(u=>{const d=Q0.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:Q0.observedRatePerHour(u.zhr,d.altitudeDeg,u.shower.populationIndex)}}).sort((u,d)=>d.rate-u.rate)[0];if(!l||l.rate<=0){this.sceneRenderer.setMeteorShower(c,0,0);return}const h=po.schedule({ratePerHour:l.rate,durationMs:r,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(t){this.ensureMeteorSchedule(this.ufoElement.sighting);const e=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,r)=>r.brightness-s.brightness);if(e.length===0)return;const i=e[t%e.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(t){const e=this.ufoElement.sighting,i=e.instrument,n=i.frame,s=ei(e,t),r=s?.fNumber??i.fNumber;if(!n||r===void 0)return;const o=Li.focalLengthMmFor(i,Hn.fovOf(e,t));if(o!==void 0)return{focalLengthMm:o,fNumber:r,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(t){const e=this.ufoElement.sighting;return Pr.of(e.instrument,qe.CANVAS_HEIGHT_PX,Hn.fovOf(e,t))}sizeEstimateOf(t){let e=this.sizeEstimates.get(t);return e||(e=new L6,this.sizeEstimates.set(t,e)),e}}const tf="rr0-scene";function eb(){fy(),customElements.get(tf)||customElements.define(tf,ze)}const Q6={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"},timeQualifierApproximate:"Approximate",timeQualifierUncertain:"Uncertain",timeQualifierBoth:"Uncertain and approximate",timeSeasonSpring:"Spring",timeSeasonSummer:"Summer",timeSeasonAutumn:"Autumn",timeSeasonWinter:"Winter",summaryGroups:{observation:"Observation",location:"Position",temporal:"Time",weather:"Weather",sound:"Sound"},summaryGroup:"Summary",summaryDescription:"Description",closeDescription:"Close the description",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",rareIceCrystals:"Rare crystals",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",filter:"In front of it",filterNone:"nothing",filterSolarVisual:"a solar filter for the eye (eclipse glasses, density 5)",filterSolarPhoto:"a solar film for a camera (density 3.8)",decorAircraft:"Aircraft",decorEntity:"Being",decorAltitude:"Altitude",decorLights:"Lights",decorLightsNone:"none",decor:"Environment",decorBuilding:"Building",decorTree:"Tree",decorShrub:"Shrub",decorBridge:"Bridge",decorWire:"Overhead line",decorCrop:"Crop row",decorTerrace:"Terrace (restanque)",decorMound:"Stone heap",decorWall:"Dry-stone wall",decorStreetlight:"Streetlight",decorTrafficLight:"Traffic light",decorCrossing:"Pedestrian crossing",decorRoadSign:"Road sign",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",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelAdvanced:"Model from an address",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorObserverSide:"Observer location",decorObserverSideNone:"Not present",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},Ul={...Q6,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"},credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Player",embedEdit:"Editor",share:"Share",embedObservation:"Embed the observation",back:"Back",embedCopy:"Copy",shareLink:"Link",shareScope:"Share",shareScopeCase:"Whole case",shareOpensOn:"Opens on",shareStartAt:"Start at",shareOptionLabels:"Show summary chips",shareOptionMap:"Open map",shareOptionMilestones:"Show moments",shareOptionCompare:"Compare account",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"},t8=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:Ul},Symbol.toStringTag,{value:"Module"}));class ln{static PLAIN=/^\d+(?:[.,]\d+)?$/;static COLONS=/^(?:(\d+):)?(\d{1,2}):(\d{1,2}(?:[.,]\d+)?)$/;static UNITS=/^(?:(\d+(?:[.,]\d+)?)h)?(?:(\d+(?:[.,]\d+)?)m)?(?:(\d+(?:[.,]\d+)?)s)?$/i;static CLOCK=/^(?:(\d{4})-(\d{2})-(\d{2})[T ])?T?(\d{1,2}):(\d{2})(?::(\d{2}(?:[.,]\d+)?))?$/;static num(t){return t===void 0?0:Number(t.replace(",","."))}static delta(t){const e=(t??"").trim();if(e==="")return;if(ln.PLAIN.test(e))return ln.num(e);const i=ln.COLONS.exec(e);if(i){const[,s,r,o]=i;return Number(r)>=60||ln.num(o)>=60?void 0:ln.num(s)*3600+Number(r)*60+ln.num(o)}const n=ln.UNITS.exec(e);return n&&(n[1]!==void 0||n[2]!==void 0||n[3]!==void 0)?ln.num(n[1])*3600+ln.num(n[2])*60+ln.num(n[3]):/^P/i.test(e)?Tc.seconds(e.toUpperCase()):void 0}static isClock(t){return ln.clock(t)!==void 0}static clock(t){const e=ln.CLOCK.exec((t??"").trim());if(!e)return;const[,i,n,s,r,o,c]=e,l={hour:Number(r),minute:Number(o),second:ln.num(c)};if(!(l.hour>=24||l.minute>=60||l.second>=60)){if(i!==void 0){const h={year:Number(i),month:Number(n),day:Number(s)};if(h.month<1||h.month>12||h.day<1||h.day>31)return;l.date=h}return l}}static elapsedSince(t,e){if(!t||t.hour===void 0||t.minute===void 0)return;const i=t.hour*3600+t.minute*60+(t.second??0),n=e.hour*3600+e.minute*60+e.second;if(e.date){if(t.year===void 0||t.month===void 0||t.day===void 0)return;const r=Date.UTC(e.date.year,e.date.month-1,e.date.day)/1e3+n,o=Date.UTC(t.year,t.month-1,t.day)/1e3+i;return Math.max(0,r-o)}let s=n-i;return s<=-43200&&(s+=86400),Math.max(0,s)}}eb();class ef{static PRODUCTION="https://ufoathome.org";static home(){try{const t=new URL(import.meta.url),e=new URL(location.href);return(e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]"||e.hostname.endsWith(".localhost"))&&t.origin===e.origin?e.origin:ef.PRODUCTION}catch{return ef.PRODUCTION}}}const td=ef.home(),ku="compare-account",ip="start-time",L2="start-clock",Dl="observer",Uu="case",np="account",Fu=`${td}/edit/`;class Bc extends HTMLElement{static get observedAttributes(){return["src","show-labels",ip,L2,Dl,cr,lr,ku]}shadow;sceneElement;toolbarElement;accountElement;accountPrefix;observerText;observerSelect;infoButton;infoPanel;infoAppLink;editLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;shareButton;shareDialog;shareTitle;shareLinkOption;shareLinkLabel;shareLinkBox;shareEmbed;shareClose;shareEmbedOption;shareEmbedLabel;shareLink;shareReplayOptions;embedCode;shareCopy;shareStartOn;shareStart;shareScopeRow;shareScopeLabel;shareScope;shareOpensRow;shareOpensLabel;shareOpens;shareStartLabel;shareOptions;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new rh(Ul,new jd,new fs(["en"]),new Bu({}),{messages:Ul,locale:"en"});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=Ul;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${db}</style>${ub}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.sceneElement=document.createElement(tf),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.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=Xt.SHARE,this.sceneElement.ufoElement.addControl(this.shareButton),this.shareDialog=this.shadow.getElementById("share-dialog"),this.shareTitle=this.shadow.getElementById("share-title"),this.shareLinkOption=this.shadow.getElementById("share-link-option"),this.shareLinkLabel=this.shadow.getElementById("share-link-label"),this.shareLinkBox=this.shadow.querySelector(".share-link"),this.shareEmbed=this.shadow.getElementById("share-embed"),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.shareReplayOptions=this.shadow.getElementById("share-replay-options"),this.embedCode=this.shadow.getElementById("embed-code"),this.shareCopy=this.shadow.getElementById("share-copy"),this.shareStartOn=this.shadow.getElementById("share-start-on"),this.shareStart=this.shadow.getElementById("share-start"),this.shareStartLabel=this.shadow.getElementById("share-start-label"),this.shareScopeRow=this.shadow.getElementById("share-scope-row"),this.shareScopeLabel=this.shadow.getElementById("share-scope-label"),this.shareScope=this.shadow.getElementById("share-scope"),this.shareOpensRow=this.shadow.getElementById("share-opens-row"),this.shareOpensLabel=this.shadow.getElementById("share-opens-label"),this.shareOpens=this.shadow.getElementById("share-opens");const e=i=>({input:this.shadow.getElementById(`share-opt-${i}`),label:this.shadow.getElementById(`share-opt-${i}-label`)});this.shareOptions={labels:e("labels"),map:e("map"),milestones:e("milestones"),compare:e("compare")},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(tb,i=>this.showConfrontation(i.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",i=>{i.newState==="open"&&(this.populateInfoPanel(),this.bringInfoButtonIntoView())}),this.infoPanel.addEventListener("toggle",i=>this.syncInfoOpen(i.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.shareLinkOption.addEventListener("click",()=>this.showShareView("link")),this.shareEmbedOption.addEventListener("click",()=>this.showShareView("embed"));for(const i of[this.shareStartOn,this.shareStart,...Object.values(this.shareOptions).map(n=>n.input)])i.addEventListener("input",()=>this.refreshShareLinks());for(const i of[this.shareScope,this.shareOpens])i.addEventListener("change",()=>this.refreshShareLinks());this.shareCopy.addEventListener("click",()=>void this.copyText(this.shareLink.value,this.shareLink,this.shareCopy)),this.shareDialog.addEventListener("click",i=>{i.target===this.shareDialog&&this.closeShare()});for(const i of[this.embedReplayRadio,this.embedEditRadio])i.addEventListener("change",()=>this.refreshShareLinks());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.isConnected&&this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const t=++this.localeToken,e=ya.preferencesFor(this);this.preferences=e;const i=Hm(e,Gm),[n,s,r]=i==="en"?[Ul,{},void 0]:await Promise.all([uS(i),dS(i),iy(i)]);if(t!==this.localeToken)return;const o=i!==this.language;this.language=i,this.messages=n,this.tags=new Bu(s),this.said=new fs(e),this.summaryBuilder=new rh(this.messages,new jd(r),this.said,this.tags,{messages:this.messages,locale:i}),this.accountPrefix.textContent=this.messages.accountBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const c=this.entries.find(l=>l.src===this.currentSrc);c&&this.offerInterpretations(c),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.shareCopy.textContent=this.messages.embedCopy,this.shareStartLabel.textContent=this.messages.shareStartAt,this.shareScopeLabel.textContent=this.messages.shareScope,this.shareOpensLabel.textContent=this.messages.shareOpensOn,this.shareOptions.labels.label.textContent=this.messages.shareOptionLabels,this.shareOptions.map.label.textContent=this.messages.shareOptionMap,this.shareOptions.milestones.label.textContent=this.messages.shareOptionMilestones,this.shareOptions.compare.label.textContent=this.messages.shareOptionCompare,this.shareStart.setAttribute("aria-label",this.messages.shareStartAt),this.shareEmbedLabel.textContent=this.messages.embed,this.shareLinkLabel.textContent=this.messages.shareLink,this.shareTitle.textContent=this.messages.share,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 fs(["en"]);tags=new Bu({});connectedCallback(){ya.preferencesFor(this).join()!==this.preferences.join()&&this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick)}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t==="show-labels"&&this.applyLabels(this.hasAttribute("show-labels")),(t===cr||t===lr)&&this.forwardPlayerAttributes(),t===Dl&&this.entries.length>1){const n=this.entryAsked(this.entries);n&&n.src!==this.currentSrc&&this.selectObserver(n.src)}t===ku&&this.setComparing(this.hasAttribute(ku))}forwardPlayerAttributes(){for(const t of[cr,lr]){const e=this.getAttribute(t);e===null?this.sceneElement.removeAttribute(t):this.sceneElement.setAttribute(t,e)}}async loadFromSrc(t){this.startPending=!0;const e=Fl.json(t);this.sceneElement.holdForNewScene(e);const i=await e;if(Array.isArray(i))throw new Error(`${t} is a bare list of recordings, which is no longer read: list them as the sighting events of a case.json`);if(Qi.isCase(i)){const n=Qi.sightingUrls(i,new URL(t,location.href).href);if(n.length===0)throw new Error(`${t} is a case with no sighting event: no recording to show`);await this.loadObserverUrls(n,{json:i,url:new URL(t,location.href).href})}else this.setEntries([{src:t,sighting:i}],void 0)}get sightingData(){return this.entries.find(t=>t.src===this.currentSrc)?.sighting}set sightingData(t){this.startPending=!0,this.currentSrc="",this.setEntries([{src:"",sighting:t}],void 0)}seekTo(t,e){const i=this.caseSource,n=e===void 0?void 0:this.entries.find(s=>{const r=this.plain(s).id;return(i?Qi.accountIds(i.json,i.url,s.src,r):[r]).includes(e)});n&&n.src!==this.currentSrc&&this.selectObserver(n.src),this.sceneElement.ufoElement.currentTime=Math.max(0,t)*1e3}get observerUrls(){return this.entries.map(t=>t.src)}set observerUrls(t){this.loadObserverUrls(t)}async loadObserverUrls(t,e){const i=await Promise.all(t.map(async n=>({src:n,sighting:await Fl.json(n)})));this.setEntries(i,e)}reportCaseProblems(t,e){const{duplicateIds:i,unresolved:n}=Qi.problems(t,e.map(s=>this.plain(s).id).filter(s=>s!==void 0));for(const s of i)console.warn(`The case ${t.id??""} gives the id "${s}" to more than one event: a reference to it is ambiguous.`);for(const{reading:s,reference:r}of n)console.warn(`The reading ${s} of the case ${t.id??""} is "interpretationOf" "${r}", which no event of the case has as its id, nor any recording it lists.`)}setEntries(t,e){this.entries=t,this.caseSource=e,e&&this.reportCaseProblems(e.json,t),this.toolbarElement.hidden=t.length===0;const i=t.length>1;this.observerSelect.hidden=!i,this.observerText.hidden=i,this.observerSelect.innerHTML="";for(const s of t){const r=document.createElement("option");r.value=s.src,r.textContent=this.observerDisplayName(this.plain(s).observer)??this.messages.unnamedObserver.replace("{n}",String(t.indexOf(s)+1)),this.observerSelect.appendChild(r)}const n=t.find(s=>s.src===this.currentSrc)??this.entryAsked(t)??t[0];n?this.selectObserver(n.src):this.updateAccountLine()}entryAsked(t){const e=this.getAttribute(Dl)?.trim();if(!e)return;const i=t.find(s=>this.plain(s).observer?.id===e);if(i)return i;const n=t.find(s=>s.src.split("/").pop()===e.split("/").pop());return n||(/^\d+$/.test(e)?t[Number(e)-1]:void 0)}observerKeyOf(t){return this.plain(t).observer?.id??String(this.entries.indexOf(t)+1)}sharedEntry(){const t=this.shareScope.value;if(!(!this.caseSource||t===Uu))return this.entries.find(e=>e.src===t)}get sharesCase(){return this.caseSource!==void 0&&!this.shareScopeRow.hidden&&this.shareScope.value===Uu}editorUrl(){if(!this.currentSrc)return Fu;const t=new URL(this.currentSrc,location.href),e=this.caseSource;return e?`${Fu}?file=${encodeURIComponent(e.url)}&track=${encodeURIComponent(this.shownTrackUrl()??t.href)}`:`${Fu}?file=${encodeURIComponent(t.href)}`}get editorHref(){return this.editorUrl()}shownTrackUrl(){const t=this.caseSource,e=this.entries.find(s=>s.src===this.currentSrc),i=/^case-(\d+)$/.exec(this.interpretationSelect.value);if(!t||!e||!i)return;const n=Qi.interpretationEvents(t.json,Qi.accountIds(t.json,t.url,e.src,this.plain(e).id))[Number(i[1])];return n?.url?new URL(n.url,t.url).href:void 0}embedMarkupFor(t){const e=t==="edit"?"rr0-sighting-editor":"rr0-sighting",i=new URL(`${e}.mjs`,import.meta.url).href,n=this.sharedAddress(),s=n.src,o=(t==="replay"?[...n.observer?[[Dl,n.observer]]:[],...this.replayAttributes()]:[]).map(([c,l])=>l===""?` ${c}`:` ${c}="${l}"`).join("");return`<script type="module" src="${i}"><\/script>
|
|
9124
|
-
<${e} src="${s}"${o}></${e}>`}refreshEmbedMarkup(){const t=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay");this.embedMarkup.value=t,this.shareCodeEditor&&(this.shareCodeEditor.text=t)}async copyText(t,e,i){try{await navigator.clipboard.writeText(t),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{e.select()}}async copyEmbedMarkup(){await this.copyText(this.shareCodeEditor?.text??this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){const t=this.sharedAddress(),e=[...t.observer?[`${Dl}=${encodeURIComponent(t.observer)}`]:[],...this.replayQuery()].join("&");return t.src?`${td}/play/?file=${encodeURIComponent(t.src)}${e&&"&"+e}`:`${td}/play/${e&&"?"+e}`}sharedAddress(){const t=e=>e?new URL(e,location.href).href:"";if(this.sharesCase){const e=this.entries.find(i=>i.src===this.shareOpens.value)??this.entries.find(i=>i.src===this.currentSrc);return{src:this.caseSource.url,observer:e?this.observerKeyOf(e):void 0}}return{src:t(this.sharedEntry()?.src??this.currentSrc??"")}}replayAttributes(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push([ip,String(this.shareStartSeconds)]),t.labels.input.checked&&e.push(["show-labels",""]),t.map.input.checked&&e.push([cr,""]),t.milestones.input.checked||e.push([lr,""]),t.compare.input.checked&&e.push([ku,""]),e}replayQuery(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push(`d=${this.shareStartSeconds}`),t.labels.input.checked||e.push("labels=0"),t.map.input.checked&&e.push("map=1"),t.milestones.input.checked||e.push("moments=0"),t.compare.input.checked&&e.push("compare=1"),e}get shareStartSeconds(){const t=Math.floor(Number(this.shareStart.value));return this.shareStartOn.checked&&Number.isFinite(t)&&t>=0?t:void 0}refreshShareLinks(){const t=this.embedEditRadio.checked;this.shareReplayOptions.disabled=t,this.shareOpensRow.hidden=!this.sharesCase;const e=this.sharedEntry();this.shareLink.value=t?e&&e.src!==this.currentSrc?`${Fu}?file=${encodeURIComponent(new URL(e.src,location.href).href)}`:this.editorUrl():this.playUrl(),this.fitShareLink(),this.refreshEmbedMarkup()}fitShareLink(){this.shareLink.style.height="auto",this.shareLink.style.height=`${this.shareLink.scrollHeight}px`}shareCodeEditor;shareCodeLoading;loadShareCode(){this.shareCodeLoading??=Xe(async()=>{const{ShareCodeEditor:t}=await import("./ShareCodeEditor-C53SBK2N.js");return{ShareCodeEditor:t}},[],import.meta.url).then(({ShareCodeEditor:t})=>{this.shareCodeEditor=new t(this.embedCode,this.embedMarkup.value,e=>{this.embedMarkup.value=e},this.messages.embed),this.embedMarkup.hidden=!0}).catch(()=>{this.shareCodeLoading=void 0})}openShare(){const t=this.sceneElement.ufoElement;this.shareStart.max=String(Math.floor(t.seekableDuration/1e3)),this.shareStart.value=String(Math.floor(t.currentTime/1e3)),this.shareStartOn.checked=!1,this.shareOptions.labels.input.checked=this.labelsShown,this.shareOptions.map.input.checked=t.observerMapOpen,this.shareOptions.milestones.input.checked=t.milestonesVisible,this.shareOptions.compare.input.checked=this.sceneElement.compareAccount,this.offerShareScope(),this.refreshShareLinks(),this.showShareView("link"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.fitShareLink(),this.shareLink.select()}offerShareScope(){const t=this.caseSource!==void 0&&this.entries.length>1;if(this.shareScopeRow.hidden=!t,this.shareScope.innerHTML="",this.shareOpens.innerHTML="",!t)return;const e=(i,n,s)=>{const r=document.createElement("option");r.value=n,r.textContent=s,i.appendChild(r)};e(this.shareScope,Uu,this.messages.shareScopeCase);for(const i of this.entries){const n=this.observerDisplayName(this.plain(i).observer)??this.messages.unnamedObserver.replace("{n}",String(this.entries.indexOf(i)+1));e(this.shareScope,i.src,n),e(this.shareOpens,i.src,n)}this.shareScope.value=Uu,this.shareOpens.value=this.currentSrc??this.entries[0].src}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(t){this.shareLinkBox.hidden=t!=="link",this.shareEmbed.hidden=t!=="embed",this.shareLinkOption.setAttribute("aria-pressed",String(t==="link")),this.shareEmbedOption.setAttribute("aria-pressed",String(t==="embed")),t==="embed"?this.loadShareCode():this.fitShareLink()}offerInterpretations(t){const e=this.offeredFor===t.sighting,i=this.interpretationSelect.value;this.offeredFor=t.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=t===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(np,this.messages.account,()=>Promise.resolve(s));const r=this.caseSource;r&&Qi.interpretationEvents(r.json,Qi.accountIds(r.json,r.url,t.src,this.plain(t).id)).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>Qi.interpretationOf(l,r.url,f=>Fl.json(f)))});const c=e&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:np;this.interpretationSelect.value=c,c===np?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(t){this.sceneElement.compareAccount=t,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const t=this.sceneElement.compareAccount;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(t));const e=t?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=e,this.compareButton.setAttribute("aria-label",e)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(t){const e=++this.interpretationToken,i=this.interpretationLoaders.get(t),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${t}":`,s)}):void 0;e===this.interpretationToken&&(this.sceneElement.interpretation=n,this.editLink.href=this.editorUrl(),this.dispatchEvent(new CustomEvent("interpretationchange",{detail:{track:this.shownTrackUrl()}})),this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(t){if("people"in t){const[e,...i]=t.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,e].join(" ")}return"org"in t?t.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.observerDisplayName(t)??""}showConfrontation(t){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;const e=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of t){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const r=[];n.separationDeg!==void 0&&r.push([this.messages.confrontationDirection.replace("{deg}",e.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&r.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&r.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),r.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}startPending=!1;startSeconds(t){const e=ln.clock(this.getAttribute(L2));return(e?ln.elapsedSince(this.plain(t).time,e):void 0)??ln.delta(this.getAttribute(ip))}selectObserver(t){const e=this.entries.find(n=>n.src===t);if(!e)return;this.currentSrc=t,this.observerSelect.value=t,this.sceneElement.documentUrl=e.src?new URL(e.src,location.href).href:void 0;const i=!this.sceneElement.ufoElement.playRequested;if(e.sighting.image?this.sceneElement.showPoster(e.sighting.image,e.src?new URL(e.src,location.href).href:void 0,i):this.sceneElement.showPoster(this.caseSource?.json.image,this.caseSource?.url,i),this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=e.sighting,this.startPending){this.startPending=!1;const n=this.startSeconds(e);n!==void 0&&(this.sceneElement.ufoElement.currentTime=Math.max(0,n)*1e3)}this.offerInterpretations(e),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(e8,{detail:{src:t}}))}async runAssessments(){const t=++this.assessmentToken,e=await new Bw(this.messages).read(this.sceneElement.ufoElement.sighting);t===this.assessmentToken&&(this.assessmentEntries=e.entries,this.refreshParamSummary())}updateAccountLine(){const t=this.entries.find(n=>n.src===this.currentSrc),e=t?this.observerDisplayName(this.plain(t).observer):void 0,i=e!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=e??"",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(t){if(!t)return;const e=[...t.firstNames??[],t.lastName].filter(Boolean).join(" ");return t.title||e||t.id}plainRecordings=new WeakMap;plain(t){return this.stripped(t).recording}stripped(t){let e=this.plainRecordings.get(t.sighting);return e||(e=Tn.strip(t.sighting),this.plainRecordings.set(t.sighting,e)),e}basisOf(t,e){const i=this.stripped(t).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(c=>e.some(l=>c===l||c.startsWith(`${l}.`))).map(c=>i.at(c)),r=s.reduce((c,l)=>n[l.basis]>n[c]?l.basis:c,"stated"),o=s.filter(c=>c.basis===r&&c.rationale).map(c=>c.rationale);return{basis:r,rationales:o}}formatDate(t){const e=t.place?.[0],i=Na(t.time??{},e?.lng??0,t.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(t,e?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(Bc.DATE_LOCALES[this.language],{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(t,e){return t.utcOffsetHours??Math.round(e/15)}formatLocation(t){const e=t.place?.[0];if(e)return`${e.lat.toFixed(4)}, ${e.lng.toFixed(4)}`}toggleInfoPanel(){const t=!this.infoOpen;if(this.supportsPopover){const e=this.infoPanel.matches(":popover-open");t&&!e?this.infoPanel.showPopover():!t&&e&&this.infoPanel.hidePopover();return}t&&this.bringInfoButtonIntoView(),this.syncInfoOpen(t),this.infoPanel.hidden=!t,t?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const t=this.infoButton.getBoundingClientRect(),e=window.innerHeight||document.documentElement.clientHeight;t.top>=0&&t.bottom<=e||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(t){t!==this.infoOpen&&(this.infoOpen=t,this.infoButton.setAttribute("aria-expanded",String(t)),t?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=t=>{const e=t.composedPath();!e.includes(this.infoPanel)&&!e.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(t){t.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(t){this.toggleAttribute("show-labels",t)}applyLabels(t){this.labelsShown=t,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 t=this.sceneElement.ufoElement.sighting,e=[...this.summaryBuilder.entriesFor(t,this.sceneElement.ufoElement.currentTime,{roadGradeDeg:this.sceneElement.roadGradeDeg}),...this.assessmentEntries],i=e.map(r=>`${r.field}=${r.label}=${r.value}${r.unit}${r.full??""}${r.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const r of e){s&&s.group!==r.group&&(s=void 0);const o=r.group==="summary"?this.messages.summaryGroup:r.group==="observer"?this.messages.observerGroup:r.group in this.messages.summaryGroups?this.messages.summaryGroups[r.group]:r.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),s={group:r.group,element:l},n.push(l)}const c=this.paramItem(r);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n),this.syncDescription(e)}openDescription;syncDescription(t){this.openDescription!==void 0&&!t.some(e=>e.full===this.openDescription)&&(this.openDescription=void 0),U2.sync(this.paramSummary,this.openDescription,this.messages.summaryDescription,this.messages.closeDescription,()=>{this.openDescription=void 0,this.syncDescription(t)})}paramItem(t){const e=document.createElement("span");if(e.className=t.fromSource?"param-label from-source":"param-label",t.full!==void 0){e.classList.add("describable"),e.tabIndex=0,e.setAttribute("role","button");const s=()=>{this.openDescription=t.full,this.syncDescription([t])};e.addEventListener("click",s),e.addEventListener("keydown",r=>{(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),s())})}const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${t.label} `,e.append(i),t.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=t.color,e.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=t.unit===""?t.value:`${t.value} ${t.unit}`,e.append(n),e}populateInfoPanel(){const t=this.entries.find(e=>e.src===this.currentSrc);if(this.infoObservationList.innerHTML="",t){const e=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(e&&this.appendInfoRow(this.infoObservationList,this.messages.case,e),!this.labelsShown){const s=this.formatDate(this.plain(t));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(t,Bc.DATE_PATHS));const r=this.formatLocation(this.plain(t));r&&this.appendInfoRow(this.infoObservationList,this.messages.location,r,this.basisOf(t,Bc.PLACE_PATHS))}const i=this.said.read(this.plain(t).description);i&&!this.labelsShown&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(t).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(t).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=td,this.infoAppLink.textContent="UFO@home v0.127.0",on.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(t,e,i){const n=document.createElement("dt");n.textContent=e;const s=document.createElement("dd"),r=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const c=document.createElement("a");c.href=i.url,c.target="_blank",c.rel="noopener noreferrer",c.textContent=r,s.appendChild(c)}else s.append(r);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),t.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(t,e,i,n){const s=document.createElement("dt");s.textContent=e;const r=document.createElement("dd");if(r.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(`
|
|
9141
|
+
<${e} src="${s}"${o}></${e}>`}refreshEmbedMarkup(){const t=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay");this.embedMarkup.value=t,this.shareCodeEditor&&(this.shareCodeEditor.text=t)}async copyText(t,e,i){try{await navigator.clipboard.writeText(t),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{e.select()}}async copyEmbedMarkup(){await this.copyText(this.shareCodeEditor?.text??this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){const t=this.sharedAddress(),e=[...t.observer?[`${Dl}=${encodeURIComponent(t.observer)}`]:[],...this.replayQuery()].join("&");return t.src?`${td}/play/?file=${encodeURIComponent(t.src)}${e&&"&"+e}`:`${td}/play/${e&&"?"+e}`}sharedAddress(){const t=e=>e?new URL(e,location.href).href:"";if(this.sharesCase){const e=this.entries.find(i=>i.src===this.shareOpens.value)??this.entries.find(i=>i.src===this.currentSrc);return{src:this.caseSource.url,observer:e?this.observerKeyOf(e):void 0}}return{src:t(this.sharedEntry()?.src??this.currentSrc??"")}}replayAttributes(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push([ip,String(this.shareStartSeconds)]),t.labels.input.checked&&e.push(["show-labels",""]),t.map.input.checked&&e.push([cr,""]),t.milestones.input.checked||e.push([lr,""]),t.compare.input.checked&&e.push([ku,""]),e}replayQuery(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push(`d=${this.shareStartSeconds}`),t.labels.input.checked||e.push("labels=0"),t.map.input.checked&&e.push("map=1"),t.milestones.input.checked||e.push("moments=0"),t.compare.input.checked&&e.push("compare=1"),e}get shareStartSeconds(){const t=Math.floor(Number(this.shareStart.value));return this.shareStartOn.checked&&Number.isFinite(t)&&t>=0?t:void 0}refreshShareLinks(){const t=this.embedEditRadio.checked;this.shareReplayOptions.disabled=t,this.shareOpensRow.hidden=!this.sharesCase;const e=this.sharedEntry();this.shareLink.value=t?e&&e.src!==this.currentSrc?`${Fu}?file=${encodeURIComponent(new URL(e.src,location.href).href)}`:this.editorUrl():this.playUrl(),this.fitShareLink(),this.refreshEmbedMarkup()}fitShareLink(){this.shareLink.style.height="auto",this.shareLink.style.height=`${this.shareLink.scrollHeight}px`}shareCodeEditor;shareCodeLoading;loadShareCode(){this.shareCodeLoading??=Xe(async()=>{const{ShareCodeEditor:t}=await import("./ShareCodeEditor-C53SBK2N.js");return{ShareCodeEditor:t}},[],import.meta.url).then(({ShareCodeEditor:t})=>{this.shareCodeEditor=new t(this.embedCode,this.embedMarkup.value,e=>{this.embedMarkup.value=e},this.messages.embed),this.embedMarkup.hidden=!0}).catch(()=>{this.shareCodeLoading=void 0})}openShare(){const t=this.sceneElement.ufoElement;this.shareStart.max=String(Math.floor(t.seekableDuration/1e3)),this.shareStart.value=String(Math.floor(t.currentTime/1e3)),this.shareStartOn.checked=!1,this.shareOptions.labels.input.checked=this.labelsShown,this.shareOptions.map.input.checked=t.observerMapOpen,this.shareOptions.milestones.input.checked=t.milestonesVisible,this.shareOptions.compare.input.checked=this.sceneElement.compareAccount,this.offerShareScope(),this.refreshShareLinks(),this.showShareView("link"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.fitShareLink(),this.shareLink.select()}offerShareScope(){const t=this.caseSource!==void 0&&this.entries.length>1;if(this.shareScopeRow.hidden=!t,this.shareScope.innerHTML="",this.shareOpens.innerHTML="",!t)return;const e=(i,n,s)=>{const r=document.createElement("option");r.value=n,r.textContent=s,i.appendChild(r)};e(this.shareScope,Uu,this.messages.shareScopeCase);for(const i of this.entries){const n=this.observerDisplayName(this.plain(i).observer)??this.messages.unnamedObserver.replace("{n}",String(this.entries.indexOf(i)+1));e(this.shareScope,i.src,n),e(this.shareOpens,i.src,n)}this.shareScope.value=Uu,this.shareOpens.value=this.currentSrc??this.entries[0].src}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(t){this.shareLinkBox.hidden=t!=="link",this.shareEmbed.hidden=t!=="embed",this.shareLinkOption.setAttribute("aria-pressed",String(t==="link")),this.shareEmbedOption.setAttribute("aria-pressed",String(t==="embed")),t==="embed"?this.loadShareCode():this.fitShareLink()}offerInterpretations(t){const e=this.offeredFor===t.sighting,i=this.interpretationSelect.value;this.offeredFor=t.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=t===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(np,this.messages.account,()=>Promise.resolve(s));const r=this.caseSource;r&&Qi.interpretationEvents(r.json,Qi.accountIds(r.json,r.url,t.src,this.plain(t).id)).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>Qi.interpretationOf(l,r.url,f=>Fl.json(f)))});const c=e&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:np;this.interpretationSelect.value=c,c===np?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(t){this.sceneElement.compareAccount=t,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const t=this.sceneElement.compareAccount;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(t));const e=t?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=e,this.compareButton.setAttribute("aria-label",e)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(t){const e=++this.interpretationToken,i=this.interpretationLoaders.get(t),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${t}":`,s)}):void 0;e===this.interpretationToken&&(this.sceneElement.interpretation=n,this.editLink.href=this.editorUrl(),this.dispatchEvent(new CustomEvent("interpretationchange",{detail:{track:this.shownTrackUrl()}})),this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(t){if("people"in t){const[e,...i]=t.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,e].join(" ")}return"org"in t?t.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.observerDisplayName(t)??""}showConfrontation(t){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;const e=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of t){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const r=[];n.separationDeg!==void 0&&r.push([this.messages.confrontationDirection.replace("{deg}",e.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&r.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&r.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),r.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}startPending=!1;startSeconds(t){const e=ln.clock(this.getAttribute(L2));return(e?ln.elapsedSince(this.plain(t).time,e):void 0)??ln.delta(this.getAttribute(ip))}selectObserver(t){const e=this.entries.find(n=>n.src===t);if(!e)return;this.currentSrc=t,this.observerSelect.value=t,this.sceneElement.documentUrl=e.src?new URL(e.src,location.href).href:void 0;const i=!this.sceneElement.ufoElement.playRequested;if(e.sighting.image?this.sceneElement.showPoster(e.sighting.image,e.src?new URL(e.src,location.href).href:void 0,i):this.sceneElement.showPoster(this.caseSource?.json.image,this.caseSource?.url,i),this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=e.sighting,this.startPending){this.startPending=!1;const n=this.startSeconds(e);n!==void 0&&(this.sceneElement.ufoElement.currentTime=Math.max(0,n)*1e3)}this.offerInterpretations(e),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(e8,{detail:{src:t}}))}async runAssessments(){const t=++this.assessmentToken,e=await new Bw(this.messages).read(this.sceneElement.ufoElement.sighting);t===this.assessmentToken&&(this.assessmentEntries=e.entries,this.refreshParamSummary())}updateAccountLine(){const t=this.entries.find(n=>n.src===this.currentSrc),e=t?this.observerDisplayName(this.plain(t).observer):void 0,i=e!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=e??"",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(t){if(!t)return;const e=[...t.firstNames??[],t.lastName].filter(Boolean).join(" ");return t.title||e||t.id}plainRecordings=new WeakMap;plain(t){return this.stripped(t).recording}stripped(t){let e=this.plainRecordings.get(t.sighting);return e||(e=Tn.strip(t.sighting),this.plainRecordings.set(t.sighting,e)),e}basisOf(t,e){const i=this.stripped(t).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(c=>e.some(l=>c===l||c.startsWith(`${l}.`))).map(c=>i.at(c)),r=s.reduce((c,l)=>n[l.basis]>n[c]?l.basis:c,"stated"),o=s.filter(c=>c.basis===r&&c.rationale).map(c=>c.rationale);return{basis:r,rationales:o}}formatDate(t){const e=t.place?.[0],i=Na(t.time??{},e?.lng??0,t.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(t,e?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(Bc.DATE_LOCALES[this.language],{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(t,e){return t.utcOffsetHours??Math.round(e/15)}formatLocation(t){const e=t.place?.[0];if(e)return`${e.lat.toFixed(4)}, ${e.lng.toFixed(4)}`}toggleInfoPanel(){const t=!this.infoOpen;if(this.supportsPopover){const e=this.infoPanel.matches(":popover-open");t&&!e?this.infoPanel.showPopover():!t&&e&&this.infoPanel.hidePopover();return}t&&this.bringInfoButtonIntoView(),this.syncInfoOpen(t),this.infoPanel.hidden=!t,t?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const t=this.infoButton.getBoundingClientRect(),e=window.innerHeight||document.documentElement.clientHeight;t.top>=0&&t.bottom<=e||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(t){t!==this.infoOpen&&(this.infoOpen=t,this.infoButton.setAttribute("aria-expanded",String(t)),t?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=t=>{const e=t.composedPath();!e.includes(this.infoPanel)&&!e.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(t){t.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(t){this.toggleAttribute("show-labels",t)}applyLabels(t){this.labelsShown=t,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 t=this.sceneElement.ufoElement.sighting,e=[...this.summaryBuilder.entriesFor(t,this.sceneElement.ufoElement.currentTime,{roadGradeDeg:this.sceneElement.roadGradeDeg}),...this.assessmentEntries],i=e.map(r=>`${r.field}=${r.label}=${r.value}${r.unit}${r.full??""}${r.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const r of e){s&&s.group!==r.group&&(s=void 0);const o=r.group==="summary"?this.messages.summaryGroup:r.group==="observer"?this.messages.observerGroup:r.group in this.messages.summaryGroups?this.messages.summaryGroups[r.group]:r.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),s={group:r.group,element:l},n.push(l)}const c=this.paramItem(r);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n),this.syncDescription(e)}openDescription;syncDescription(t){this.openDescription!==void 0&&!t.some(e=>e.full===this.openDescription)&&(this.openDescription=void 0),U2.sync(this.paramSummary,this.openDescription,this.messages.summaryDescription,this.messages.closeDescription,()=>{this.openDescription=void 0,this.syncDescription(t)})}paramItem(t){const e=document.createElement("span");if(e.className=t.fromSource?"param-label from-source":"param-label",t.full!==void 0){e.classList.add("describable"),e.tabIndex=0,e.setAttribute("role","button");const s=()=>{this.openDescription=t.full,this.syncDescription([t])};e.addEventListener("click",s),e.addEventListener("keydown",r=>{(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),s())})}const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${t.label} `,e.append(i),t.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=t.color,e.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=t.unit===""?t.value:`${t.value} ${t.unit}`,e.append(n),e}populateInfoPanel(){const t=this.entries.find(e=>e.src===this.currentSrc);if(this.infoObservationList.innerHTML="",t){const e=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(e&&this.appendInfoRow(this.infoObservationList,this.messages.case,e),!this.labelsShown){const s=this.formatDate(this.plain(t));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(t,Bc.DATE_PATHS));const r=this.formatLocation(this.plain(t));r&&this.appendInfoRow(this.infoObservationList,this.messages.location,r,this.basisOf(t,Bc.PLACE_PATHS))}const i=this.said.read(this.plain(t).description);i&&!this.labelsShown&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(t).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(t).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=td,this.infoAppLink.textContent="UFO@home v0.127.2",on.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(t,e,i){const n=document.createElement("dt");n.textContent=e;const s=document.createElement("dd"),r=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const c=document.createElement("a");c.href=i.url,c.target="_blank",c.rel="noopener noreferrer",c.textContent=r,s.appendChild(c)}else s.append(r);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),t.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(t,e,i,n){const s=document.createElement("dt");s.textContent=e;const r=document.createElement("dd");if(r.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(`
|
|
9125
9142
|
`)),r.append(" ",o)}t.appendChild(s),t.appendChild(r)}}const N2="rr0-sighting",e8="observerchange",k2="rr0-eyeobserver";class i8 extends Bc{}function n8(){eb(),customElements.get(N2)||customElements.define(N2,Bc),customElements.get(k2)||customElements.define(k2,i8)}n8();export{s8 as $,ho as A,re as B,nt as C,dc as D,Qn as E,se as F,Ie as G,$u as H,v8 as I,Gr as J,fl as K,op as L,J3 as M,Cn as N,In as O,Zp as P,m8 as Q,Ee as R,eh as S,ds as T,q3 as U,bs as V,d8 as W,Mo as X,$i as Y,F6 as Z,Ng as _,_n as a,a8 as a0,r8 as a1,Sh as a2,g8 as a3,f8 as a4,Od as a5,en as a6,ex as a7,zv as a8,l8 as a9,o3 as aA,bC as aB,Id as aC,qp as aD,sn as aE,Qy as aF,ug as aG,dg as aH,Te as aI,wa as aJ,wh as aK,Vn as aa,fv as ab,ui as ac,p8 as ad,M8 as ae,Ny as af,hr as ag,Nh as ah,Nf as ai,oE as aj,ge as ak,Ke as al,wo as am,vp as an,_i as ao,Mr as ap,f3 as aq,We as ar,c8 as as,h8 as at,Fy as au,u8 as av,Bn as aw,Ps as ax,Uy as ay,Pv as az,xt as b,bu as c,st as d,Yl as e,fa as f,ue as g,oe as h,vs as i,y8 as j,kd as k,is as l,nn as m,Hr as n,R as o,rS as p,De as q,or as r,Na as s,qs as t,Mt as u,ye as v,x8 as w,ce as x,o8 as y,bS as z};
|