@rr0/ufoathome 0.121.0 → 0.123.0

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.
Files changed (46) hide show
  1. package/README.md +3 -2
  2. package/dist-embed-interview/InterviewMessages_es-D5d2JVA3.js +1 -0
  3. package/dist-embed-interview/InterviewMessages_fr-CmScqfza.js +1 -0
  4. package/dist-embed-interview/InterviewMessages_it-2SNw5xMp.js +1 -0
  5. package/dist-embed-interview/rr0-interview.mjs +34 -0
  6. package/dist-embed-scene/rr0-scene.mjs +2 -2
  7. package/dist-embed-sighting/rr0-sighting.mjs +27 -27
  8. package/dist-embed-sighting-editor/{AdsbLolArchiveProvider-fy3504GB.js → AdsbLolArchiveProvider-CDtWnd9O.js} +1 -1
  9. package/dist-embed-sighting-editor/{BodyEditor-CzR-jvO7.js → BodyEditor-ChwDW_Ws.js} +1 -1
  10. package/dist-embed-sighting-editor/CaseEditorMessages_es-CNLEMPjy.js +1 -0
  11. package/dist-embed-sighting-editor/CaseEditorMessages_fr-DN3xxn9o.js +1 -0
  12. package/dist-embed-sighting-editor/CaseEditorMessages_it-B6aG-baK.js +1 -0
  13. package/dist-embed-sighting-editor/{ContrailSystem-DPqcSIVY.js → ContrailSystem-C1ugmbHe.js} +1 -1
  14. package/dist-embed-sighting-editor/{CoverageAssessor-Cvcqlzqm.js → CoverageAssessor-CmEo7iZm.js} +1 -1
  15. package/dist-embed-sighting-editor/GLTFLoader-C8s-rYg8.js +1 -0
  16. package/dist-embed-sighting-editor/HeadlightSystem-NhpS6K9T.js +34 -0
  17. package/dist-embed-sighting-editor/{HynekAssessor-EGYF4GLv.js → HynekAssessor-BzyMfAGm.js} +1 -1
  18. package/dist-embed-sighting-editor/InterviewEditorElement-CT26rBmp.js +101 -0
  19. package/dist-embed-sighting-editor/InterviewMedia-CvAxC62V.js +1 -0
  20. package/dist-embed-sighting-editor/InterviewMessages_en-cs-wWpmz.js +1 -0
  21. package/dist-embed-sighting-editor/InterviewMessages_es-D5d2JVA3.js +1 -0
  22. package/dist-embed-sighting-editor/InterviewMessages_fr-CmScqfza.js +1 -0
  23. package/dist-embed-sighting-editor/InterviewMessages_it-2SNw5xMp.js +1 -0
  24. package/dist-embed-sighting-editor/{LaunchEditor-V2d95SPb.js → LaunchEditor-BCbplrLt.js} +1 -1
  25. package/dist-embed-sighting-editor/{ModelSource-BsUEhu3K.js → ModelSource-C3dP1aBw.js} +1 -1
  26. package/dist-embed-sighting-editor/{ModelThumbnails-Bxh0kDEJ.js → ModelThumbnails-B2MXsKrk.js} +1 -1
  27. package/dist-embed-sighting-editor/{ModelViewer-8GDjRszL.js → ModelViewer-BltV6g37.js} +1 -1
  28. package/dist-embed-sighting-editor/{RoadMarkings-DgTkyJ3L.js → RoadMarkings-B3u94pIv.js} +1 -1
  29. package/dist-embed-sighting-editor/{TraceSystem-B432m_Cj.js → TraceSystem-CZFR0soj.js} +2 -2
  30. package/dist-embed-sighting-editor/interviewImport-C-TiARLK.js +4 -0
  31. package/dist-embed-sighting-editor/interviewJson-CfwBPiuG.js +8 -0
  32. package/dist-embed-sighting-editor/interviewSchema-CMRZUnRy.js +1 -0
  33. package/dist-embed-sighting-editor/rr0-sighting-editor.mjs +341 -364
  34. package/dist-embed-sighting-editor/surroundingsSources-CvhFXPJx.js +1 -0
  35. package/dist-embed-sighting-editor/{trafficRuntime-j3m3LpCc.js → trafficRuntime-XVgt3vom.js} +2 -2
  36. package/package.json +10 -6
  37. package/dist-embed-sighting-editor/CaseEditorMessages_es-D73IC39g.js +0 -1
  38. package/dist-embed-sighting-editor/CaseEditorMessages_fr-Ct3RkRag.js +0 -1
  39. package/dist-embed-sighting-editor/CaseEditorMessages_it-DLJsrUtH.js +0 -1
  40. package/dist-embed-sighting-editor/GLTFLoader-7CUTWiMy.js +0 -1
  41. package/dist-embed-sighting-editor/HeadlightSystem-BSokhsgi.js +0 -34
  42. package/dist-embed-sighting-editor/InterviewMessages_es-TjWn41kX.js +0 -1
  43. package/dist-embed-sighting-editor/InterviewMessages_fr-BY_iezXh.js +0 -1
  44. package/dist-embed-sighting-editor/InterviewMessages_it-DkQ8uaNR.js +0 -1
  45. package/dist-embed-sighting-editor/interviewSchema-DcJWoqJZ.js +0 -1
  46. package/dist-embed-sighting-editor/surroundingsSources-CCnNDL0o.js +0 -1
@@ -1 +1 @@
1
- import{h as M,i as y,f as I}from"./rr0-sighting-editor.mjs";class d{static RECORD_BYTES=20;static NON_ICAO_FLAG=1<<24;static UNKNOWN=65535;static MAX_DT=35999;static decode(t){if(t.length%d.RECORD_BYTES!==0)throw new Error(`An aircraft tile is a multiple of ${d.RECORD_BYTES} bytes, not ${t.length}`);const e=new DataView(t.buffer,t.byteOffset,t.byteLength),c=[];for(let n=0;n<t.length;n+=d.RECORD_BYTES){const a=e.getUint32(n,!0),s=e.getUint16(n+16,!0),r=e.getUint16(n+18,!0);c.push({icao:a&16777215,nonIcao:(a&d.NON_ICAO_FLAG)!==0,secondsInHour:e.getUint16(n+4,!0)/10,lat:e.getInt32(n+6,!0)/1e5,lng:e.getInt32(n+10,!0)/1e5,altitudeFt:e.getInt16(n+14,!0)*25,groundSpeedKt:s===d.UNKNOWN?void 0:s/10,trackDeg:r===d.UNKNOWN?void 0:r/10})}return c}}const w="https://ufoathome.org/aircraft/index.json";class f{citation=M;static DEFAULT_RADIUS_KM=150;static FLAG_MILITARY=1;static FLAG_PIA=4;static FLAG_LADD=8;static KM_PER_DEG=111.32;static HOUR_MS=36e5;fetchImpl;indexUrls;index;hours=new Map;tiles=new Map;shards=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??f.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/aircraft/index.json",location.href).href),t.includes(w)||t.push(w),t}mayCover(t){return y.mayCover(t)}async between(t,e,c,n=f.DEFAULT_RADIUS_KM){const a=await this.loadIndex();if(!a)return{status:"failed"};const s=[];for(let o=Math.floor(e/f.HOUR_MS);o<=Math.floor(c/f.HOUR_MS);o++)s.push(o);if(!s.every(o=>a.index.days.includes(f.dayOf(o))))return{status:"outside"};const r=f.tilesAround(t,n);try{const o=(await Promise.all(s.flatMap(u=>r.map(i=>this.tileOf(a.base,u,i))))).flat();return{status:"found",tracks:f.merge(o,t,e,c,n)}}catch{return{status:"failed"}}}async describe(t,e){const c=await this.loadIndex();if(!c)return;const n=t.icao.toString(16).padStart(6,"0"),a=t.nonIcao?"non-icao":n.slice(0,2),s=`${e}/${a}`;let r=this.shards.get(s);r||(r=this.fetchImpl(new URL(`${e}/aircraft/${a}.json`,c.base).href).then(g=>g.ok?g.json():{}).catch(()=>({})),this.shards.set(s,r));const o=(await r)[t.nonIcao?`~${n}`:n];if(!o)return;const[u,i,l,h=0]=o,p={registration:u||void 0,type:i||void 0,category:l||void 0,military:(h&f.FLAG_MILITARY)!==0||void 0,restricted:(h&(f.FLAG_PIA|f.FLAG_LADD))!==0||void 0};return Object.values(p).some(g=>g!==void 0)?p:void 0}static tilesAround(t,e){const c=e/f.KM_PER_DEG,n=Math.max(-90,t.lat-c),a=Math.min(90,t.lat+c),s=Math.cos(Math.max(Math.abs(n),Math.abs(a))*Math.PI/180),r=s<1e-6?180:e/(f.KM_PER_DEG*s),o=new Set;if(r>=180)for(let i=-180;i<180;i++)o.add(i);else for(let i=Math.floor(t.lng-r);i<=Math.floor(t.lng+r);i++)o.add(I.wrapLongitude(i));const u=[];for(let i=Math.floor(n);i<=Math.min(89,Math.floor(a));i++)for(const l of o)u.push(`${i}_${l}`);return u}static dayOf(t){return new Date(t*f.HOUR_MS).toISOString().slice(0,10)}static merge(t,e,c,n,a){const s=new Map;for(const o of t){const u=o.points.filter(h=>h.t>=c&&h.t<=n&&I.groundDistanceKm(e,h)<=a);if(u.length===0)continue;const i=`${o.nonIcao?"~":""}${o.icao}`,l=s.get(i);l?l.points.push(...u):s.set(i,{icao:o.icao,nonIcao:o.nonIcao,points:u})}const r=[...s.values()];for(const o of r)o.points.sort((u,i)=>u.t-i.t);return r.sort((o,u)=>o.icao-u.icao)}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}tileOf(t,e,c){const n=f.dayOf(e),a=String(e%24).padStart(2,"0"),s=`${n}/${a}/${c}`;let r=this.tiles.get(s);return r||(r=this.hourIndex(t,n,a).then(async o=>{const u=o[c];if(!u)return[];const[i,l]=u,h=await this.fetchImpl(new URL(`${n}/${a}.pack`,t).href,{headers:{Range:`bytes=${i}-${i+l-1}`}});if(!h.ok)throw new Error(`The pack of ${n} ${a} h answered ${h.status}`);const p=new Uint8Array(await h.arrayBuffer()),g=h.status===206?p:p.subarray(i,i+l);return f.tracksOf(await f.gunzip(g),e)}),r.catch(()=>this.tiles.delete(s)),this.tiles.set(s,r)),r}hourIndex(t,e,c){const n=`${e}/${c}`;let a=this.hours.get(n);return a||(a=this.fetchImpl(new URL(`${e}/${c}.json`,t).href).then(s=>{if(s.status===404)return{};if(!s.ok)throw new Error(`The index of ${e} ${c} h answered ${s.status}`);return s.json()}),a.catch(()=>this.hours.delete(n)),this.hours.set(n,a)),a}static async gunzip(t){const e=new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}static tracksOf(t,e){const c=new Map;for(const n of d.decode(t)){const a=`${n.nonIcao?"~":""}${n.icao}`;let s=c.get(a);s||c.set(a,s={icao:n.icao,nonIcao:n.nonIcao,points:[]}),s.points.push({t:e*f.HOUR_MS+n.secondsInHour*1e3,lat:n.lat,lng:n.lng,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg})}return[...c.values()]}}export{f as AdsbLolArchiveProvider,w as UFOATHOME_AIRCRAFT_INDEX_URL};
1
+ import{o as M,p as y,m as I}from"./rr0-sighting-editor.mjs";class d{static RECORD_BYTES=20;static NON_ICAO_FLAG=1<<24;static UNKNOWN=65535;static MAX_DT=35999;static decode(t){if(t.length%d.RECORD_BYTES!==0)throw new Error(`An aircraft tile is a multiple of ${d.RECORD_BYTES} bytes, not ${t.length}`);const e=new DataView(t.buffer,t.byteOffset,t.byteLength),c=[];for(let n=0;n<t.length;n+=d.RECORD_BYTES){const a=e.getUint32(n,!0),s=e.getUint16(n+16,!0),r=e.getUint16(n+18,!0);c.push({icao:a&16777215,nonIcao:(a&d.NON_ICAO_FLAG)!==0,secondsInHour:e.getUint16(n+4,!0)/10,lat:e.getInt32(n+6,!0)/1e5,lng:e.getInt32(n+10,!0)/1e5,altitudeFt:e.getInt16(n+14,!0)*25,groundSpeedKt:s===d.UNKNOWN?void 0:s/10,trackDeg:r===d.UNKNOWN?void 0:r/10})}return c}}const w="https://ufoathome.org/aircraft/index.json";class f{citation=M;static DEFAULT_RADIUS_KM=150;static FLAG_MILITARY=1;static FLAG_PIA=4;static FLAG_LADD=8;static KM_PER_DEG=111.32;static HOUR_MS=36e5;fetchImpl;indexUrls;index;hours=new Map;tiles=new Map;shards=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??f.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/aircraft/index.json",location.href).href),t.includes(w)||t.push(w),t}mayCover(t){return y.mayCover(t)}async between(t,e,c,n=f.DEFAULT_RADIUS_KM){const a=await this.loadIndex();if(!a)return{status:"failed"};const s=[];for(let o=Math.floor(e/f.HOUR_MS);o<=Math.floor(c/f.HOUR_MS);o++)s.push(o);if(!s.every(o=>a.index.days.includes(f.dayOf(o))))return{status:"outside"};const r=f.tilesAround(t,n);try{const o=(await Promise.all(s.flatMap(u=>r.map(i=>this.tileOf(a.base,u,i))))).flat();return{status:"found",tracks:f.merge(o,t,e,c,n)}}catch{return{status:"failed"}}}async describe(t,e){const c=await this.loadIndex();if(!c)return;const n=t.icao.toString(16).padStart(6,"0"),a=t.nonIcao?"non-icao":n.slice(0,2),s=`${e}/${a}`;let r=this.shards.get(s);r||(r=this.fetchImpl(new URL(`${e}/aircraft/${a}.json`,c.base).href).then(g=>g.ok?g.json():{}).catch(()=>({})),this.shards.set(s,r));const o=(await r)[t.nonIcao?`~${n}`:n];if(!o)return;const[u,i,l,h=0]=o,p={registration:u||void 0,type:i||void 0,category:l||void 0,military:(h&f.FLAG_MILITARY)!==0||void 0,restricted:(h&(f.FLAG_PIA|f.FLAG_LADD))!==0||void 0};return Object.values(p).some(g=>g!==void 0)?p:void 0}static tilesAround(t,e){const c=e/f.KM_PER_DEG,n=Math.max(-90,t.lat-c),a=Math.min(90,t.lat+c),s=Math.cos(Math.max(Math.abs(n),Math.abs(a))*Math.PI/180),r=s<1e-6?180:e/(f.KM_PER_DEG*s),o=new Set;if(r>=180)for(let i=-180;i<180;i++)o.add(i);else for(let i=Math.floor(t.lng-r);i<=Math.floor(t.lng+r);i++)o.add(I.wrapLongitude(i));const u=[];for(let i=Math.floor(n);i<=Math.min(89,Math.floor(a));i++)for(const l of o)u.push(`${i}_${l}`);return u}static dayOf(t){return new Date(t*f.HOUR_MS).toISOString().slice(0,10)}static merge(t,e,c,n,a){const s=new Map;for(const o of t){const u=o.points.filter(h=>h.t>=c&&h.t<=n&&I.groundDistanceKm(e,h)<=a);if(u.length===0)continue;const i=`${o.nonIcao?"~":""}${o.icao}`,l=s.get(i);l?l.points.push(...u):s.set(i,{icao:o.icao,nonIcao:o.nonIcao,points:u})}const r=[...s.values()];for(const o of r)o.points.sort((u,i)=>u.t-i.t);return r.sort((o,u)=>o.icao-u.icao)}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}tileOf(t,e,c){const n=f.dayOf(e),a=String(e%24).padStart(2,"0"),s=`${n}/${a}/${c}`;let r=this.tiles.get(s);return r||(r=this.hourIndex(t,n,a).then(async o=>{const u=o[c];if(!u)return[];const[i,l]=u,h=await this.fetchImpl(new URL(`${n}/${a}.pack`,t).href,{headers:{Range:`bytes=${i}-${i+l-1}`}});if(!h.ok)throw new Error(`The pack of ${n} ${a} h answered ${h.status}`);const p=new Uint8Array(await h.arrayBuffer()),g=h.status===206?p:p.subarray(i,i+l);return f.tracksOf(await f.gunzip(g),e)}),r.catch(()=>this.tiles.delete(s)),this.tiles.set(s,r)),r}hourIndex(t,e,c){const n=`${e}/${c}`;let a=this.hours.get(n);return a||(a=this.fetchImpl(new URL(`${e}/${c}.json`,t).href).then(s=>{if(s.status===404)return{};if(!s.ok)throw new Error(`The index of ${e} ${c} h answered ${s.status}`);return s.json()}),a.catch(()=>this.hours.delete(n)),this.hours.set(n,a)),a}static async gunzip(t){const e=new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}static tracksOf(t,e){const c=new Map;for(const n of d.decode(t)){const a=`${n.nonIcao?"~":""}${n.icao}`;let s=c.get(a);s||c.set(a,s={icao:n.icao,nonIcao:n.nonIcao,points:[]}),s.points.push({t:e*f.HOUR_MS+n.secondsInHour*1e3,lat:n.lat,lng:n.lng,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg})}return[...c.values()]}}export{f as AdsbLolArchiveProvider,w as UFOATHOME_AIRCRAFT_INDEX_URL};
@@ -1,4 +1,4 @@
1
- import{U as A,l as z,B as u,E as f,P as M,b as v}from"./rr0-sighting-editor.mjs";import{bodyEditorMessages_en as k}from"./BodyEditorMessages_en-C3VGB1gD.js";class m{static before(e,o){const t=[...e.track].sort((s,n)=>s.t-n.t);return[...t].reverse().find(s=>s.t<=o)??t[0]}static viewOf(e,o,t){const s=m.before(e,o),n=i=>Number(i.toFixed(2));return{mode:s?.eastM!==void 0&&s.northM!==void 0?"world":"observer",azimuthDeg:n(t.azimuthDeg),elevationDeg:n(t.altitudeDeg),distanceM:n(t.distanceM),eastM:n(t.eastM),northM:n(t.northM),aboveGroundM:n(t.aboveGroundM),onGround:s?.onGround===!0,widthM:n(t.sizeM.widthM),lengthM:n(t.sizeM.lengthM),heightM:n(t.sizeM.heightM),headingDeg:n(t.attitude.headingDeg),pitchDeg:n(t.attitude.pitchDeg),rollDeg:n(t.attitude.rollDeg),color:t.appearance.color,albedo:n(t.appearance.albedo),luminanceCdM2:n(t.appearance.luminanceCdM2),transparency:n(t.appearance.transparency??0),haloScale:n(t.appearance.haloScale??1)}}static keyframeOf(e,o,t,s){const n=r=>Number.isFinite(r)?r:0,i=e.mode==="world"?{t:o,eastM:n(e.eastM),northM:n(e.northM),...e.onGround?{onGround:!0}:{altitudeAboveGroundM:n(e.aboveGroundM)}}:{t:o,azimuthDeg:n(e.azimuthDeg),altitudeDeg:n(e.elevationDeg),distanceM:Math.max(.1,n(e.distanceM)),...e.onGround?{onGround:!0}:{}},d=s?{color:e.color,albedo:Math.max(0,Math.min(1,n(e.albedo))),luminanceCdM2:Math.max(0,n(e.luminanceCdM2)),transparency:Math.max(0,Math.min(1,n(e.transparency))),haloScale:Math.max(0,n(e.haloScale))}:t?.appearance;return{...m.withoutPlacement(t),...i,sizeM:{widthM:Math.max(.01,n(e.widthM)),lengthM:Math.max(.01,n(e.lengthM)),heightM:Math.max(.01,n(e.heightM))},attitude:{headingDeg:n(e.headingDeg),pitchDeg:n(e.pitchDeg),rollDeg:n(e.rollDeg)},...d?{appearance:d}:{}}}static withoutPlacement(e){if(!e)return{};const{eastM:o,northM:t,azimuthDeg:s,altitudeDeg:n,distanceM:i,onGround:d,altitudeAboveGroundM:r,sizeM:a,attitude:h,appearance:c,...b}=e;return b}}class l{static number(e,o,t,s,n,i,d={}){return{type:"number",key:e,label:o,min:t,max:s,step:n,unit:i,required:!0,...d}}static BODY={kind:"body",title:{en:"Body",fr:"Corps",es:"Cuerpo",it:"Corpo"},parameters:[{type:"text",key:"id",required:!0,label:{en:"ID",fr:"Identifiant",es:"Identificador",it:"Identificativo"},validate:(e,o,t)=>!(t?.ids??[]).some(s=>s===e&&s!==o.id)},{type:"said",key:"title",label:{en:"Name",fr:"Nom",es:"Nombre",it:"Nome"}},{type:"set",key:"explains",label:{en:"Stands for the shapes",fr:"Représente les formes",es:"Representa las formas",it:"Rappresenta le forme"},options:(e,o)=>{const t=o?.shapes??[],s=(e.explains??[]).filter(n=>!t.some(i=>i.value===n));return[...t,...s.map(n=>({value:n,label:n}))]},empty:{en:"No shape",fr:"Aucune forme",es:"Ninguna forma",it:"Nessuna forma"}},{type:"text",key:"outlineNode",label:{en:"Part drawn by the observer",fr:"Partie dessinée par l'observateur",es:"Parte dibujada por el observador",it:"Parte disegnata dall'osservatore"},placeholder:{en:"Node of the model, e.g. hull",fr:"Nœud du modèle, par ex. hull",es:"Nodo del modelo, p. ej. hull",it:"Nodo del modello, ad es. hull"}}]};static KEYFRAME={kind:"body-keyframe",title:{en:"At the playhead",fr:"À l'instant courant",es:"En el instante actual",it:"All'istante corrente"},parameters:[{type:"choice",key:"mode",required:!0,label:{en:"Position",fr:"Position",es:"Posición",it:"Posizione"},choices:[{value:"observer",label:{en:"From the observer",fr:"Depuis l'observateur",es:"Desde el observador",it:"Dall'osservatore"}},{value:"world",label:{en:"In the world",fr:"Dans le monde",es:"En el mundo",it:"Nel mondo"}}]},l.number("azimuthDeg",{en:"Azimuth",fr:"Azimut",es:"Acimut",it:"Azimut"},0,360,.01,"°",{visibleWhen:e=>e.mode==="observer"}),l.number("elevationDeg",{en:"Elevation",fr:"Hauteur",es:"Elevación",it:"Elevazione"},-90,90,.01,"°",{visibleWhen:e=>e.mode==="observer"}),l.number("distanceM",{en:"Distance",fr:"Distance",es:"Distancia",it:"Distanza"},.1,3e4,.1,"m",{visibleWhen:e=>e.mode==="observer"}),l.number("eastM",{en:"East",fr:"Est",es:"Este",it:"Est"},-3e4,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"}),l.number("northM",{en:"North",fr:"Nord",es:"Norte",it:"Nord"},-3e4,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"}),{type:"boolean",key:"onGround",label:{en:"On the ground",fr:"Au sol",es:"En el suelo",it:"A terra"}},l.number("aboveGroundM",{en:"Above the ground",fr:"Au-dessus du sol",es:"Sobre el suelo",it:"Sopra il suolo"},0,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"&&e.onGround!==!0}),l.number("widthM",{en:"Width",fr:"Largeur",es:"Ancho",it:"Larghezza"},.01,1e3,.01,"m"),l.number("lengthM",{en:"Length",fr:"Longueur",es:"Largo",it:"Lunghezza"},.01,1e3,.01,"m"),l.number("heightM",{en:"Height",fr:"Hauteur",es:"Alto",it:"Altezza"},.01,1e3,.01,"m"),l.number("headingDeg",{en:"Heading",fr:"Cap",es:"Rumbo",it:"Rotta"},0,360,.1,"°"),l.number("pitchDeg",{en:"Pitch",fr:"Tangage",es:"Cabeceo",it:"Beccheggio"},-90,90,.1,"°"),l.number("rollDeg",{en:"Roll",fr:"Roulis",es:"Alabeo",it:"Rollio"},-180,180,.1,"°"),{type:"colour",key:"color",label:{en:"Colour",fr:"Couleur",es:"Color",it:"Colore"},fallback:"#c8c8c8",visibleWhen:(e,o)=>o?.drawnFromModel!==!0},l.number("albedo",{en:"Albedo",fr:"Albédo",es:"Albedo",it:"Albedo"},0,1,.01,void 0),l.number("luminanceCdM2",{en:"Light of its own",fr:"Lumière propre",es:"Luz propia",it:"Luce propria"},0,1e10,.1,"cd/m²"),l.number("transparency",{en:"Transparency",fr:"Transparence",es:"Transparencia",it:"Trasparenza"},0,1,.01,void 0),l.number("haloScale",{en:"Halo",fr:"Halo",es:"Halo",it:"Alone"},0,20,.1,"×")]}}class p{constructor(e,o,t){this.container=e,this.host=o,this.language=t,this.render(),this.setLanguage(t)}static APPEARANCE_KEYS=["color","albedo","luminanceCdM2","transparency","haloScale"];messages=k;languageToken=0;currentId;catalogueToken=0;shownEntry;syncedId;bodyForm;keyForm;async setLanguage(e){const o=++this.languageToken;this.language=e;const t=A.includes(e)?e:"en",s=t==="en"?k:await z(t);o===this.languageToken&&s!==this.messages&&(this.messages=s,this.render())}sync(){const e=this.bodies;e.some(i=>i.id===this.currentId)||(this.currentId=e[0]?.id),this.input("body-interpretation-title").value=this.host.said().read(this.interpretation?.title)??"",this.list?.setItems(e.map(i=>({id:i.id,label:this.labelOf(i)})),this.currentId);const o=this.host.newBodyStart();this.list?.setAddState(o!==void 0,o?o.label!==void 0?this.messages.addBodyHint.replace("{shape}",o.label):this.messages.addBodyHintView:void 0),this.input("body-interpretation-title").closest("label").hidden=!1;const t=this.current;if(this.element("body-none").hidden=e.length>0,this.element("body-fields").hidden=t===void 0,!t)return;this.bodyForm?.sync(),this.syncModelOptions(t);const s=t.model;this.input("body-model-url").value=s.url??"",this.input("body-model-title").value=s.credit?.title??"",this.input("body-model-author").value=s.credit?.author??"",this.input("body-model-license").value=s.credit?.license??"",this.input("body-model-source").value=s.credit?.sourceUrl??"";const n=this.element("body-model-advanced");n.open=s.url!==void 0||n.open&&t.id===this.syncedId,this.syncedId=t.id,this.element("body-model-incomplete").hidden=s.url===void 0||s.credit?.title!==void 0&&s.credit.license!==void 0,this.syncKeyframe()}syncKeyframe(e=!1){const o=this.current;if(!o)return;const t=this.host.currentTime(),s=this.messages;this.element("body-key-legend").textContent=s.atPlayhead.replace("{t}",p.seconds(t));const n=this.host.readingOf(o,t),i=o.track.find(d=>d.t===t);this.element("body-key-note").textContent=n?i?s.keyframeHere:s.keyframeAdded:s.notPlaced,this.keyList?.setItems(o.track.map(d=>({id:String(d.t),label:p.seconds(d.t)})),i?String(i.t):""),this.keyList?.setAddState(n!==void 0&&i===void 0),this.keyList?.setStepState(o.track.some(d=>d.t<t),o.track.some(d=>d.t>t)),this.element("body-key-parameters").hidden=!n,n&&this.keyForm?.sync(e)}stepKeyframe(e){const o=this.current;if(!o)return;const t=this.host.currentTime(),s=o.track.map(n=>n.t).filter(n=>e<0?n<t:n>t);s.length!==0&&(this.host.seekTo(e<0?Math.max(...s):Math.min(...s)),this.syncKeyframe(!0))}keyframeContext(){const e=this.current?.model;return{drawnFromModel:e===void 0||e.url!==void 0||!u.includes(e.id??"")}}keyframeView(){const e=this.current;if(!e)return;const o=this.host.currentTime(),t=this.host.readingOf(e,o);return t?m.viewOf(e,o,t):void 0}render(){const e=this.messages,o=(i,d,r="text",a="",h="",c="")=>`<label><span>${d}</span> <input id="${i}" type="${r}" placeholder="${a}" ${c} autocomplete="off"/>${h?` ${h}`:""}</label>`;this.container.innerHTML=`<div class="body-editor">
1
+ import{U as A,g as z,B as u,E as f,P as M,h as v}from"./rr0-sighting-editor.mjs";import{bodyEditorMessages_en as k}from"./BodyEditorMessages_en-C3VGB1gD.js";class m{static before(e,o){const t=[...e.track].sort((s,n)=>s.t-n.t);return[...t].reverse().find(s=>s.t<=o)??t[0]}static viewOf(e,o,t){const s=m.before(e,o),n=i=>Number(i.toFixed(2));return{mode:s?.eastM!==void 0&&s.northM!==void 0?"world":"observer",azimuthDeg:n(t.azimuthDeg),elevationDeg:n(t.altitudeDeg),distanceM:n(t.distanceM),eastM:n(t.eastM),northM:n(t.northM),aboveGroundM:n(t.aboveGroundM),onGround:s?.onGround===!0,widthM:n(t.sizeM.widthM),lengthM:n(t.sizeM.lengthM),heightM:n(t.sizeM.heightM),headingDeg:n(t.attitude.headingDeg),pitchDeg:n(t.attitude.pitchDeg),rollDeg:n(t.attitude.rollDeg),color:t.appearance.color,albedo:n(t.appearance.albedo),luminanceCdM2:n(t.appearance.luminanceCdM2),transparency:n(t.appearance.transparency??0),haloScale:n(t.appearance.haloScale??1)}}static keyframeOf(e,o,t,s){const n=r=>Number.isFinite(r)?r:0,i=e.mode==="world"?{t:o,eastM:n(e.eastM),northM:n(e.northM),...e.onGround?{onGround:!0}:{altitudeAboveGroundM:n(e.aboveGroundM)}}:{t:o,azimuthDeg:n(e.azimuthDeg),altitudeDeg:n(e.elevationDeg),distanceM:Math.max(.1,n(e.distanceM)),...e.onGround?{onGround:!0}:{}},d=s?{color:e.color,albedo:Math.max(0,Math.min(1,n(e.albedo))),luminanceCdM2:Math.max(0,n(e.luminanceCdM2)),transparency:Math.max(0,Math.min(1,n(e.transparency))),haloScale:Math.max(0,n(e.haloScale))}:t?.appearance;return{...m.withoutPlacement(t),...i,sizeM:{widthM:Math.max(.01,n(e.widthM)),lengthM:Math.max(.01,n(e.lengthM)),heightM:Math.max(.01,n(e.heightM))},attitude:{headingDeg:n(e.headingDeg),pitchDeg:n(e.pitchDeg),rollDeg:n(e.rollDeg)},...d?{appearance:d}:{}}}static withoutPlacement(e){if(!e)return{};const{eastM:o,northM:t,azimuthDeg:s,altitudeDeg:n,distanceM:i,onGround:d,altitudeAboveGroundM:r,sizeM:a,attitude:h,appearance:c,...b}=e;return b}}class l{static number(e,o,t,s,n,i,d={}){return{type:"number",key:e,label:o,min:t,max:s,step:n,unit:i,required:!0,...d}}static BODY={kind:"body",title:{en:"Body",fr:"Corps",es:"Cuerpo",it:"Corpo"},parameters:[{type:"text",key:"id",required:!0,label:{en:"ID",fr:"Identifiant",es:"Identificador",it:"Identificativo"},validate:(e,o,t)=>!(t?.ids??[]).some(s=>s===e&&s!==o.id)},{type:"said",key:"title",label:{en:"Name",fr:"Nom",es:"Nombre",it:"Nome"}},{type:"set",key:"explains",label:{en:"Stands for the shapes",fr:"Représente les formes",es:"Representa las formas",it:"Rappresenta le forme"},options:(e,o)=>{const t=o?.shapes??[],s=(e.explains??[]).filter(n=>!t.some(i=>i.value===n));return[...t,...s.map(n=>({value:n,label:n}))]},empty:{en:"No shape",fr:"Aucune forme",es:"Ninguna forma",it:"Nessuna forma"}},{type:"text",key:"outlineNode",label:{en:"Part drawn by the observer",fr:"Partie dessinée par l'observateur",es:"Parte dibujada por el observador",it:"Parte disegnata dall'osservatore"},placeholder:{en:"Node of the model, e.g. hull",fr:"Nœud du modèle, par ex. hull",es:"Nodo del modelo, p. ej. hull",it:"Nodo del modello, ad es. hull"}}]};static KEYFRAME={kind:"body-keyframe",title:{en:"At the playhead",fr:"À l'instant courant",es:"En el instante actual",it:"All'istante corrente"},parameters:[{type:"choice",key:"mode",required:!0,label:{en:"Position",fr:"Position",es:"Posición",it:"Posizione"},choices:[{value:"observer",label:{en:"From the observer",fr:"Depuis l'observateur",es:"Desde el observador",it:"Dall'osservatore"}},{value:"world",label:{en:"In the world",fr:"Dans le monde",es:"En el mundo",it:"Nel mondo"}}]},l.number("azimuthDeg",{en:"Azimuth",fr:"Azimut",es:"Acimut",it:"Azimut"},0,360,.01,"°",{visibleWhen:e=>e.mode==="observer"}),l.number("elevationDeg",{en:"Elevation",fr:"Hauteur",es:"Elevación",it:"Elevazione"},-90,90,.01,"°",{visibleWhen:e=>e.mode==="observer"}),l.number("distanceM",{en:"Distance",fr:"Distance",es:"Distancia",it:"Distanza"},.1,3e4,.1,"m",{visibleWhen:e=>e.mode==="observer"}),l.number("eastM",{en:"East",fr:"Est",es:"Este",it:"Est"},-3e4,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"}),l.number("northM",{en:"North",fr:"Nord",es:"Norte",it:"Nord"},-3e4,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"}),{type:"boolean",key:"onGround",label:{en:"On the ground",fr:"Au sol",es:"En el suelo",it:"A terra"}},l.number("aboveGroundM",{en:"Above the ground",fr:"Au-dessus du sol",es:"Sobre el suelo",it:"Sopra il suolo"},0,3e4,.1,"m",{visibleWhen:e=>e.mode==="world"&&e.onGround!==!0}),l.number("widthM",{en:"Width",fr:"Largeur",es:"Ancho",it:"Larghezza"},.01,1e3,.01,"m"),l.number("lengthM",{en:"Length",fr:"Longueur",es:"Largo",it:"Lunghezza"},.01,1e3,.01,"m"),l.number("heightM",{en:"Height",fr:"Hauteur",es:"Alto",it:"Altezza"},.01,1e3,.01,"m"),l.number("headingDeg",{en:"Heading",fr:"Cap",es:"Rumbo",it:"Rotta"},0,360,.1,"°"),l.number("pitchDeg",{en:"Pitch",fr:"Tangage",es:"Cabeceo",it:"Beccheggio"},-90,90,.1,"°"),l.number("rollDeg",{en:"Roll",fr:"Roulis",es:"Alabeo",it:"Rollio"},-180,180,.1,"°"),{type:"colour",key:"color",label:{en:"Colour",fr:"Couleur",es:"Color",it:"Colore"},fallback:"#c8c8c8",visibleWhen:(e,o)=>o?.drawnFromModel!==!0},l.number("albedo",{en:"Albedo",fr:"Albédo",es:"Albedo",it:"Albedo"},0,1,.01,void 0),l.number("luminanceCdM2",{en:"Light of its own",fr:"Lumière propre",es:"Luz propia",it:"Luce propria"},0,1e10,.1,"cd/m²"),l.number("transparency",{en:"Transparency",fr:"Transparence",es:"Transparencia",it:"Trasparenza"},0,1,.01,void 0),l.number("haloScale",{en:"Halo",fr:"Halo",es:"Halo",it:"Alone"},0,20,.1,"×")]}}class p{constructor(e,o,t){this.container=e,this.host=o,this.language=t,this.render(),this.setLanguage(t)}static APPEARANCE_KEYS=["color","albedo","luminanceCdM2","transparency","haloScale"];messages=k;languageToken=0;currentId;catalogueToken=0;shownEntry;syncedId;bodyForm;keyForm;async setLanguage(e){const o=++this.languageToken;this.language=e;const t=A.includes(e)?e:"en",s=t==="en"?k:await z(t);o===this.languageToken&&s!==this.messages&&(this.messages=s,this.render())}sync(){const e=this.bodies;e.some(i=>i.id===this.currentId)||(this.currentId=e[0]?.id),this.input("body-interpretation-title").value=this.host.said().read(this.interpretation?.title)??"",this.list?.setItems(e.map(i=>({id:i.id,label:this.labelOf(i)})),this.currentId);const o=this.host.newBodyStart();this.list?.setAddState(o!==void 0,o?o.label!==void 0?this.messages.addBodyHint.replace("{shape}",o.label):this.messages.addBodyHintView:void 0),this.input("body-interpretation-title").closest("label").hidden=!1;const t=this.current;if(this.element("body-none").hidden=e.length>0,this.element("body-fields").hidden=t===void 0,!t)return;this.bodyForm?.sync(),this.syncModelOptions(t);const s=t.model;this.input("body-model-url").value=s.url??"",this.input("body-model-title").value=s.credit?.title??"",this.input("body-model-author").value=s.credit?.author??"",this.input("body-model-license").value=s.credit?.license??"",this.input("body-model-source").value=s.credit?.sourceUrl??"";const n=this.element("body-model-advanced");n.open=s.url!==void 0||n.open&&t.id===this.syncedId,this.syncedId=t.id,this.element("body-model-incomplete").hidden=s.url===void 0||s.credit?.title!==void 0&&s.credit.license!==void 0,this.syncKeyframe()}syncKeyframe(e=!1){const o=this.current;if(!o)return;const t=this.host.currentTime(),s=this.messages;this.element("body-key-legend").textContent=s.atPlayhead.replace("{t}",p.seconds(t));const n=this.host.readingOf(o,t),i=o.track.find(d=>d.t===t);this.element("body-key-note").textContent=n?i?s.keyframeHere:s.keyframeAdded:s.notPlaced,this.keyList?.setItems(o.track.map(d=>({id:String(d.t),label:p.seconds(d.t)})),i?String(i.t):""),this.keyList?.setAddState(n!==void 0&&i===void 0),this.keyList?.setStepState(o.track.some(d=>d.t<t),o.track.some(d=>d.t>t)),this.element("body-key-parameters").hidden=!n,n&&this.keyForm?.sync(e)}stepKeyframe(e){const o=this.current;if(!o)return;const t=this.host.currentTime(),s=o.track.map(n=>n.t).filter(n=>e<0?n<t:n>t);s.length!==0&&(this.host.seekTo(e<0?Math.max(...s):Math.min(...s)),this.syncKeyframe(!0))}keyframeContext(){const e=this.current?.model;return{drawnFromModel:e===void 0||e.url!==void 0||!u.includes(e.id??"")}}keyframeView(){const e=this.current;if(!e)return;const o=this.host.currentTime(),t=this.host.readingOf(e,o);return t?m.viewOf(e,o,t):void 0}render(){const e=this.messages,o=(i,d,r="text",a="",h="",c="")=>`<label><span>${d}</span> <input id="${i}" type="${r}" placeholder="${a}" ${c} autocomplete="off"/>${h?` ${h}`:""}</label>`;this.container.innerHTML=`<div class="body-editor">
2
2
  <p class="body-intro">${e.intro}</p>
3
3
  ${o("body-interpretation-title",e.interpretationTitle)}
4
4
  <p id="body-none" class="body-intro">${e.none}</p>
@@ -0,0 +1 @@
1
+ const e={event:"Evento",accountOf:"Observación de",passagesHeading:"Relatado en",interviewOf:"Entrevista a",untitledInterview:"Entrevista {n}",deleteInterviewQuestion:"¿Eliminar esta entrevista del caso? Nada se escribe hasta guardar el caso.",untitledReading:"Lectura {n}",untitledObservation:"Observación {n}",deleteRecording:"Quitar esta grabación del caso",deleteReadingQuestion:"¿Eliminar esta lectura? Nada se escribe hasta guardar el caso.",deleteObservationQuestion:"¿Eliminar esta observación del caso? Nada se escribe hasta guardar el caso.",deleteRefused:"Esta observación es interpretada por {n} lectura(s): elimínelas primero.",titleField:"Título de la interpretación",authorField:"Autor",addTitle:"Añadir un evento",kindField:"Tipo",kindObservation:"Observación",kindInterview:"Entrevista",witnessField:"Testigo",mediumField:"Medio",interviewerField:"Entrevistador",plainTitleField:"Título",sourceField:"Origen",sourceBlank:"Una grabación en blanco",sourceFile:"Un archivo JSON",sourceUrl:"Una dirección",observerField:"Testigo",fileField:"Archivo",urlField:"Dirección",loadFailed:"No se pudo leer esa grabación.",isACase:"Eso es un caso, no una grabación.",ok:"Aceptar",cancel:"Cancelar",caseHeading:"Caso",caseId:"Identificador",recordingId:"Identificador",idTaken:"Otra grabación del caso tiene este identificador.",idInvalid:"Un identificador se compone de letras, dígitos, guiones y guiones bajos, y empieza por una letra o un dígito.",idNeeded:"Una interpretación designa esta grabación por su identificador: no puede quedar vacío.",idDuplicated:"Dos eventos del caso tienen el identificador «{id}»: una interpretación que lo designa es ambigua.",readingUnresolved:"Una interpretación designa «{id}», que ningún evento del caso tiene como identificador, ni ninguna grabación que enumera.",caseTitle:"Título",caseTime:"Fecha",eventsTab:"Eventos",fileTab:"Archivo",importFile:"Cargar un archivo JSON",importUrl:"O desde una dirección",importButton:"Cargar",fileNotACase:"Ese archivo no es un caso (no tiene eventos).",fileInvalid:"Este texto aún no es JSON válido, o no es un caso: el caso conserva lo último que entendió.",fileLoading:"Cargando el editor…",add:"Añadir",addHint:"Añadir un evento",interpretationOf:"Interpretación de",interpretationOfNone:"—",exportButton:"Guardar",exportTitle:"Guardar el caso",exportAlso:"Guardar también las observaciones",addToCase:"Añadir a un caso",unsavedChanges:"Cambios sin guardar",discardQuestion:"Hay cambios que aún no se han guardado. ¿Cargar de todos modos y perderlos?",discardTitle:"Cambios sin guardar",discardOk:"Cargar de todos modos",leaveQuestion:"Hay cambios que aún no se han guardado. ¿Salir de todos modos y perderlos?",leaveOk:"Salir de todos modos"};export{e as caseEditorMessages_es};
@@ -0,0 +1 @@
1
+ const e={event:"Événement",accountOf:"Observation de",passagesHeading:"Relaté dans",interviewOf:"Interview de",untitledInterview:"Interview {n}",deleteInterviewQuestion:"Supprimer cet entretien du dossier ? Rien n'est écrit avant la sauvegarde du dossier.",untitledReading:"Lecture {n}",untitledObservation:"Observation {n}",deleteRecording:"Retirer cet enregistrement du dossier",deleteReadingQuestion:"Supprimer cette lecture ? Rien n'est écrit avant la sauvegarde du dossier.",deleteObservationQuestion:"Supprimer cette observation du dossier ? Rien n'est écrit avant la sauvegarde du dossier.",deleteRefused:"Cette observation est interprétée par {n} lecture(s) : supprimez-les d'abord.",titleField:"Titre de l'interprétation",authorField:"Auteur",addTitle:"Ajouter un événement",kindField:"Type",kindObservation:"Observation",kindInterview:"Interview",witnessField:"Témoin",mediumField:"Moyen",interviewerField:"Enquêteur",plainTitleField:"Titre",sourceField:"Source",sourceBlank:"Un enregistrement vierge",sourceFile:"Un fichier JSON",sourceUrl:"Une adresse",observerField:"Témoin",fileField:"Fichier",urlField:"Adresse",loadFailed:"Cet enregistrement n'a pas pu être lu.",isACase:"C'est un dossier, pas un enregistrement.",ok:"OK",cancel:"Annuler",caseHeading:"Dossier",caseId:"Identifiant",recordingId:"Identifiant",idTaken:"Un autre enregistrement du dossier porte cet identifiant.",idInvalid:"Un identifiant est fait de lettres, de chiffres, de tirets et de soulignés, et commence par une lettre ou un chiffre.",idNeeded:"Une interprétation désigne cet enregistrement par son identifiant : il ne peut pas rester vide.",idDuplicated:"Deux événements du dossier portent l'identifiant « {id} » : une interprétation qui le désigne est ambiguë.",readingUnresolved:"Une interprétation désigne « {id} », qu'aucun événement du dossier ne porte comme identifiant, ni aucun enregistrement qu'il liste.",caseTitle:"Titre",caseTime:"Date",eventsTab:"Événements",fileTab:"Fichier",importFile:"Charger un fichier JSON",importUrl:"Ou depuis une adresse",importButton:"Charger",fileNotACase:"Ce fichier n'est pas un dossier (il n'a pas d'événements).",fileInvalid:"Ce texte n'est pas encore du JSON valide, ou pas un dossier : le dossier garde ce qu'il a compris en dernier.",fileLoading:"Chargement de l'éditeur…",add:"Ajouter",addHint:"Ajouter un événement",interpretationOf:"Interprétation de",interpretationOfNone:"—",exportButton:"Sauver",exportTitle:"Sauver le dossier",exportAlso:"Sauver aussi les observations",addToCase:"Ajouter à un dossier",unsavedChanges:"Modifications non sauvées",discardQuestion:"Des modifications ne sont pas encore sauvées. Charger quand même et les perdre ?",discardTitle:"Modifications non sauvées",discardOk:"Charger quand même",leaveQuestion:"Des modifications ne sont pas encore sauvées. Quitter quand même et les perdre ?",leaveOk:"Quitter quand même"};export{e as caseEditorMessages_fr};
@@ -0,0 +1 @@
1
+ const e={event:"Evento",accountOf:"Osservazione di",passagesHeading:"Riportato in",interviewOf:"Intervista a",untitledInterview:"Intervista {n}",deleteInterviewQuestion:"Eliminare questa intervista dal caso? Nulla viene scritto prima del salvataggio del caso.",untitledReading:"Lettura {n}",untitledObservation:"Osservazione {n}",deleteRecording:"Togliere questa registrazione dal caso",deleteReadingQuestion:"Eliminare questa lettura? Nulla viene scritto prima del salvataggio del caso.",deleteObservationQuestion:"Eliminare questa osservazione dal caso? Nulla viene scritto prima del salvataggio del caso.",deleteRefused:"Questa osservazione è interpretata da {n} lettura/e: eliminale prima.",titleField:"Titolo dell'interpretazione",authorField:"Autore",addTitle:"Aggiungi un evento",kindField:"Tipo",kindObservation:"Osservazione",kindInterview:"Intervista",witnessField:"Testimone",mediumField:"Mezzo",interviewerField:"Intervistatore",plainTitleField:"Titolo",sourceField:"Origine",sourceBlank:"Una registrazione vuota",sourceFile:"Un file JSON",sourceUrl:"Un indirizzo",observerField:"Testimone",fileField:"File",urlField:"Indirizzo",loadFailed:"Impossibile leggere quella registrazione.",isACase:"Questo è un caso, non una registrazione.",ok:"OK",cancel:"Annulla",caseHeading:"Caso",caseId:"Identificativo",recordingId:"Identificativo",idTaken:"Un'altra registrazione del caso ha questo identificativo.",idInvalid:"Un identificativo è fatto di lettere, cifre, trattini e trattini bassi, e inizia con una lettera o una cifra.",idNeeded:"Un'interpretazione designa questa registrazione con il suo identificativo: non può restare vuoto.",idDuplicated:"Due eventi del caso hanno l'identificativo «{id}»: un'interpretazione che lo designa è ambigua.",readingUnresolved:"Un'interpretazione designa «{id}», che nessun evento del caso ha come identificativo, né alcuna registrazione che elenca.",caseTitle:"Titolo",caseTime:"Data",eventsTab:"Eventi",fileTab:"File",importFile:"Carica un file JSON",importUrl:"O da un indirizzo",importButton:"Carica",fileNotACase:"Quel file non è un caso (non ha eventi).",fileInvalid:"Questo testo non è ancora JSON valido, o non è un caso: il caso conserva l'ultimo che ha capito.",fileLoading:"Caricamento dell'editor…",add:"Aggiungi",addHint:"Aggiungi un evento",interpretationOf:"Interpretazione di",interpretationOfNone:"—",exportButton:"Salva",exportTitle:"Salva il caso",exportAlso:"Salva anche le osservazioni",addToCase:"Aggiungi a un caso",unsavedChanges:"Modifiche non salvate",discardQuestion:"Alcune modifiche non sono ancora state salvate. Caricare comunque e perderle?",discardTitle:"Modifiche non salvate",discardOk:"Carica comunque",leaveQuestion:"Alcune modifiche non sono ancora state salvate. Uscire comunque e perderle?",leaveOk:"Esci comunque"};export{e as caseEditorMessages_it};
@@ -1 +1 @@
1
- import{G as T,a5 as A,ac as N,M as w,ad as G,ae as O}from"./rr0-sighting-editor.mjs";import{C as S}from"./ContrailGrowth-CuAzwIoc.js";class f{static MAX_SEGMENTS=4e3;static MIN_PIXELS=2;static UNRESOLVED_CONTRAST=.5;static VERTICES_PER_SEGMENT=12;object;group=new T;trails=[];positions=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*3);colors=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*4);segments=0;constructor(){const t=new A;t.setAttribute("position",new N(this.positions,3)),t.setAttribute("color",new N(this.colors,4)),t.setDrawRange(0,0),this.object=new w(t,new G({vertexColors:!0,transparent:!0,depthWrite:!1,side:O})),this.object.frustumCulled=!1,this.object.name="contrails",this.group.name="contrails",this.group.add(this.object)}get segmentCount(){return this.segments}set(t){this.trails=t}update(t,s,r){let a=0;this.segments=0;for(const n of this.trails){const h=this.samplesOf(n,t,s),e=r(n.id);for(let c=0;c+1<h.length;c++){const o=h[c],p=h[c+1];if(!o.forms||!p.forms)continue;if(this.segments>=f.MAX_SEGMENTS)break;const l=this.pushSegment(a,o,p,n.spanM,e,s);l>a&&this.segments++,a=l}}const M=this.object.geometry;M.setDrawRange(0,a);for(const[n,h]of[["position",3],["color",4]]){const e=M.getAttribute(n);e.clearUpdateRanges(),a>0&&e.addUpdateRange(0,a*h),e.needsUpdate=!0}}samplesOf(t,s,r){const a=s-S.FORMATION_S*1e3,M=[],n=(o,p,l,d,m,y)=>({x:p+o.driftEastMs*m+r.origin.x,y:d,z:-(l+o.driftNorthMs*m)+r.origin.z,age:m,forms:y,point:o});let h=-1;t.points.forEach((o,p)=>{o.tMs>a||(h=p,M.push(n(o,o.eastM,o.northM,o.upM,(s-o.tMs)/1e3,o.forms)))});const e=t.points[h],c=t.points[h+1];if(e&&c){const o=(a-e.tMs)/(c.tMs-e.tMs),p=(l,d)=>l+(d-l)*o;M.push(n(e,p(e.eastM,c.eastM),p(e.northM,c.northM),p(e.upM,c.upM),S.FORMATION_S,e.forms&&c.forms))}return M}pushSegment(t,s,r,a,M,n){const h={persistent:s.point.persistent,lifetimeS:s.point.lifetimeS,spanM:a,shearPerS:s.point.shearPerS},e=S.opacity(s.age,h),c=S.opacity(r.age,h);if(e<=0&&c<=0)return t;const o={x:r.x-s.x,y:r.y-s.y,z:r.z-s.z};if(Math.hypot(o.x,o.y,o.z)<1e-6)return t;const p={x:(s.x+r.x)/2-n.eye.x,y:(s.y+r.y)/2-n.eye.y,z:(s.z+r.z)/2-n.eye.z},l=this.normalise(this.cross(o,p)),d=(i,u)=>{const g=Math.hypot(i.x-n.eye.x,i.y-n.eye.y,i.z-n.eye.z),E=S.widthM(a,i.age,i.point.shearPerS),R=Math.max(E,f.MIN_PIXELS*n.pixelRad*g);return{half:R/2,alpha:u*(E/R)**f.UNRESOLVED_CONTRAST}},m=[{sample:s,...d(s,e)},{sample:r,...d(r,c)}],y=(i,u)=>{const g=t*3;this.positions[g]=i.sample.x+l.x*i.half*u,this.positions[g+1]=i.sample.y+l.y*i.half*u,this.positions[g+2]=i.sample.z+l.z*i.half*u;const E=t*4;this.colors[E]=M[0],this.colors[E+1]=M[1],this.colors[E+2]=M[2],this.colors[E+3]=u===0?i.alpha:0,t++},[x,z]=m;for(const[i,u]of[[-1,0],[1,0]])y(x,i),y(x,u),y(z,i),y(x,u),y(z,u),y(z,i);return t}cross(t,s){return{x:t.y*s.z-t.z*s.y,y:t.z*s.x-t.x*s.z,z:t.x*s.y-t.y*s.x}}normalise(t){const s=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/s,y:t.y/s,z:t.z/s}}dispose(){this.object.geometry.dispose(),this.object.material.dispose(),this.group.removeFromParent()}}export{f as ContrailSystem};
1
+ import{G as T,ad as A,ak as N,M as w,al as G,am as O}from"./rr0-sighting-editor.mjs";import{C as S}from"./ContrailGrowth-CuAzwIoc.js";class f{static MAX_SEGMENTS=4e3;static MIN_PIXELS=2;static UNRESOLVED_CONTRAST=.5;static VERTICES_PER_SEGMENT=12;object;group=new T;trails=[];positions=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*3);colors=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*4);segments=0;constructor(){const t=new A;t.setAttribute("position",new N(this.positions,3)),t.setAttribute("color",new N(this.colors,4)),t.setDrawRange(0,0),this.object=new w(t,new G({vertexColors:!0,transparent:!0,depthWrite:!1,side:O})),this.object.frustumCulled=!1,this.object.name="contrails",this.group.name="contrails",this.group.add(this.object)}get segmentCount(){return this.segments}set(t){this.trails=t}update(t,s,r){let a=0;this.segments=0;for(const n of this.trails){const h=this.samplesOf(n,t,s),e=r(n.id);for(let c=0;c+1<h.length;c++){const o=h[c],p=h[c+1];if(!o.forms||!p.forms)continue;if(this.segments>=f.MAX_SEGMENTS)break;const l=this.pushSegment(a,o,p,n.spanM,e,s);l>a&&this.segments++,a=l}}const M=this.object.geometry;M.setDrawRange(0,a);for(const[n,h]of[["position",3],["color",4]]){const e=M.getAttribute(n);e.clearUpdateRanges(),a>0&&e.addUpdateRange(0,a*h),e.needsUpdate=!0}}samplesOf(t,s,r){const a=s-S.FORMATION_S*1e3,M=[],n=(o,p,l,d,m,y)=>({x:p+o.driftEastMs*m+r.origin.x,y:d,z:-(l+o.driftNorthMs*m)+r.origin.z,age:m,forms:y,point:o});let h=-1;t.points.forEach((o,p)=>{o.tMs>a||(h=p,M.push(n(o,o.eastM,o.northM,o.upM,(s-o.tMs)/1e3,o.forms)))});const e=t.points[h],c=t.points[h+1];if(e&&c){const o=(a-e.tMs)/(c.tMs-e.tMs),p=(l,d)=>l+(d-l)*o;M.push(n(e,p(e.eastM,c.eastM),p(e.northM,c.northM),p(e.upM,c.upM),S.FORMATION_S,e.forms&&c.forms))}return M}pushSegment(t,s,r,a,M,n){const h={persistent:s.point.persistent,lifetimeS:s.point.lifetimeS,spanM:a,shearPerS:s.point.shearPerS},e=S.opacity(s.age,h),c=S.opacity(r.age,h);if(e<=0&&c<=0)return t;const o={x:r.x-s.x,y:r.y-s.y,z:r.z-s.z};if(Math.hypot(o.x,o.y,o.z)<1e-6)return t;const p={x:(s.x+r.x)/2-n.eye.x,y:(s.y+r.y)/2-n.eye.y,z:(s.z+r.z)/2-n.eye.z},l=this.normalise(this.cross(o,p)),d=(i,u)=>{const g=Math.hypot(i.x-n.eye.x,i.y-n.eye.y,i.z-n.eye.z),E=S.widthM(a,i.age,i.point.shearPerS),R=Math.max(E,f.MIN_PIXELS*n.pixelRad*g);return{half:R/2,alpha:u*(E/R)**f.UNRESOLVED_CONTRAST}},m=[{sample:s,...d(s,e)},{sample:r,...d(r,c)}],y=(i,u)=>{const g=t*3;this.positions[g]=i.sample.x+l.x*i.half*u,this.positions[g+1]=i.sample.y+l.y*i.half*u,this.positions[g+2]=i.sample.z+l.z*i.half*u;const E=t*4;this.colors[E]=M[0],this.colors[E+1]=M[1],this.colors[E+2]=M[2],this.colors[E+3]=u===0?i.alpha:0,t++},[x,z]=m;for(const[i,u]of[[-1,0],[1,0]])y(x,i),y(x,u),y(z,i),y(x,u),y(z,u),y(z,i);return t}cross(t,s){return{x:t.y*s.z-t.z*s.y,y:t.z*s.x-t.x*s.z,z:t.x*s.y-t.y*s.x}}normalise(t){const s=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/s,y:t.y/s,z:t.z/s}}dispose(){this.object.geometry.dispose(),this.object.material.dispose(),this.group.removeFromParent()}}export{f as ContrailSystem};
@@ -1 +1 @@
1
- import{v as m}from"./rr0-sighting-editor.mjs";const o=[{id:"when",paths:["time.year","time.month","time.day","time.hour","time.minute","time.raw"]},{id:"where",paths:["place.*.lat","place.*.lng","observerTrack.keyframes.*.pose.lat","observerTrack.keyframes.*.pose.lng"]},{id:"facing",paths:["observerTrack.keyframes.*.pose.headingDeg"]},{id:"apparent-size",paths:["timeline.keyframes.*.shapes.*.shape.angular.widthDeg","timeline.keyframes.*.shapes.*.shape.angular.heightDeg"]},{id:"sky-position",paths:["timeline.keyframes.*.shapes.*.shape.aim.azimuthDeg","timeline.keyframes.*.shapes.*.shape.aim.altitudeDeg"]},{id:"how-long",paths:["durationSeconds","endTime.hour","endTime.minute","endTime.raw"]},{id:"appearance",paths:["timeline.keyframes.*.shapes.*.shape.kind","timeline.keyframes.*.shapes.*.shape.title","timeline.keyframes.*.shapes.*.shape.color","timeline.keyframes.*.shapes.*.shape.brightness"]},{id:"movement",paths:["timeline.keyframes.1.t","observerTrack.keyframes.1.t"]},{id:"sound",paths:["soundTrack.keyframes.*.sound.kind"]},{id:"conditions",paths:["weatherTrack.keyframes.*.weather.*","weather.*"]}],d=["assumed","derived","stated"];class p{about="observer";async assess(t){const r=m(t),s=o.map(e=>p.answer(e,r,t));return{score:s.filter(e=>e.basis==="stated").length/s.length,criteria:s}}static answer(t,r,s){const e=t.paths.flatMap(a=>p.resolve(a,r));if(e.length===0)return{id:t.id,paths:[]};const n=e.map(a=>s.provenance.at(a)?.basis??"stated");return{id:t.id,basis:d.find(a=>n.includes(a)),paths:e}}static resolve(t,r){let s=[{path:[],value:r}];for(const e of t.split("."))s=s.flatMap(({path:n,value:a})=>{if(typeof a!="object"||a===null)return[];if(e!=="*"){const i=a[e];return i===void 0?[]:[{path:[...n,e],value:i}]}return Object.entries(a).filter(([,i])=>i!==void 0).map(([i,h])=>({path:[...n,i],value:h}))});return s.filter(({value:e})=>e!==null&&e!==""&&!(Array.isArray(e)&&e.length===0)).map(({path:e})=>e.join("."))}}export{p as CoverageAssessor};
1
+ import{K as m}from"./rr0-sighting-editor.mjs";const o=[{id:"when",paths:["time.year","time.month","time.day","time.hour","time.minute","time.raw"]},{id:"where",paths:["place.*.lat","place.*.lng","observerTrack.keyframes.*.pose.lat","observerTrack.keyframes.*.pose.lng"]},{id:"facing",paths:["observerTrack.keyframes.*.pose.headingDeg"]},{id:"apparent-size",paths:["timeline.keyframes.*.shapes.*.shape.angular.widthDeg","timeline.keyframes.*.shapes.*.shape.angular.heightDeg"]},{id:"sky-position",paths:["timeline.keyframes.*.shapes.*.shape.aim.azimuthDeg","timeline.keyframes.*.shapes.*.shape.aim.altitudeDeg"]},{id:"how-long",paths:["durationSeconds","endTime.hour","endTime.minute","endTime.raw"]},{id:"appearance",paths:["timeline.keyframes.*.shapes.*.shape.kind","timeline.keyframes.*.shapes.*.shape.title","timeline.keyframes.*.shapes.*.shape.color","timeline.keyframes.*.shapes.*.shape.brightness"]},{id:"movement",paths:["timeline.keyframes.1.t","observerTrack.keyframes.1.t"]},{id:"sound",paths:["soundTrack.keyframes.*.sound.kind"]},{id:"conditions",paths:["weatherTrack.keyframes.*.weather.*","weather.*"]}],d=["assumed","derived","stated"];class p{about="observer";async assess(t){const r=m(t),s=o.map(e=>p.answer(e,r,t));return{score:s.filter(e=>e.basis==="stated").length/s.length,criteria:s}}static answer(t,r,s){const e=t.paths.flatMap(a=>p.resolve(a,r));if(e.length===0)return{id:t.id,paths:[]};const n=e.map(a=>s.provenance.at(a)?.basis??"stated");return{id:t.id,basis:d.find(a=>n.includes(a)),paths:e}}static resolve(t,r){let s=[{path:[],value:r}];for(const e of t.split("."))s=s.flatMap(({path:n,value:a})=>{if(typeof a!="object"||a===null)return[];if(e!=="*"){const i=a[e];return i===void 0?[]:[{path:[...n,e],value:i}]}return Object.entries(a).filter(([,i])=>i!==void 0).map(([i,h])=>({path:[...n,i],value:h}))});return s.filter(({value:e})=>e!==null&&e!==""&&!(Array.isArray(e)&&e.length===0)).map(({path:e})=>e.join("."))}}export{p as CoverageAssessor};
@@ -0,0 +1 @@
1
+ import{aq as Le,ar as Q,as as he,at as Me,au as v,av as de,aw as w,a5 as pe,ab as F,ax as b,ay as U,an as Se,az as ye,C as we,a9 as K,aA as be,J as C,aB as me,aC as Ne,aD as ge,aE as Ie,aF as Oe,ak as V,aG as Ce,aH as Te,aI as Fe,aJ as Pe,aK as He,aL as J,aM as Re,aN as Z,aO as ke,aP as De,ae as Ge,aQ as X,aR as ve,v as Ee,am as Ue,al as G,aS as Ke,ad as Be,aT as je,M as Ve,aU as Xe,aV as ze,aW as qe,af as We,G as z,F as Ye,aa as Qe,aX as Je,aY as Ze,aZ as $e,a_ as en,a$ as nn,b0 as tn,b1 as xe,a0 as sn,b2 as ne,b3 as te,b4 as se,b5 as ie,b6 as re,b7 as rn,b8 as on,w as an,x as cn}from"./rr0-sighting-editor.mjs";function oe(f,n){if(n===Le)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),f;if(n===Q||n===he){let e=f.getIndex();if(e===null){const r=[],a=f.getAttribute("position");if(a!==void 0){for(let o=0;o<a.count;o++)r.push(o);f.setIndex(r),e=f.getIndex()}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),f}const s=e.count-2,t=[];if(n===Q)for(let r=1;r<=s;r++)t.push(e.getX(0)),t.push(e.getX(r)),t.push(e.getX(r+1));else for(let r=0;r<s;r++)r%2===0?(t.push(e.getX(r)),t.push(e.getX(r+1)),t.push(e.getX(r+2))):(t.push(e.getX(r+2)),t.push(e.getX(r+1)),t.push(e.getX(r)));t.length/3!==s&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const i=f.clone();return i.setIndex(t),i.clearGroups(),i}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",n),f}class jn extends Me{constructor(n){super(n),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new dn(e)}),this.register(function(e){return new pn(e)}),this.register(function(e){return new Ln(e)}),this.register(function(e){return new Mn(e)}),this.register(function(e){return new Sn(e)}),this.register(function(e){return new gn(e)}),this.register(function(e){return new Tn(e)}),this.register(function(e){return new Rn(e)}),this.register(function(e){return new En(e)}),this.register(function(e){return new hn(e)}),this.register(function(e){return new xn(e)}),this.register(function(e){return new mn(e)}),this.register(function(e){return new _n(e)}),this.register(function(e){return new An(e)}),this.register(function(e){return new ln(e)}),this.register(function(e){return new ae(e,g.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new ae(e,g.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new yn(e)})}load(n,e,s,t){const i=this;let r;if(this.resourcePath!=="")r=this.resourcePath;else if(this.path!==""){const c=v.extractUrlBase(n);r=v.resolveURL(c,this.path)}else r=v.extractUrlBase(n);this.manager.itemStart(n);const a=function(c){t?t(c):console.error(c),i.manager.itemError(n),i.manager.itemEnd(n)},o=new de(this.manager);o.setPath(this.path),o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setWithCredentials(this.withCredentials),o.load(n,function(c){try{i.parse(c,r,function(u){e(u),i.manager.itemEnd(n)},a)}catch(u){a(u)}},s,a)}setDRACOLoader(n){return this.dracoLoader=n,this}setKTX2Loader(n){return this.ktx2Loader=n,this}setMeshoptDecoder(n){return this.meshoptDecoder=n,this}register(n){return this.pluginCallbacks.indexOf(n)===-1&&this.pluginCallbacks.push(n),this}unregister(n){return this.pluginCallbacks.indexOf(n)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(n),1),this}parse(n,e,s,t){let i;const r={},a={},o=new TextDecoder;if(typeof n=="string")i=JSON.parse(n);else if(n instanceof ArrayBuffer)if(o.decode(new Uint8Array(n,0,4))===Ae){try{r[g.KHR_BINARY_GLTF]=new wn(n)}catch(l){t&&t(l);return}i=JSON.parse(r[g.KHR_BINARY_GLTF].content)}else i=JSON.parse(o.decode(n));else i=n;if(i.asset===void 0||i.asset.version[0]<2){t&&t(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));return}const c=new Un(i,{path:e||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let u=0;u<this.pluginCallbacks.length;u++){const l=this.pluginCallbacks[u](c);l.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),a[l.name]=l,r[l.name]=!0}if(i.extensionsUsed)for(let u=0;u<i.extensionsUsed.length;++u){const l=i.extensionsUsed[u],h=i.extensionsRequired||[];switch(l){case g.KHR_MATERIALS_UNLIT:r[l]=new fn;break;case g.KHR_DRACO_MESH_COMPRESSION:r[l]=new bn(i,this.dracoLoader);break;case g.KHR_TEXTURE_TRANSFORM:r[l]=new Nn;break;case g.KHR_MESH_QUANTIZATION:r[l]=new In;break;default:h.indexOf(l)>=0&&a[l]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+l+'".')}}c.setExtensions(r),c.setPlugins(a),c.parse(s,t)}parseAsync(n,e){const s=this;return new Promise(function(t,i){s.parse(n,e,t,i)})}}function un(){let f={};return{get:function(n){return f[n]},add:function(n,e){f[n]=e},remove:function(n){delete f[n]},removeAll:function(){f={}}}}function _(f,n,e){const s=f.json.materials[n];return s.extensions&&s.extensions[e]?s.extensions[e]:null}const g={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",KHR_MESHOPT_COMPRESSION:"KHR_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class ln{constructor(n){this.parser=n,this.name=g.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const n=this.parser,e=this.parser.json.nodes||[];for(let s=0,t=e.length;s<t;s++){const i=e[s];i.extensions&&i.extensions[this.name]&&i.extensions[this.name].light!==void 0&&n._addNodeRef(this.cache,i.extensions[this.name].light)}}_loadLight(n){const e=this.parser,s="light:"+n;let t=e.cache.get(s);if(t)return t;const i=e.json,o=((i.extensions&&i.extensions[this.name]||{}).lights||[])[n];let c;const u=new F(16777215);o.color!==void 0&&u.setRGB(o.color[0],o.color[1],o.color[2],b);const l=o.range!==void 0?o.range:0;switch(o.type){case"directional":c=new we(u),c.target.position.set(0,0,-1),c.add(c.target);break;case"point":c=new ye(u),c.distance=l;break;case"spot":c=new Se(u),c.distance=l,o.spot=o.spot||{},o.spot.innerConeAngle=o.spot.innerConeAngle!==void 0?o.spot.innerConeAngle:0,o.spot.outerConeAngle=o.spot.outerConeAngle!==void 0?o.spot.outerConeAngle:Math.PI/4,c.angle=o.spot.outerConeAngle,c.penumbra=1-o.spot.innerConeAngle/o.spot.outerConeAngle,c.target.position.set(0,0,-1),c.add(c.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+o.type)}return c.position.set(0,0,0),y(c,o),o.intensity!==void 0&&(c.intensity=o.intensity),c.name=e.createUniqueName(o.name||"light_"+n),t=Promise.resolve(c),e.cache.add(s,t),t}getDependency(n,e){if(n==="light")return this._loadLight(e)}createNodeAttachment(n){const e=this,s=this.parser,i=s.json.nodes[n],a=(i.extensions&&i.extensions[this.name]||{}).light;return a===void 0?null:this._loadLight(a).then(function(o){return s._getNodeRef(e.cache,a,o)})}}class fn{constructor(){this.name=g.KHR_MATERIALS_UNLIT}getMaterialType(){return G}extendParams(n,e,s){const t=[];n.color=new F(1,1,1),n.opacity=1;const i=e.pbrMetallicRoughness;if(i){if(Array.isArray(i.baseColorFactor)){const r=i.baseColorFactor;n.color.setRGB(r[0],r[1],r[2],b),n.opacity=r[3]}i.baseColorTexture!==void 0&&t.push(s.assignTexture(n,"map",i.baseColorTexture,U))}return Promise.all(t)}}class hn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||s.emissiveStrength!==void 0&&(e.emissiveIntensity=s.emissiveStrength),Promise.resolve()}}class dn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_CLEARCOAT}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];if(s.clearcoatFactor!==void 0&&(e.clearcoat=s.clearcoatFactor),s.clearcoatTexture!==void 0&&t.push(this.parser.assignTexture(e,"clearcoatMap",s.clearcoatTexture)),s.clearcoatRoughnessFactor!==void 0&&(e.clearcoatRoughness=s.clearcoatRoughnessFactor),s.clearcoatRoughnessTexture!==void 0&&t.push(this.parser.assignTexture(e,"clearcoatRoughnessMap",s.clearcoatRoughnessTexture)),s.clearcoatNormalTexture!==void 0&&(t.push(this.parser.assignTexture(e,"clearcoatNormalMap",s.clearcoatNormalTexture)),s.clearcoatNormalTexture.scale!==void 0)){const i=s.clearcoatNormalTexture.scale;e.clearcoatNormalScale=new pe(i,i)}return Promise.all(t)}}class pn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_DISPERSION}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||(e.dispersion=s.dispersion!==void 0?s.dispersion:0),Promise.resolve()}}class mn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_IRIDESCENCE}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.iridescenceFactor!==void 0&&(e.iridescence=s.iridescenceFactor),s.iridescenceTexture!==void 0&&t.push(this.parser.assignTexture(e,"iridescenceMap",s.iridescenceTexture)),s.iridescenceIor!==void 0&&(e.iridescenceIOR=s.iridescenceIor),e.iridescenceThicknessRange===void 0&&(e.iridescenceThicknessRange=[100,400]),s.iridescenceThicknessMinimum!==void 0&&(e.iridescenceThicknessRange[0]=s.iridescenceThicknessMinimum),s.iridescenceThicknessMaximum!==void 0&&(e.iridescenceThicknessRange[1]=s.iridescenceThicknessMaximum),s.iridescenceThicknessTexture!==void 0&&t.push(this.parser.assignTexture(e,"iridescenceThicknessMap",s.iridescenceThicknessTexture)),Promise.all(t)}}class gn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_SHEEN}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];if(e.sheenColor=new F(0,0,0),e.sheenRoughness=0,e.sheen=1,s.sheenColorFactor!==void 0){const i=s.sheenColorFactor;e.sheenColor.setRGB(i[0],i[1],i[2],b)}return s.sheenRoughnessFactor!==void 0&&(e.sheenRoughness=s.sheenRoughnessFactor),s.sheenColorTexture!==void 0&&t.push(this.parser.assignTexture(e,"sheenColorMap",s.sheenColorTexture,U)),s.sheenRoughnessTexture!==void 0&&t.push(this.parser.assignTexture(e,"sheenRoughnessMap",s.sheenRoughnessTexture)),Promise.all(t)}}class Tn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_TRANSMISSION}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.transmissionFactor!==void 0&&(e.transmission=s.transmissionFactor),s.transmissionTexture!==void 0&&t.push(this.parser.assignTexture(e,"transmissionMap",s.transmissionTexture)),Promise.all(t)}}class Rn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_VOLUME}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];e.thickness=s.thicknessFactor!==void 0?s.thicknessFactor:0,s.thicknessTexture!==void 0&&t.push(this.parser.assignTexture(e,"thicknessMap",s.thicknessTexture)),e.attenuationDistance=s.attenuationDistance||1/0;const i=s.attenuationColor||[1,1,1];return e.attenuationColor=new F().setRGB(i[0],i[1],i[2],b),Promise.all(t)}}class En{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_IOR}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||(e.ior=s.ior!==void 0?s.ior:1.5,e.ior===0&&(e.ior=1e3)),Promise.resolve()}}class xn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_SPECULAR}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];e.specularIntensity=s.specularFactor!==void 0?s.specularFactor:1,s.specularTexture!==void 0&&t.push(this.parser.assignTexture(e,"specularIntensityMap",s.specularTexture));const i=s.specularColorFactor||[1,1,1];return e.specularColor=new F().setRGB(i[0],i[1],i[2],b),s.specularColorTexture!==void 0&&t.push(this.parser.assignTexture(e,"specularColorMap",s.specularColorTexture,U)),Promise.all(t)}}class An{constructor(n){this.parser=n,this.name=g.EXT_MATERIALS_BUMP}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return e.bumpScale=s.bumpFactor!==void 0?s.bumpFactor:1,s.bumpTexture!==void 0&&t.push(this.parser.assignTexture(e,"bumpMap",s.bumpTexture)),Promise.all(t)}}class _n{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_ANISOTROPY}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.anisotropyStrength!==void 0&&(e.anisotropy=s.anisotropyStrength),s.anisotropyRotation!==void 0&&(e.anisotropyRotation=s.anisotropyRotation),s.anisotropyTexture!==void 0&&t.push(this.parser.assignTexture(e,"anisotropyMap",s.anisotropyTexture)),Promise.all(t)}}class Ln{constructor(n){this.parser=n,this.name=g.KHR_TEXTURE_BASISU}loadTexture(n){const e=this.parser,s=e.json,t=s.textures[n];if(!t.extensions||!t.extensions[this.name])return null;const i=t.extensions[this.name],r=e.options.ktx2Loader;if(!r){if(s.extensionsRequired&&s.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return e.loadTextureImage(n,i.source,r)}}class Mn{constructor(n){this.parser=n,this.name=g.EXT_TEXTURE_WEBP}loadTexture(n){const e=this.name,s=this.parser,t=s.json,i=t.textures[n];if(!i.extensions||!i.extensions[e])return null;const r=i.extensions[e],a=t.images[r.source];let o=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(o=c)}return s.loadTextureImage(n,r.source,o)}}class Sn{constructor(n){this.parser=n,this.name=g.EXT_TEXTURE_AVIF}loadTexture(n){const e=this.name,s=this.parser,t=s.json,i=t.textures[n];if(!i.extensions||!i.extensions[e])return null;const r=i.extensions[e],a=t.images[r.source];let o=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(o=c)}return s.loadTextureImage(n,r.source,o)}}class ae{constructor(n,e){this.name=e,this.parser=n}loadBufferView(n){const e=this.parser.json,s=e.bufferViews[n];if(s.extensions&&s.extensions[this.name]){const t=s.extensions[this.name],i=this.parser.getDependency("buffer",t.buffer),r=this.parser.options.meshoptDecoder;if(!r||!r.supported){if(e.extensionsRequired&&e.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return i.then(function(a){const o=t.byteOffset||0,c=t.byteLength||0,u=t.count,l=t.byteStride,h=new Uint8Array(a,o,c);return r.decodeGltfBufferAsync?r.decodeGltfBufferAsync(u,l,h,t.mode,t.filter).then(function(d){return d.buffer}):r.ready.then(function(){const d=new ArrayBuffer(u*l);return r.decodeGltfBuffer(new Uint8Array(d),u,l,h,t.mode,t.filter),d})})}else return null}}class yn{constructor(n){this.name=g.EXT_MESH_GPU_INSTANCING,this.parser=n}createNodeMesh(n){const e=this.parser.json,s=e.nodes[n];if(!s.extensions||!s.extensions[this.name]||s.mesh===void 0)return null;const t=e.meshes[s.mesh];for(const c of t.primitives)if(c.mode!==M.TRIANGLES&&c.mode!==M.TRIANGLE_STRIP&&c.mode!==M.TRIANGLE_FAN&&c.mode!==void 0)return null;const r=s.extensions[this.name].attributes,a=[],o={};for(const c in r)a.push(this.parser.getDependency("accessor",r[c]).then(u=>(o[c]=u,o[c])));return a.length<1?null:(a.push(this.parser.createNodeMesh(n)),Promise.all(a).then(c=>{const u=c.pop(),l=u.isGroup?u.children:[u],h=c[0].count,d=[];for(const p of l){const R=new K,m=new C,T=new me,A=new C(1,1,1),x=new be(p.geometry,p.material,h);for(let E=0;E<h;E++)o.TRANSLATION&&m.fromBufferAttribute(o.TRANSLATION,E),o.ROTATION&&T.fromBufferAttribute(o.ROTATION,E),o.SCALE&&A.fromBufferAttribute(o.SCALE,E),x.setMatrixAt(E,R.compose(m,T,A));for(const E in o)if(E==="_COLOR_0"){const L=o[E];x.instanceColor=new Ne(L.array,L.itemSize,L.normalized)}else E!=="TRANSLATION"&&E!=="ROTATION"&&E!=="SCALE"&&p.geometry.setAttribute(E,o[E]);ge.prototype.copy.call(x,p),this.parser.assignFinalMaterial(x),d.push(x)}return u.isGroup?(u.clear(),u.add(...d),u):d[0]}))}}const Ae="glTF",D=12,ce={JSON:1313821514,BIN:5130562};class wn{constructor(n){this.name=g.KHR_BINARY_GLTF,this.content=null,this.body=null;const e=new DataView(n,0,D),s=new TextDecoder;if(this.header={magic:s.decode(new Uint8Array(n.slice(0,4))),version:e.getUint32(4,!0),length:e.getUint32(8,!0)},this.header.magic!==Ae)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const t=this.header.length-D,i=new DataView(n,D);let r=0;for(;r<t;){const a=i.getUint32(r,!0);r+=4;const o=i.getUint32(r,!0);if(r+=4,o===ce.JSON){const c=new Uint8Array(n,D+r,a);this.content=s.decode(c)}else if(o===ce.BIN){const c=D+r;this.body=n.slice(c,c+a)}r+=a}if(this.content===null)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class bn{constructor(n,e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=g.KHR_DRACO_MESH_COMPRESSION,this.json=n,this.dracoLoader=e,this.dracoLoader.preload()}decodePrimitive(n,e){const s=this.json,t=this.dracoLoader,i=n.extensions[this.name].bufferView,r=n.extensions[this.name].attributes,a={},o={},c={};for(const u in r){const l=$[u]||u.toLowerCase();a[l]=r[u]}for(const u in n.attributes){const l=$[u]||u.toLowerCase();if(r[u]!==void 0){const h=s.accessors[n.attributes[u]],d=H[h.componentType];c[l]=d.name,o[l]=h.normalized===!0}}return e.getDependency("bufferView",i).then(function(u){return new Promise(function(l,h){t.decodeDracoFile(u,function(d){for(const p in d.attributes){const R=d.attributes[p],m=o[p];m!==void 0&&(R.normalized=m)}l(d)},a,c,b,h)})})}}class Nn{constructor(){this.name=g.KHR_TEXTURE_TRANSFORM}extendTexture(n,e){return(e.texCoord===void 0||e.texCoord===n.channel)&&e.offset===void 0&&e.rotation===void 0&&e.scale===void 0||(n=n.clone(),e.texCoord!==void 0&&(n.channel=e.texCoord),e.offset!==void 0&&n.offset.fromArray(e.offset),e.rotation!==void 0&&(n.rotation=e.rotation),e.scale!==void 0&&n.repeat.fromArray(e.scale),n.needsUpdate=!0),n}}class In{constructor(){this.name=g.KHR_MESH_QUANTIZATION}}class _e extends on{constructor(n,e,s,t){super(n,e,s,t)}copySampleValue_(n){const e=this.resultBuffer,s=this.sampleValues,t=this.valueSize,i=n*t*3+t;for(let r=0;r!==t;r++)e[r]=s[i+r];return e}interpolate_(n,e,s,t){const i=this.resultBuffer,r=this.sampleValues,a=this.valueSize,o=a*2,c=a*3,u=t-e,l=(s-e)/u,h=l*l,d=h*l,p=n*c,R=p-c,m=-2*d+3*h,T=d-h,A=1-m,x=T-h+l;for(let E=0;E!==a;E++){const L=r[R+E+a],N=r[R+E+o]*u,S=r[p+E+a],k=r[p+E]*u;i[E]=A*L+x*N+m*S+T*k}return i}}const On=new me;class Cn extends _e{interpolate_(n,e,s,t){const i=super.interpolate_(n,e,s,t);return On.fromArray(i).normalize().toArray(i),i}}const M={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},H={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},ue={9728:Re,9729:J,9984:He,9985:Pe,9986:Fe,9987:Te},le={33071:De,33648:ke,10497:Z},q={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},$={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},I={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},Fn={CUBICSPLINE:void 0,LINEAR:xe,STEP:tn},W={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"};function Pn(f){return f.DefaultMaterial===void 0&&(f.DefaultMaterial=new Ee({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:rn})),f.DefaultMaterial}function O(f,n,e){for(const s in e.extensions)f[s]===void 0&&(n.userData.gltfExtensions=n.userData.gltfExtensions||{},n.userData.gltfExtensions[s]=e.extensions[s])}function y(f,n){n.extras!==void 0&&(typeof n.extras=="object"?Object.assign(f.userData,n.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+n.extras))}function Hn(f,n,e){let s=!1,t=!1,i=!1;for(let c=0,u=n.length;c<u;c++){const l=n[c];if(l.POSITION!==void 0&&(s=!0),l.NORMAL!==void 0&&(t=!0),l.COLOR_0!==void 0&&(i=!0),s&&t&&i)break}if(!s&&!t&&!i)return Promise.resolve(f);const r=[],a=[],o=[];for(let c=0,u=n.length;c<u;c++){const l=n[c];if(s){const h=l.POSITION!==void 0?e.getDependency("accessor",l.POSITION):f.attributes.position;r.push(h)}if(t){const h=l.NORMAL!==void 0?e.getDependency("accessor",l.NORMAL):f.attributes.normal;a.push(h)}if(i){const h=l.COLOR_0!==void 0?e.getDependency("accessor",l.COLOR_0):f.attributes.color;o.push(h)}}return Promise.all([Promise.all(r),Promise.all(a),Promise.all(o)]).then(function(c){const u=c[0],l=c[1],h=c[2];return s&&(f.morphAttributes.position=u),t&&(f.morphAttributes.normal=l),i&&(f.morphAttributes.color=h),f.morphTargetsRelative=!0,f})}function kn(f,n){if(f.updateMorphTargets(),n.weights!==void 0)for(let e=0,s=n.weights.length;e<s;e++)f.morphTargetInfluences[e]=n.weights[e];if(n.extras&&Array.isArray(n.extras.targetNames)){const e=n.extras.targetNames;if(f.morphTargetInfluences.length===e.length){f.morphTargetDictionary={};for(let s=0,t=e.length;s<t;s++)f.morphTargetDictionary[e[s]]=s}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function Dn(f){let n;const e=f.extensions&&f.extensions[g.KHR_DRACO_MESH_COMPRESSION];if(e?n="draco:"+e.bufferView+":"+e.indices+":"+Y(e.attributes):n=f.indices+":"+Y(f.attributes)+":"+f.mode,f.targets!==void 0)for(let s=0,t=f.targets.length;s<t;s++)n+=":"+Y(f.targets[s]);return n}function Y(f){let n="";const e=Object.keys(f).sort();for(let s=0,t=e.length;s<t;s++)n+=e[s]+":"+f[e[s]]+";";return n}function ee(f){switch(f){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}function Gn(f){return f.search(/\.jpe?g($|\?)/i)>0||f.search(/^data\:image\/jpeg/)===0?"image/jpeg":f.search(/\.webp($|\?)/i)>0||f.search(/^data\:image\/webp/)===0?"image/webp":f.search(/\.ktx2($|\?)/i)>0||f.search(/^data\:image\/ktx2/)===0?"image/ktx2":"image/png"}const vn=new K;class Un{constructor(n={},e={}){this.json=n,this.extensions={},this.plugins={},this.options=e,this.cache=new un,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let s=!1,t=-1,i=!1,r=-1;if(typeof navigator<"u"&&typeof navigator.userAgent<"u"){const a=navigator.userAgent;s=/^((?!chrome|android).)*safari/i.test(a)===!0;const o=a.match(/Version\/(\d+)/);t=s&&o?parseInt(o[1],10):-1,i=a.indexOf("Firefox")>-1,r=i?a.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>"u"||s&&t<17||i&&r<98?this.textureLoader=new Ie(this.options.manager):this.textureLoader=new Oe(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new de(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(n){this.extensions=n}setPlugins(n){this.plugins=n}parse(n,e){const s=this,t=this.json,i=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(r){return r._markDefs&&r._markDefs()}),Promise.all(this._invokeAll(function(r){return r.beforeRoot&&r.beforeRoot()})).then(function(){return Promise.all([s.getDependencies("scene"),s.getDependencies("animation"),s.getDependencies("camera")])}).then(function(r){const a={scene:r[0][t.scene||0],scenes:r[0],animations:r[1],cameras:r[2],asset:t.asset,parser:s,userData:{}};return O(i,a,t),y(a,t),Promise.all(s._invokeAll(function(o){return o.afterRoot&&o.afterRoot(a)})).then(function(){for(const o of a.scenes)o.updateMatrixWorld();n(a)})}).catch(e)}_markDefs(){const n=this.json.nodes||[],e=this.json.skins||[],s=this.json.meshes||[];for(let t=0,i=e.length;t<i;t++){const r=e[t].joints;for(let a=0,o=r.length;a<o;a++)n[r[a]].isBone=!0}for(let t=0,i=n.length;t<i;t++){const r=n[t];r.mesh!==void 0&&(this._addNodeRef(this.meshCache,r.mesh),r.skin!==void 0&&(s[r.mesh].isSkinnedMesh=!0)),r.camera!==void 0&&this._addNodeRef(this.cameraCache,r.camera)}}_addNodeRef(n,e){e!==void 0&&(n.refs[e]===void 0&&(n.refs[e]=n.uses[e]=0),n.refs[e]++)}_getNodeRef(n,e,s){if(n.refs[e]<=1)return s;const t=s.clone(),i=(r,a)=>{const o=this.associations.get(r);o!=null&&this.associations.set(a,o);for(const[c,u]of r.children.entries())i(u,a.children[c])};return i(s,t),t.name+="_instance_"+n.uses[e]++,t}_invokeOne(n){const e=Object.values(this.plugins);e.push(this);for(let s=0;s<e.length;s++){const t=n(e[s]);if(t)return t}return null}_invokeAll(n){const e=Object.values(this.plugins);e.unshift(this);const s=[];for(let t=0;t<e.length;t++){const i=n(e[t]);i&&s.push(i)}return s}getDependency(n,e){const s=n+":"+e;let t=this.cache.get(s);if(!t){switch(n){case"scene":t=this.loadScene(e);break;case"node":t=this._invokeOne(function(i){return i.loadNode&&i.loadNode(e)});break;case"mesh":t=this._invokeOne(function(i){return i.loadMesh&&i.loadMesh(e)});break;case"accessor":t=this.loadAccessor(e);break;case"bufferView":t=this._invokeOne(function(i){return i.loadBufferView&&i.loadBufferView(e)});break;case"buffer":t=this.loadBuffer(e);break;case"material":t=this._invokeOne(function(i){return i.loadMaterial&&i.loadMaterial(e)});break;case"texture":t=this._invokeOne(function(i){return i.loadTexture&&i.loadTexture(e)});break;case"skin":t=this.loadSkin(e);break;case"animation":t=this._invokeOne(function(i){return i.loadAnimation&&i.loadAnimation(e)});break;case"camera":t=this.loadCamera(e);break;default:if(t=this._invokeOne(function(i){return i!=this&&i.getDependency&&i.getDependency(n,e)}),!t)throw new Error("Unknown type: "+n);break}this.cache.add(s,t)}return t}getDependencies(n){let e=this.cache.get(n);if(!e){const s=this,t=this.json[n+(n==="mesh"?"es":"s")]||[];e=Promise.all(t.map(function(i,r){return s.getDependency(n,r)})),this.cache.add(n,e)}return e}loadBuffer(n){const e=this.json.buffers[n],s=this.fileLoader;if(e.type&&e.type!=="arraybuffer")throw new Error("THREE.GLTFLoader: "+e.type+" buffer type is not supported.");if(e.uri===void 0&&n===0)return Promise.resolve(this.extensions[g.KHR_BINARY_GLTF].body);const t=this.options;return new Promise(function(i,r){s.load(v.resolveURL(e.uri,t.path),i,void 0,function(){r(new Error('THREE.GLTFLoader: Failed to load buffer "'+e.uri+'".'))})})}loadBufferView(n){const e=this.json.bufferViews[n];return this.getDependency("buffer",e.buffer).then(function(s){const t=e.byteLength||0,i=e.byteOffset||0;return s.slice(i,i+t)})}loadAccessor(n){const e=this,s=this.json,t=this.json.accessors[n];if(t.bufferView===void 0&&t.sparse===void 0){const r=q[t.type],a=H[t.componentType],o=t.normalized===!0,c=new a(t.count*r);return Promise.resolve(new V(c,r,o))}const i=[];return t.bufferView!==void 0?i.push(this.getDependency("bufferView",t.bufferView)):i.push(null),t.sparse!==void 0&&(i.push(this.getDependency("bufferView",t.sparse.indices.bufferView)),i.push(this.getDependency("bufferView",t.sparse.values.bufferView))),Promise.all(i).then(function(r){const a=r[0],o=q[t.type],c=H[t.componentType],u=c.BYTES_PER_ELEMENT,l=u*o,h=t.byteOffset||0,d=t.bufferView!==void 0?s.bufferViews[t.bufferView].byteStride:void 0,p=t.normalized===!0;let R,m;if(d&&d!==l){const T=Math.floor(h/d),A="InterleavedBuffer:"+t.bufferView+":"+t.componentType+":"+T+":"+t.count;let x=e.cache.get(A);x||(R=new c(a,T*d,t.count*d/u),x=new Ce(R,d/u),e.cache.add(A,x)),m=new sn(x,o,h%d/u,p)}else a===null?R=new c(t.count*o):R=new c(a,h,t.count*o),m=new V(R,o,p);if(t.sparse!==void 0){const T=q.SCALAR,A=H[t.sparse.indices.componentType],x=t.sparse.indices.byteOffset||0,E=t.sparse.values.byteOffset||0,L=new A(r[1],x,t.sparse.count*T),N=new c(r[2],E,t.sparse.count*o);a!==null&&(m=new V(m.array.slice(),m.itemSize,m.normalized)),m.normalized=!1;for(let S=0,k=L.length;S<k;S++){const P=L[S];if(m.setX(P,N[S*o]),o>=2&&m.setY(P,N[S*o+1]),o>=3&&m.setZ(P,N[S*o+2]),o>=4&&m.setW(P,N[S*o+3]),o>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}m.normalized=p}return m})}loadTexture(n){const e=this.json,s=this.options,i=e.textures[n].source,r=e.images[i];let a=this.textureLoader;if(r.uri){const o=s.manager.getHandler(r.uri);o!==null&&(a=o)}return this.loadTextureImage(n,i,a)}loadTextureImage(n,e,s){const t=this,i=this.json,r=i.textures[n],a=i.images[e],o=(a.uri||a.bufferView)+":"+r.sampler;if(this.textureCache[o])return this.textureCache[o];const c=this.loadImageSource(e,s).then(function(u){u.flipY=!1,u.name=r.name||a.name||"",u.name===""&&typeof a.uri=="string"&&a.uri.startsWith("data:image/")===!1&&(u.name=a.uri);const h=(i.samplers||{})[r.sampler]||{};return u.magFilter=ue[h.magFilter]||J,u.minFilter=ue[h.minFilter]||Te,u.wrapS=le[h.wrapS]||Z,u.wrapT=le[h.wrapT]||Z,u.generateMipmaps=!u.isCompressedTexture&&u.minFilter!==Re&&u.minFilter!==J,t.associations.set(u,{textures:n}),u}).catch(function(){return null});return this.textureCache[o]=c,c}loadImageSource(n,e){const s=this,t=this.json,i=this.options;if(this.sourceCache[n]!==void 0)return this.sourceCache[n].then(l=>l.clone());const r=t.images[n],a=self.URL||self.webkitURL;let o=r.uri||"",c=!1;if(r.bufferView!==void 0)o=s.getDependency("bufferView",r.bufferView).then(function(l){c=!0;const h=new Blob([l],{type:r.mimeType});return o=a.createObjectURL(h),o});else if(r.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+n+" is missing URI and bufferView");const u=Promise.resolve(o).then(function(l){return new Promise(function(h,d){let p=h;e.isImageBitmapLoader===!0&&(p=function(R){const m=new ne(R);m.needsUpdate=!0,h(m)}),e.load(v.resolveURL(l,i.path),p,void 0,d)})}).then(function(l){return c===!0&&a.revokeObjectURL(o),y(l,r),l.userData.mimeType=r.mimeType||Gn(r.uri),l}).catch(function(l){throw console.error("THREE.GLTFLoader: Couldn't load texture",o),l});return this.sourceCache[n]=u,u}assignTexture(n,e,s,t){const i=this;return this.getDependency("texture",s.index).then(function(r){if(!r)return null;if(s.texCoord!==void 0&&s.texCoord>0&&(r=r.clone(),r.channel=s.texCoord),i.extensions[g.KHR_TEXTURE_TRANSFORM]){const a=s.extensions!==void 0?s.extensions[g.KHR_TEXTURE_TRANSFORM]:void 0;if(a){const o=i.associations.get(r);r=i.extensions[g.KHR_TEXTURE_TRANSFORM].extendTexture(r,a),i.associations.set(r,o)}}return t!==void 0&&(r.colorSpace=t),n[e]=r,r})}assignFinalMaterial(n){const e=n.geometry;let s=n.material;const t=e.attributes.tangent===void 0,i=e.attributes.color!==void 0,r=e.attributes.normal===void 0;if(n.isPoints){const a="PointsMaterial:"+s.uuid;let o=this.cache.get(a);o||(o=new Ge,X.prototype.copy.call(o,s),o.color.copy(s.color),o.map=s.map,o.sizeAttenuation=!1,this.cache.add(a,o)),s=o}else if(n.isLine){const a="LineBasicMaterial:"+s.uuid;let o=this.cache.get(a);o||(o=new ve,X.prototype.copy.call(o,s),o.color.copy(s.color),o.map=s.map,this.cache.add(a,o)),s=o}if(t||i||r){let a="ClonedMaterial:"+s.uuid+":";t&&(a+="derivative-tangents:"),i&&(a+="vertex-colors:"),r&&(a+="flat-shading:");let o=this.cache.get(a);o||(o=s.clone(),i&&(o.vertexColors=!0),r&&(o.flatShading=!0),t&&(o.normalScale&&(o.normalScale.y*=-1),o.clearcoatNormalScale&&(o.clearcoatNormalScale.y*=-1)),this.cache.add(a,o),this.associations.set(o,this.associations.get(s))),s=o}n.material=s}getMaterialType(){return Ee}loadMaterial(n){const e=this,s=this.json,t=this.extensions,i=s.materials[n];let r;const a={},o=i.extensions||{},c=[];if(o[g.KHR_MATERIALS_UNLIT]){const l=t[g.KHR_MATERIALS_UNLIT];r=l.getMaterialType(),c.push(l.extendParams(a,i,e))}else{const l=i.pbrMetallicRoughness||{};if(a.color=new F(1,1,1),a.opacity=1,Array.isArray(l.baseColorFactor)){const h=l.baseColorFactor;a.color.setRGB(h[0],h[1],h[2],b),a.opacity=h[3]}l.baseColorTexture!==void 0&&c.push(e.assignTexture(a,"map",l.baseColorTexture,U)),a.metalness=l.metallicFactor!==void 0?l.metallicFactor:1,a.roughness=l.roughnessFactor!==void 0?l.roughnessFactor:1,l.metallicRoughnessTexture!==void 0&&(c.push(e.assignTexture(a,"metalnessMap",l.metallicRoughnessTexture)),c.push(e.assignTexture(a,"roughnessMap",l.metallicRoughnessTexture))),r=this._invokeOne(function(h){return h.getMaterialType&&h.getMaterialType(n)}),c.push(Promise.all(this._invokeAll(function(h){return h.extendMaterialParams&&h.extendMaterialParams(n,a)})))}i.doubleSided===!0&&(a.side=Ue);const u=i.alphaMode||W.OPAQUE;if(u===W.BLEND?(a.transparent=!0,a.depthWrite=!1):(a.transparent=!1,u===W.MASK&&(a.alphaTest=i.alphaCutoff!==void 0?i.alphaCutoff:.5)),i.normalTexture!==void 0&&r!==G&&(c.push(e.assignTexture(a,"normalMap",i.normalTexture)),a.normalScale=new pe(1,1),i.normalTexture.scale!==void 0)){const l=i.normalTexture.scale;a.normalScale.set(l,l)}if(i.occlusionTexture!==void 0&&r!==G&&(c.push(e.assignTexture(a,"aoMap",i.occlusionTexture)),i.occlusionTexture.strength!==void 0&&(a.aoMapIntensity=i.occlusionTexture.strength)),i.emissiveFactor!==void 0&&r!==G){const l=i.emissiveFactor;a.emissive=new F().setRGB(l[0],l[1],l[2],b)}return i.emissiveTexture!==void 0&&r!==G&&c.push(e.assignTexture(a,"emissiveMap",i.emissiveTexture,U)),Promise.all(c).then(function(){const l=new r(a);return i.name&&(l.name=i.name),y(l,i),e.associations.set(l,{materials:n}),i.extensions&&O(t,l,i),l})}createUniqueName(n){const e=Ke.sanitizeNodeName(n||"");return e in this.nodeNamesUsed?e+"_"+ ++this.nodeNamesUsed[e]:(this.nodeNamesUsed[e]=0,e)}loadGeometries(n){const e=this,s=this.extensions,t=this.primitiveCache;function i(a){return s[g.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(a,e).then(function(o){return fe(o,a,e)})}const r=[];for(let a=0,o=n.length;a<o;a++){const c=n[a],u=Dn(c),l=t[u];if(l)r.push(l.promise);else{let h;c.extensions&&c.extensions[g.KHR_DRACO_MESH_COMPRESSION]?h=i(c):h=fe(new Be,c,e),t[u]={primitive:c,promise:h},r.push(h)}}return Promise.all(r)}loadMesh(n){const e=this,s=this.json,t=this.extensions,i=s.meshes[n],r=i.primitives,a=[];for(let o=0,c=r.length;o<c;o++){const u=r[o].material===void 0?Pn(this.cache):this.getDependency("material",r[o].material);a.push(u)}return a.push(e.loadGeometries(r)),Promise.all(a).then(function(o){const c=o.slice(0,o.length-1),u=o[o.length-1],l=[];for(let d=0,p=u.length;d<p;d++){const R=u[d],m=r[d];let T;const A=c[d];if(m.mode===M.TRIANGLES||m.mode===M.TRIANGLE_STRIP||m.mode===M.TRIANGLE_FAN||m.mode===void 0)T=i.isSkinnedMesh===!0?new je(R,A):new Ve(R,A),T.isSkinnedMesh===!0&&T.normalizeSkinWeights(),m.mode===M.TRIANGLE_STRIP?T.geometry=oe(T.geometry,he):m.mode===M.TRIANGLE_FAN&&(T.geometry=oe(T.geometry,Q));else if(m.mode===M.LINES)T=new Xe(R,A);else if(m.mode===M.LINE_STRIP)T=new ze(R,A);else if(m.mode===M.LINE_LOOP)T=new qe(R,A);else if(m.mode===M.POINTS)T=new We(R,A);else throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+m.mode);Object.keys(T.geometry.morphAttributes).length>0&&kn(T,i),T.name=e.createUniqueName(i.name||"mesh_"+n),y(T,i),m.extensions&&O(t,T,m),e.assignFinalMaterial(T),l.push(T)}for(let d=0,p=l.length;d<p;d++)e.associations.set(l[d],{meshes:n,primitives:d});if(l.length===1)return i.extensions&&O(t,l[0],i),l[0];const h=new z;i.extensions&&O(t,h,i),e.associations.set(h,{meshes:n});for(let d=0,p=l.length;d<p;d++)h.add(l[d]);return h})}loadCamera(n){let e;const s=this.json.cameras[n],t=s[s.type];if(!t){console.warn("THREE.GLTFLoader: Missing camera parameters.");return}return s.type==="perspective"?e=new Ye(Qe.radToDeg(t.yfov),t.aspectRatio||1,t.znear||1,t.zfar||2e6):s.type==="orthographic"&&(e=new Je(-t.xmag,t.xmag,t.ymag,-t.ymag,t.znear,t.zfar)),s.name&&(e.name=this.createUniqueName(s.name)),y(e,s),Promise.resolve(e)}loadSkin(n){const e=this.json.skins[n],s=[];for(let t=0,i=e.joints.length;t<i;t++)s.push(this._loadNodeShallow(e.joints[t]));return e.inverseBindMatrices!==void 0?s.push(this.getDependency("accessor",e.inverseBindMatrices)):s.push(null),Promise.all(s).then(function(t){const i=t.pop(),r=t,a=[],o=[];for(let c=0,u=r.length;c<u;c++){const l=r[c];if(l){a.push(l);const h=new K;i!==null&&h.fromArray(i.array,c*16),o.push(h)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',e.joints[c])}return new Ze(a,o)})}loadAnimation(n){const e=this.json,s=this,t=e.animations[n],i=t.name?t.name:"animation_"+n,r=[],a=[],o=[],c=[],u=[];for(let l=0,h=t.channels.length;l<h;l++){const d=t.channels[l],p=t.samplers[d.sampler],R=d.target,m=R.node,T=t.parameters!==void 0?t.parameters[p.input]:p.input,A=t.parameters!==void 0?t.parameters[p.output]:p.output;R.node!==void 0&&(r.push(this.getDependency("node",m)),a.push(this.getDependency("accessor",T)),o.push(this.getDependency("accessor",A)),c.push(p),u.push(R))}return Promise.all([Promise.all(r),Promise.all(a),Promise.all(o),Promise.all(c),Promise.all(u)]).then(function(l){const h=l[0],d=l[1],p=l[2],R=l[3],m=l[4],T=[];for(let x=0,E=h.length;x<E;x++){const L=h[x],N=d[x],S=p[x],k=R[x],P=m[x];if(L===void 0)continue;L.updateMatrix&&L.updateMatrix();const B=s._createAnimationTracks(L,N,S,k,P);if(B)for(let j=0;j<B.length;j++)T.push(B[j])}const A=new $e(i,void 0,T);return y(A,t),A})}createNodeMesh(n){const e=this.json,s=this,t=e.nodes[n];return t.mesh===void 0?null:s.getDependency("mesh",t.mesh).then(function(i){const r=s._getNodeRef(s.meshCache,t.mesh,i);return t.weights!==void 0&&r.traverse(function(a){if(a.isMesh)for(let o=0,c=t.weights.length;o<c;o++)a.morphTargetInfluences[o]=t.weights[o]}),r})}loadNode(n){const e=this.json,s=this,t=e.nodes[n],i=s._loadNodeShallow(n),r=[],a=t.children||[];for(let c=0,u=a.length;c<u;c++)r.push(s.getDependency("node",a[c]));const o=t.skin===void 0?Promise.resolve(null):s.getDependency("skin",t.skin);return Promise.all([i,Promise.all(r),o]).then(function(c){const u=c[0],l=c[1],h=c[2];h!==null&&u.traverse(function(d){d.isSkinnedMesh&&d.bind(h,vn)});for(let d=0,p=l.length;d<p;d++)u.add(l[d]);if(u.userData.pivot!==void 0&&l.length>0){const d=u.userData.pivot,p=l[0];u.pivot=new C().fromArray(d),u.position.x-=d[0],u.position.y-=d[1],u.position.z-=d[2],p.position.set(0,0,0),delete u.userData.pivot}return u})}_loadNodeShallow(n){const e=this.json,s=this.extensions,t=this;if(this.nodeCache[n]!==void 0)return this.nodeCache[n];const i=e.nodes[n],r=i.name?t.createUniqueName(i.name):"",a=[],o=t._invokeOne(function(c){return c.createNodeMesh&&c.createNodeMesh(n)});return o&&a.push(o),i.camera!==void 0&&a.push(t.getDependency("camera",i.camera).then(function(c){return t._getNodeRef(t.cameraCache,i.camera,c)})),t._invokeAll(function(c){return c.createNodeAttachment&&c.createNodeAttachment(n)}).forEach(function(c){a.push(c)}),this.nodeCache[n]=Promise.all(a).then(function(c){let u;if(i.isBone===!0?u=new en:c.length>1?u=new z:c.length===1?u=c[0]:u=new ge,u!==c[0])for(let l=0,h=c.length;l<h;l++)u.add(c[l]);if(i.name&&(u.userData.name=i.name,u.name=r),y(u,i),i.extensions&&O(s,u,i),i.matrix!==void 0){const l=new K;l.fromArray(i.matrix),u.applyMatrix4(l)}else i.translation!==void 0&&u.position.fromArray(i.translation),i.rotation!==void 0&&u.quaternion.fromArray(i.rotation),i.scale!==void 0&&u.scale.fromArray(i.scale);if(!t.associations.has(u))t.associations.set(u,{});else if(i.mesh!==void 0&&t.meshCache.refs[i.mesh]>1){const l=t.associations.get(u);t.associations.set(u,{...l})}return t.associations.get(u).nodes=n,u}),this.nodeCache[n]}loadScene(n){const e=this.extensions,s=this.json.scenes[n],t=this,i=new z;s.name&&(i.name=t.createUniqueName(s.name)),y(i,s),s.extensions&&O(e,i,s);const r=s.nodes||[],a=[];for(let o=0,c=r.length;o<c;o++)a.push(t.getDependency("node",r[o]));return Promise.all(a).then(function(o){for(let u=0,l=o.length;u<l;u++){const h=o[u];h.parent!==null?i.add(nn(h)):i.add(h)}const c=u=>{const l=new Map;for(const[h,d]of t.associations)(h instanceof X||h instanceof ne)&&l.set(h,d);return u.traverse(h=>{const d=t.associations.get(h);d!=null&&l.set(h,d)}),l};return t.associations=c(i),i})}_createAnimationTracks(n,e,s,t,i){const r=[],a=n.name?n.name:n.uuid,o=[];function c(d){d.morphTargetInfluences&&o.push(d.name?d.name:d.uuid)}I[i.path]===I.weights?(c(n),n.isGroup&&n.children.forEach(c)):o.push(a);let u;switch(I[i.path]){case I.weights:u=se;break;case I.rotation:u=ie;break;case I.translation:case I.scale:u=te;break;default:switch(s.itemSize){case 1:u=se;break;case 2:case 3:default:u=te;break}break}const l=t.interpolation!==void 0?Fn[t.interpolation]:xe,h=this._getArrayFromAccessor(s);for(let d=0,p=o.length;d<p;d++){const R=new u(o[d]+"."+I[i.path],e.array,h,l);t.interpolation==="CUBICSPLINE"&&this._createCubicSplineTrackInterpolant(R),r.push(R)}return r}_getArrayFromAccessor(n){let e=n.array;if(n.normalized){const s=ee(e.constructor),t=new Float32Array(e.length);for(let i=0,r=e.length;i<r;i++)t[i]=e[i]*s;e=t}return e}_createCubicSplineTrackInterpolant(n){n.createInterpolant=function(s){const t=this instanceof ie?Cn:_e;return new t(this.times,this.values,this.getValueSize()/3,s)},n.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function Kn(f,n,e){const s=n.attributes,t=new an;if(s.POSITION!==void 0){const a=e.json.accessors[s.POSITION],o=a.min,c=a.max;if(o!==void 0&&c!==void 0){if(t.set(new C(o[0],o[1],o[2]),new C(c[0],c[1],c[2])),a.normalized){const u=ee(H[a.componentType]);t.min.multiplyScalar(u),t.max.multiplyScalar(u)}}else{console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");return}}else return;const i=n.targets;if(i!==void 0){const a=new C,o=new C;for(let c=0,u=i.length;c<u;c++){const l=i[c];if(l.POSITION!==void 0){const h=e.json.accessors[l.POSITION],d=h.min,p=h.max;if(d!==void 0&&p!==void 0){if(o.setX(Math.max(Math.abs(d[0]),Math.abs(p[0]))),o.setY(Math.max(Math.abs(d[1]),Math.abs(p[1]))),o.setZ(Math.max(Math.abs(d[2]),Math.abs(p[2]))),h.normalized){const R=ee(H[h.componentType]);o.multiplyScalar(R)}a.max(o)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}t.expandByVector(a)}f.boundingBox=t;const r=new cn;t.getCenter(r.center),r.radius=t.min.distanceTo(t.max)/2,f.boundingSphere=r}function fe(f,n,e){const s=n.attributes,t=[];function i(r,a){return e.getDependency("accessor",r).then(function(o){f.setAttribute(a,o)})}for(const r in s){const a=$[r]||r.toLowerCase();a in f.attributes||t.push(i(s[r],a))}if(n.indices!==void 0&&!f.index){const r=e.getDependency("accessor",n.indices).then(function(a){f.setIndex(a)});t.push(r)}return re.workingColorSpace!==b&&"COLOR_0"in s&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${re.workingColorSpace}" not supported.`),y(f,n),Kn(f,n,e),Promise.all(t).then(function(){return n.targets!==void 0?Hn(f,n.targets,e):f})}export{jn as GLTFLoader};
@@ -0,0 +1,34 @@
1
+ import{an as A,M as g,J as P,ao as h,ad as C,ak as E,a2 as L,ab as x,am as R,ap as I}from"./rr0-sighting-editor.mjs";class i{constructor(e){this.scene=e}static REAL_BEAMS=4;static LAMPS=2;static DISTANCE_M=500;static AIR_LENGTH_M=90;static CLEAR_AIR_SCATTER_PER_M=2e-4;static SHADOW_MAP_PX=1024;beams=new Map;static airGeometry;has(e){return this.beams.has(e)}get size(){return this.beams.size}lamps(e){return this.beams.get(e)?.lamps??[]}airMeshes(e){return this.beams.get(e)?.air??[]}add(e){if(this.beams.has(e))return!0;if(this.beams.size>=i.REAL_BEAMS)return!1;const t=[],r=[];for(let n=0;n<i.LAMPS;n++){const a=new A(16777215,0,i.DISTANCE_M,Math.PI/8,.5,2);a.castShadow=e==="observer",a.shadow.mapSize.set(i.SHADOW_MAP_PX,i.SHADOW_MAP_PX),a.shadow.camera.near=.4,a.shadow.camera.far=110,a.shadow.bias=-4e-4,a.shadow.normalBias=.04,a.shadow.radius=2,this.scene.add(a),this.scene.add(a.target),t.push(a);const o=new g(i.airCone(),i.airMaterial());o.visible=!1,o.frustumCulled=!1,o.renderOrder=8,o.castShadow=!1,o.receiveShadow=!1,o.name="headlight air",this.scene.add(o),r.push(o)}return this.beams.set(e,{lamps:t,air:r}),!0}remove(e){const t=this.beams.get(e);if(t){for(const r of t.lamps)r.removeFromParent(),r.target.removeFromParent(),r.dispose();for(const r of t.air)r.removeFromParent(),r.material.dispose();this.beams.delete(e)}}clear(e){for(const t of[...this.beams.keys()])e&&t==="observer"||this.remove(t)}dispose(){this.clear(!1),i.airGeometry?.dispose(),i.airGeometry=void 0}aim(e,t,r,n,a,o,u){const c=this.beams.get(e),w=Math.max(u,i.CLEAR_AIR_SCATTER_PER_M);if(!c)return;const l=h.BEAMS[t],v=new P(-n.z,0,n.x),b=e==="observer"&&l!==void 0;c.lamps.forEach((s,d)=>{if(!l){s.intensity=0,c.air[d].visible=!1,s.shadow.autoUpdate=!1;return}const f=d===0?-1:1,m=l.pitchDeg*Math.PI/180,p=l.candela*h.DISPLAY_GAIN*o/c.lamps.length;s.color.set(l.color),s.intensity=p,s.angle=l.halfAngleDeg*Math.PI/180,s.penumbra=l.penumbra,b?(s.shadow.autoUpdate||(s.shadow.needsUpdate=!0),s.shadow.autoUpdate=!0):s.shadow.autoUpdate=!1,s.position.copy(r).addScaledVector(v,f*a);const M=n.clone().addScaledVector(v,-f*Math.tan(h.TOE_IN_DEG*Math.PI/180)).normalize();s.target.position.set(s.position.x+M.x*Math.cos(m)*50,s.position.y-Math.sin(m)*50,s.position.z+M.z*Math.cos(m)*50),s.target.updateMatrixWorld(),this.aimAir(c.air[d],s,l.color,p,w)})}aimAir(e,t,r,n,a){if(e.visible=a*n>1e-4,!e.visible)return;const o=i.AIR_LENGTH_M,u=o*Math.tan(t.angle);e.position.copy(t.position),e.scale.set(u,u,o),e.lookAt(t.target.position),e.updateMatrixWorld();const c=e.material.uniforms;c.uColor.value.set(r),c.uCandela.value=n,c.uScatter.value=a,c.uLength.value=o,c.uRadius.value=u}static airCone(){if(i.airGeometry)return i.airGeometry;const e=24,t=new Float32Array((e+1)*3);for(let a=0;a<e;a++){const o=a/e*Math.PI*2;t.set([Math.cos(o),Math.sin(o),1],(a+1)*3)}const r=[];for(let a=0;a<e;a++)r.push(0,1+a,1+(a+1)%e);const n=new C;return n.setAttribute("position",new E(t,3)),n.setIndex(r),i.airGeometry=n,n}static airMaterial(){return new L({transparent:!0,depthWrite:!1,depthTest:!0,blending:I,side:R,uniforms:{uColor:{value:new x(1,1,1)},uCandela:{value:0},uScatter:{value:0},uLength:{value:90},uRadius:{value:20}},vertexShader:`
2
+ varying vec3 vLocal;
3
+ varying vec3 vNormalView;
4
+ varying vec3 vViewDir;
5
+ void main() {
6
+ vLocal = position;
7
+ vec4 viewPosition = modelViewMatrix * vec4(position, 1.0);
8
+ // The side's normal, out of the axis: the apex has none (its length is nought), and a normal of nought there would spread NaN over the whole cone.
9
+ float ring = length(position.xy);
10
+ vec3 outward = ring > 1e-5 ? vec3(position.xy / ring, 0.0) : vec3(0.0, 0.0, 1.0);
11
+ vNormalView = normalize(normalMatrix * outward);
12
+ vViewDir = -viewPosition.xyz;
13
+ gl_Position = projectionMatrix * viewPosition;
14
+ }`,fragmentShader:`
15
+ uniform vec3 uColor;
16
+ uniform float uCandela;
17
+ uniform float uScatter;
18
+ uniform float uLength;
19
+ uniform float uRadius;
20
+ varying vec3 vLocal;
21
+ varying vec3 vNormalView;
22
+ varying vec3 vViewDir;
23
+ void main() {
24
+ float t = clamp(vLocal.z, 0.0, 1.0);
25
+ float distanceM = max(t * uLength, 1.5);
26
+ // The chord a ray makes through a cone of this thickness: long going along the beam, short going across its edge.
27
+ float facing = abs(dot(normalize(vNormalView), normalize(vViewDir + vec3(0.0, 0.0, 1e-4))));
28
+ float chord = 2.0 * uRadius * t * (0.25 + 0.75 * facing);
29
+ // The beam's own profile averaged over the chord: strongest on the axis, none at the edge of the cone.
30
+ float profile = 0.55;
31
+ float radiance = uScatter * uCandela * chord * profile / (distanceM * distanceM + 9.0);
32
+ float ends = (1.0 - smoothstep(0.75, 1.0, t)) * smoothstep(0.0, 0.04, t);
33
+ gl_FragColor = vec4(uColor * radiance * ends, 1.0);
34
+ }`})}}export{i as HeadlightSystem};
@@ -1 +1 @@
1
- import{w as r,x as c,y as l}from"./rr0-sighting-editor.mjs";const v=-6,p=150;class o{about="temporal";async assess(e){const t=o.daylight(e),i=e.decor.map((s,n)=>({object:s,index:n})).filter(({object:s})=>s.kind==="entity"),a=o.nearest(e),d=a!==void 0&&a<=p;return{verdict:i.length>0?"ce3":d?"ce1":t===void 0?void 0:t?"dd":"nl",criteria:[{id:"entities",basis:i.length>0?"stated":void 0,paths:i.map(({index:s})=>`decor.${s}`)},{id:"traces",paths:[],unsupported:!0},{id:"proximity",basis:a===void 0?void 0:"derived",paths:a===void 0?[]:["timeline","observerTrack"]},{id:"radar",paths:[],unsupported:!0},{id:"daylight",basis:t===void 0?void 0:"derived",paths:t===void 0?[]:["time","place"]}]}}static nearest(e){const t=e.timeline.sourceIds.map(i=>r.of(e,i)?.nearestM).filter(i=>i!==void 0);return t.length>0?Math.min(...t):void 0}static daylight(e){const t=e.event.place?.[0],i=e.event.time;if(!t||!i)return;const a=c(i,t.lng,e.event.utcOffsetHours);if(a)return l("Sun",a,{lat:t.lat,lng:t.lng,elevationM:0}).altitudeDeg>v}}export{o as HynekAssessor};
1
+ import{N as r,Q as c,X as l}from"./rr0-sighting-editor.mjs";const v=-6,p=150;class o{about="temporal";async assess(e){const t=o.daylight(e),i=e.decor.map((s,n)=>({object:s,index:n})).filter(({object:s})=>s.kind==="entity"),a=o.nearest(e),d=a!==void 0&&a<=p;return{verdict:i.length>0?"ce3":d?"ce1":t===void 0?void 0:t?"dd":"nl",criteria:[{id:"entities",basis:i.length>0?"stated":void 0,paths:i.map(({index:s})=>`decor.${s}`)},{id:"traces",paths:[],unsupported:!0},{id:"proximity",basis:a===void 0?void 0:"derived",paths:a===void 0?[]:["timeline","observerTrack"]},{id:"radar",paths:[],unsupported:!0},{id:"daylight",basis:t===void 0?void 0:"derived",paths:t===void 0?[]:["time","place"]}]}}static nearest(e){const t=e.timeline.sourceIds.map(i=>r.of(e,i)?.nearestM).filter(i=>i!==void 0);return t.length>0?Math.min(...t):void 0}static daylight(e){const t=e.event.place?.[0],i=e.event.time;if(!t||!i)return;const a=c(i,t.lng,e.event.utcOffsetHours);if(a)return l("Sun",a,{lat:t.lat,lng:t.lng,elevationM:0}).altitudeDeg>v}}export{o as HynekAssessor};
@@ -0,0 +1,101 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./SightingFileEditor-C0NC8jbz.js","./sightingSchema-kkSSrggd.js"])))=>i.map(i=>d[i]);
2
+ import{S as y,a as w,H as N,s as F,U as O,l as R,I as j,b,_ as k,c as I}from"./rr0-sighting-editor.mjs";import{interviewMessages_en as x}from"./InterviewMessages_en-cs-wWpmz.js";import{InterviewMedia as E}from"./InterviewMedia-CvAxC62V.js";import{InterviewFile as g}from"./interviewJson-CfwBPiuG.js";const C="rr0-interview",U=`
3
+ rr0-interview { display: block; --rr0-interview-line: color-mix(in srgb, currentColor 35%, transparent); }
4
+ rr0-interview [hidden] { display: none !important; }
5
+ rr0-interview .rr0-interview-status { font-size: .85em; opacity: .85; margin: 0 0 .5em; }
6
+ /* Scrolling only where a height is asked for: a box that scrolls keeps clear of the page's floated figures for all its height. */
7
+ rr0-interview .rr0-interview-turns { max-height: var(--rr0-interview-max-height, none); overflow-y: var(--rr0-interview-overflow, visible); }
8
+ rr0-interview .turn { position: relative; padding: .2em .5em; margin: 0 0 .4em; border-left: 3px solid var(--speaker); --speaker: hsl(var(--speaker-hue, 0) 55% 38%); }
9
+ @media (prefers-color-scheme: dark) { rr0-interview .turn { --speaker: hsl(var(--speaker-hue, 0) 65% 70%); } }
10
+ rr0-interview .turn { transition: background-color .15s; }
11
+ rr0-interview .turn:hover { background: color-mix(in srgb, var(--speaker) 7%, transparent); }
12
+ rr0-interview .turn.flash { background: color-mix(in srgb, #fc3 28%, transparent); }
13
+ rr0-interview .turn .who { font-size: .85em; font-weight: 600; color: var(--speaker); overflow-wrap: anywhere; }
14
+ rr0-interview .turn.is-redacted .who, rr0-interview .turn.goes-on .who { display: none; }
15
+ rr0-interview .turn.goes-on { margin-top: -.4em; padding-top: .6em; }
16
+ rr0-interview .turn .said, rr0-interview .turn .redacted { margin: 0; padding: 0; text-indent: 0; white-space: pre-wrap; }
17
+ rr0-interview .turn .said::before, rr0-interview .turn .said::after { content: none; }
18
+ /* Tooltips drawn here rather than left to the browser's own, which some hosts (an embedded pane) never show. */
19
+ rr0-interview .turn[data-time]:hover:not(:has(.bar:hover, .bar:focus, .said a:hover))::after { content: attr(data-time); position: absolute; right: .3em; top: .2em; z-index: 2;
20
+ padding: 0 .4em; border-radius: 3px; font-size: .8em; font-variant-numeric: tabular-nums; background: #222; color: #fff; pointer-events: none; }
21
+ rr0-interview .bar { position: relative; display: inline-block; width: 3em; height: .9em; vertical-align: -.1em; border-radius: 2px; background: currentColor; margin: 0 .2em; cursor: help; }
22
+ rr0-interview .bar::after { content: attr(data-tip); display: none; position: absolute; left: 0; top: 1.4em; z-index: 3; width: max-content; max-width: 22em; padding: .3em .5em;
23
+ border-radius: 4px; background: #222; color: #fff; font-size: .85em; line-height: 1.3; white-space: normal; }
24
+ rr0-interview .bar:hover::after, rr0-interview .bar:focus::after { display: block; }
25
+ rr0-interview .turn .refs { display: flex; flex-wrap: wrap; gap: .25em; }
26
+ rr0-interview .turn .ref { font: inherit; font-size: .8em; cursor: pointer; border: 1px solid var(--rr0-interview-line); border-radius: 999px; background: transparent; color: inherit;
27
+ padding: 0 .35em; font-variant-numeric: tabular-nums; white-space: nowrap; }
28
+ `;class T extends HTMLElement{messages=x;said=new y(["en"]);localeToken=0;loadToken=0;json;base;status=document.createElement("p");turns=document.createElement("div");blocks=new Map;constructor(){super(),this.status.className="rr0-interview-status",this.status.setAttribute("role","status"),this.turns.className="rr0-interview-turns"}static get observedAttributes(){return["src"]}attributeChangedCallback(e,t,i){e==="src"&&i!==t&&this.isConnected&&this.load()}connectedCallback(){T.styleRoot(this.getRootNode()),this.contains(this.turns)||this.replaceChildren(this.status,this.turns),this.loadLocale(),this.hasAttribute("src")&&this.json===void 0&&this.load()}get interview(){return this.json}set interview(e){this.loadToken++,this.json=e,this.draw()}set documentUrl(e){this.base=e}static styleRoot(e){const t=e instanceof ShadowRoot?e:document.head;if(t.querySelector("style[data-rr0-interview]"))return;const i=document.createElement("style");i.dataset.rr0Interview="",i.textContent=U,t.append(i)}async load(){const e=this.getAttribute("src"),t=++this.loadToken;if(!e)return;const i=new URL(e,location.href).href;let s;try{s=await w.json(i)}catch{s=void 0}t===this.loadToken&&(this.base=i,this.json=s,this.draw())}async loadLocale(){const e=++this.localeToken,t=N.preferencesFor(this),i=F(t,O),s=i==="en"?x:await R(i);e===this.localeToken&&(this.said=new y(t),this.messages=s,this.draw())}speakerName(e,t){const i=g.speakerName(e,t),s=e.speakers?.[t]?.role;return i===s&&s in this.messages.roles?this.messages.roles[s]:i}seek(e){const t=this.json,i={sighting:e.sighting??g.sightingsOf(t)[0],at:e.at};this.dispatchEvent(new CustomEvent(j,{bubbles:!0,composed:!0,detail:i}));const s=this.getAttribute("player");if(!s)return;const c=this.getRootNode().getElementById?.(s);typeof c?.seekTo=="function"&&(c.scrollIntoView?.({block:"center",behavior:"smooth"}),c.seekTo(i.at,i.sighting))}gap(e,t){const i=document.createElement(t),s=document.createElement("span");s.className="bar";const r=`${this.messages.redacted} : ${this.said.read(e)??""}`;return s.dataset.tip=r,s.tabIndex=0,s.setAttribute("role","img"),s.setAttribute("aria-label",r),i.append(s),i}saidNodes(e){if(!/[<&]/.test(e))return[document.createTextNode(e)];const t=document.createElement("template");t.innerHTML=e;for(const i of t.content.querySelectorAll("*")){if(["SCRIPT","STYLE","IFRAME","OBJECT","EMBED"].includes(i.tagName)){i.remove();continue}for(const s of[...i.attributes])if(/^on/i.test(s.name)||/^\s*javascript:/i.test(s.value))i.removeAttribute(s.name);else if(["href","src"].includes(s.name))try{s.value=new URL(s.value,this.base??location.href).href}catch{}}return[...t.content.childNodes]}draw(){const e=this.messages,t=this.json;this.blocks.clear();const i=Array.isArray(t?.segments)?t.segments:[];if(!t||i.length===0){this.status.hidden=!0;const a=document.createElement("p");a.textContent=e.exchangesEmpty,this.turns.replaceChildren(a);return}const s=t.speakers??{},r=Object.keys(s);if(t.proofreading){const a=r.filter(o=>!["approved","covered"].includes(t.proofreading?.[o]?.status??""));this.status.textContent=a.length===0?e.proofreadAll:e.proofreadPending.replace("{names}",a.map(o=>this.speakerName(t,o)).join(", ")),this.status.hidden=!1}else this.status.hidden=!0;const c=[];let n,p;i.forEach((a,o)=>{const h=a.redacted?JSON.stringify(a.redacted.reason):void 0;if(h!==void 0&&n?.reason===h){this.blocks.set(o,n.block);return}const l=document.createElement("div");l.className="turn",l.dataset.segment=String(o),l.style.setProperty("--speaker-hue",String((Math.max(0,r.indexOf(a.speaker))*67+210)%360));const v=document.createElement("div");v.className="who";const A=document.createElement("span");if(A.textContent=a.redacted?"":this.speakerName(t,a.speaker),a.start!==void 0&&(l.dataset.time=g.clock(a.start,!0)),!a.redacted&&p===a.speaker&&l.classList.add("goes-on"),p=a.redacted?void 0:a.speaker,v.append(A),a.redacted){l.classList.add("is-redacted");const u=this.gap(a.redacted.reason,"p");u.className="redacted",n={block:l,reason:h},l.append(v,u)}else{const u=document.createElement("p");if(u.className="said",a.parts){let f="";for(const m of a.parts){const L="redacted"in m?"▮":g.plain(m.text);/[\p{L}\p{N}.,;:!?)»”…▮]$/u.test(f)&&/^[\p{L}\p{N}(«“▮]/u.test(L)&&u.append(" "),"redacted"in m?u.append(this.gap(m.redacted.reason,"span")):u.append(...this.saidNodes(m.text)),f=L}}else u.append(...this.saidNodes(a.text??""));n=void 0,l.append(v,u)}if(a.refs?.length){const u=document.createElement("div");u.className="refs";for(const f of a.refs){const m=document.createElement("button");m.type="button",m.className="ref",m.textContent=`↗ ${g.clock(f.at,!0)}`,m.addEventListener("click",()=>this.seek(f)),u.append(m)}l.append(u)}this.blocks.set(o,l),c.push(l)}),this.turns.replaceChildren(...c)}revealSegment(e){const t=this.blocks.get(e);t&&(t.scrollIntoView?.({block:"center"}),t.classList.add("flash"),window.setTimeout(()=>t.classList.remove("flash"),1600))}}function B(){customElements.get(C)||customElements.define(C,T)}const S="rr0-interview-editor",M=`
29
+ <style>
30
+ :host { display: block; }
31
+ /* The colours of the transcript's text editor (see SightingFileEditor): a key, a string, a number or a word, and a mistake. Dark mode redefines them. */
32
+ :host { --file-key: #1a5fb4; --file-string: #26662f; --file-literal: #a5321f; --rr0-alert: #c33; }
33
+ @media (prefers-color-scheme: dark) { :host { --file-key: #8cb8ff; --file-string: #8fd39a; --file-literal: #ffa08a; } }
34
+ [hidden] { display: none !important; }
35
+ /* Two groups as the recording's editor has its own (see sightingEditorTemplate): the open tab raised and joined to its panel. */
36
+ .group-tabs { --tab-line: color-mix(in srgb, CanvasText 35%, transparent); --tab-surface: color-mix(in srgb, CanvasText 5%, Canvas);
37
+ --tab-recessed: color-mix(in srgb, CanvasText 11%, Canvas); --tab-accent: #4a9eff;
38
+ display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0; margin: 0; padding: 0; border-bottom: 1px solid var(--tab-line); }
39
+ .group-tab { font: inherit; font-weight: 600; cursor: pointer; color: color-mix(in srgb, CanvasText 70%, transparent); background: var(--tab-recessed);
40
+ border: 1px solid var(--tab-line); border-radius: 8px 8px 0 0; padding: .4em .6em; margin: 0 0 -1px -1px; position: relative; }
41
+ .group-tab:hover { color: CanvasText; background: color-mix(in srgb, CanvasText 16%, Canvas); }
42
+ .group-tab[aria-expanded="true"] { color: CanvasText; background: var(--tab-surface); border-bottom-color: var(--tab-surface); box-shadow: inset 0 2px 0 var(--tab-accent); z-index: 1; }
43
+ .group-tab:focus-visible { outline: 2px solid #4af; outline-offset: -2px; }
44
+ .group-panel { border: 1px solid var(--tab-line, color-mix(in srgb, CanvasText 35%, transparent)); border-top: 0; border-radius: 0 0 4px 4px;
45
+ background: color-mix(in srgb, CanvasText 5%, Canvas); padding: .5em .75em; margin: 0 0 .5em; }
46
+ .row { display: flex; align-items: center; gap: .5em; flex-wrap: wrap; margin-bottom: .5em; }
47
+ .group-panel > .row:last-child { margin-bottom: 0; }
48
+ label { display: flex; align-items: center; gap: .4em; }
49
+ label.wide { flex: 1 1 100%; align-items: flex-start; }
50
+ label.wide textarea { flex: 1 1 auto; min-width: 0; min-height: 9em; font: inherit; }
51
+ label.fill { flex: 1 1 100%; }
52
+ label.fill input { flex: 1 1 auto; }
53
+ input[type="text"] { min-width: 0; }
54
+ #by { width: 16em; }
55
+ input[type="url"] { width: 18em; max-width: 100%; }
56
+ /* Addresses and file names are read letter by letter. */
57
+ input[type="url"], #url { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
58
+ select { min-width: 0; max-width: 100%; text-overflow: ellipsis; }
59
+ fieldset.witnesses { display: flex; flex-wrap: wrap; align-items: center; gap: .25em .75em; border: 0; margin: 0; padding: 0; min-width: 0; }
60
+ fieldset.witnesses legend { float: left; padding: 0; margin-right: .4em; }
61
+ #exchanges { --rr0-interview-max-height: 32em; --rr0-interview-overflow: auto; }
62
+ .file-note { font-size: .85em; opacity: .8; margin: .3em 0; }
63
+ .file-editor { min-height: 18em; margin-top: .5em; }
64
+ </style>
65
+ <div id="tabs" class="group-tabs">
66
+ <button class="group-tab" type="button" aria-controls="group-summary" aria-expanded="true"><span id="label-summary-group">Summary</span></button>
67
+ <button class="group-tab" type="button" aria-controls="group-exchanges" aria-expanded="false"><span id="label-exchanges-group">Exchanges</span></button>
68
+ <button class="group-tab" type="button" aria-controls="group-transcript" aria-expanded="false"><span id="label-file-group">File</span></button>
69
+ </div>
70
+ <section class="group-panel" id="group-summary" aria-labelledby="label-summary-group">
71
+ <div class="row">
72
+ <label class="fill"><span id="label-title">Title</span> <input id="title" type="text"/></label>
73
+ </div>
74
+ <div class="row">
75
+ <fieldset id="witness" class="witnesses"><legend id="label-witness">Witness</legend></fieldset>
76
+ <label><span id="label-medium">Medium</span> <select id="medium"></select></label>
77
+ <label><span id="label-time">When</span> <input id="time" type="text" size="16" placeholder="2026-10-13 21:27"/></label>
78
+ <label><span id="label-by">Interviewer</span> <input id="by" type="text" autocomplete="off" spellcheck="false"/></label>
79
+ </div>
80
+ <div class="row">
81
+ <label class="wide"><span id="label-summary">What it established</span> <textarea id="summary"></textarea></label>
82
+ </div>
83
+ </section>
84
+ <section class="group-panel" id="group-exchanges" aria-labelledby="label-exchanges-group" hidden>
85
+ <rr0-interview id="exchanges"></rr0-interview>
86
+ </section>
87
+ <section class="group-panel" id="group-transcript" aria-labelledby="label-file-group" hidden>
88
+ <div class="row">
89
+ <label class="fill"><span id="label-url">Transcript</span> <input id="url" type="text" autocomplete="off" spellcheck="false" placeholder="interview-….json"/></label>
90
+ </div>
91
+ <div class="row toolbar">
92
+ <label><span id="label-import-file">Load JSON file</span> <input id="import-file" type="file" accept="application/json,.json,.txt,.md,.vtt,.srt,text/*"/></label>
93
+ <label><span id="label-import-url">Or load from URL</span> <input id="import-url" type="url" placeholder="https://…/interview.json"/></label>
94
+ <button id="import-url-button" type="button">Load</button>
95
+ <button id="save" type="button">Save</button>
96
+ </div>
97
+ <p id="file-note" class="file-note" hidden role="status"></p>
98
+ <div id="file-editor" class="file-editor"></div>
99
+ </section>
100
+ `;class d extends HTMLElement{shadow=this.attachShadow({mode:"open"});messages=x;said=new y(["en"]);language="en";localeToken=0;current;options=[];group="summary";base;text;fileEditor;fileEditorLoading;shownFor;constructor(){super(),this.shadow.innerHTML=M;for(const e of["title","time","by","url","summary","witness","medium"])this.shadow.getElementById(e).addEventListener(e==="witness"||e==="medium"?"change":"input",()=>this.write(e));for(const e of this.shadow.querySelectorAll("#tabs .group-tab"))e.addEventListener("click",()=>this.openGroup(d.GROUPS[e.getAttribute("aria-controls")]??"summary"));this.shadow.getElementById("url").addEventListener("change",()=>{this.shownFor=void 0,this.text===void 0&&this.group==="file"&&this.showTranscript()}),this.shadow.getElementById("import-file").addEventListener("change",()=>void this.importFromFile()),this.shadow.getElementById("import-url-button").addEventListener("click",()=>void this.importFromUrl()),this.shadow.getElementById("save").addEventListener("click",()=>this.save())}static GROUPS={"group-summary":"summary","group-exchanges":"exchanges","group-transcript":"file"};static get observedAttributes(){return["readonly"]}attributeChangedCallback(){this.applyReadonly()}connectedCallback(){this.loadLocale()}get event(){return this.current}set event(e){e!==this.current&&(this.shownFor=void 0),this.current=e,this.render(),this.group==="file"&&this.showTranscript(),this.group==="exchanges"&&this.showExchanges()}set witnesses(e){this.options=e,this.render()}set documentUrl(e){this.base=e}get transcriptText(){return this.text}set transcriptText(e){this.text=e,this.shownFor=void 0}field(e){return this.shadow.getElementById(e)}async loadLocale(){const e=++this.localeToken,t=N.preferencesFor(this),i=F(t,O),s=i==="en"?x:await R(i);e===this.localeToken&&(this.language=i,this.said=new y(t),this.messages=s,this.render())}applyReadonly(){const e=this.hasAttribute("readonly");for(const t of["title","time","by","url","summary"])this.field(t).readOnly=e;for(const t of this.shadow.querySelectorAll("#witness input"))t.disabled=e;this.field("medium").disabled=e;for(const t of["import-file","import-url","import-url-button"])this.field(t).disabled=e}static byText(e){return(e??[]).map(t=>"people"in t?t.people:"org"in t?t.org:t.title??"").filter(t=>t!=="").join(", ")}render(){const e=this.messages,t=(o,h)=>{this.shadow.getElementById(o).textContent=h};t("label-summary-group",e.summaryTab),t("label-file-group",e.fileTab),t("label-exchanges-group",e.exchangesTab),t("label-title",e.title),t("label-witness",e.witness),t("label-medium",e.medium),t("label-time",e.time),t("label-by",e.by),t("label-summary",e.summary),t("label-url",e.transcript),t("label-import-file",e.importFile),t("label-import-url",e.importUrl),t("import-url-button",e.importButton),t("save",e.saveButton),this.field("url").title=e.transcriptHint,this.field("by").title=e.byHint;const i=this.current,s=this.shadow.activeElement,r=(o,h)=>{this.field(o)!==s&&(this.field(o).value=h)};r("title",this.said.read(i?.title)??""),r("time",i?.time??""),r("by",d.byText(i?.by)),r("url",i?.url??""),r("summary",this.said.read(i?.summary)??"");const c=[i?.interviewOf].flat().filter(o=>typeof o=="string"),n=this.shadow.getElementById("witness"),p=[...this.options,...c.filter(o=>!this.options.some(h=>h.id===o)).map(o=>({id:o,label:o}))];n.replaceChildren(n.querySelector("legend"),...p.map(o=>{const h=document.createElement("label"),l=document.createElement("input");return l.type="checkbox",l.value=o.id,l.checked=c.includes(o.id),h.append(l,o.label),h}));const a=this.shadow.getElementById("medium");if(a.replaceChildren(...E.ALL.map(o=>new Option(E.label(o,this.language),o))),i?.medium!==void 0&&!E.ALL.includes(i.medium)&&a.append(new Option(String(i.medium),String(i.medium))),i?.medium===void 0){const o=new Option(e.witnessNone,"");o.disabled=!0,o.hidden=!0,a.prepend(o)}a.value=i?.medium??"",this.applyReadonly()}write(e){const t=this.current;if(!t)return;const i=e==="witness"?"":this.field(e).value;switch(e){case"title":{const s=this.said.write(t.title,i,this.language);s===void 0?delete t.title:t.title=s;break}case"summary":{const s=this.said.write(t.summary,i,this.language);s===void 0?delete t.summary:t.summary=s;break}case"time":i.trim()===""?delete t.time:t.time=i.trim();break;case"url":i.trim()===""?delete t.url:t.url=i.trim();break;case"by":{const s=i.split(",").map(r=>r.trim()).filter(r=>r!=="");s.length===0?delete t.by:t.by=s.map(r=>({people:r}));break}case"witness":{const s=[...this.shadow.querySelectorAll("#witness input:checked")].map(r=>r.value);if(s.length===0){this.render();return}t.interviewOf=s.length===1?s[0]:s;break}case"medium":i===""?delete t.medium:t.medium=i;break}this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{field:e,event:t}})),e==="medium"&&this.render(),e!=="url"&&this.syncFileFromEvent()}openGroup(e){this.group=e;const t={summary:"group-summary",exchanges:"group-exchanges",file:"group-transcript"};for(const i of this.shadow.querySelectorAll("#tabs .group-tab"))i.setAttribute("aria-expanded",String(i.getAttribute("aria-controls")===t[e]));for(const[i,s]of Object.entries(t))this.shadow.getElementById(s).hidden=i!==e;e==="file"&&this.showTranscript(),e==="exchanges"&&this.showExchanges()}exchangesToken=0;async transcriptJson(e){try{const t=this.fileEditor?.text??this.text;if(t!==void 0)return JSON.parse(t);const i=this.transcriptUrl(e);if(i!==void 0)return await w.json(i)}catch{}}async showExchanges(){const e=this.current;if(!e)return;const t=++this.exchangesToken,i=await this.transcriptJson(e);t!==this.exchangesToken||this.current!==e||this.drawExchanges(i)}drawExchanges(e){const t=this.shadow.getElementById("exchanges");t.documentUrl=this.current?this.transcriptUrl(this.current):void 0,t.interview=e}async revealSegment(e){this.openGroup("exchanges"),await this.showExchanges(),this.shadow.getElementById("exchanges").revealSegment(e)}note(e){const t=this.shadow.getElementById("file-note");t.textContent=e??"",t.hidden=e===void 0}transcriptUrl(e){return e.url?new URL(e.url,this.base??location.href).href:void 0}static pretty(e){return JSON.stringify(e,null,2)+`
101
+ `}static SHARED=["title","time","medium","by","interviewOf","summary"];static ORDER=["version","id","language","title","time","medium","by","interviewOf","summary","speakers","transcription","proofreading","anonymization","segments"];static ordered(e){const t={};for(const i of d.ORDER)i in e&&(t[i]=e[i]);for(const i of Object.keys(e))i in t||(t[i]=e[i]);return t}static witnessesOf(e){return[e].flat().filter(t=>typeof t=="string")}static withEventFields(e,t){const i={...e};for(const r of d.SHARED)t[r]===void 0?delete i[r]:i[r]=structuredClone(t[r]);const s=i.speakers;if(typeof s=="object"&&s!==null){const r={...s},c=(n,p,a)=>{a.forEach((o,h)=>{const l=h===0?n:`${n}${h+1}`;r[l]?r[l]={...r[l],[p]:o}:h>0&&(r[l]={role:n,[p]:o})})};c("interviewer","by",t.by??[]),c("witness","of",d.witnessesOf(t.interviewOf)),i.speakers=r}return d.ordered(i)}applyFileToEvent(e,t){const i=this.current;if(!i)return!1;const s=JSON.stringify(d.SHARED.map(n=>i[n])),r=n=>typeof n=="string"||typeof n=="object"&&n!==null&&!Array.isArray(n),c={title:r,summary:r,time:n=>typeof n=="string",medium:n=>typeof n=="string",by:n=>Array.isArray(n),interviewOf:n=>typeof n=="string"||Array.isArray(n)};for(const n of d.SHARED){const p=e[n];p!==void 0&&c[n](p)?i[n]=structuredClone(p):t&&delete i[n]}return JSON.stringify(d.SHARED.map(n=>i[n]))!==s}syncFileFromEvent(){const e=this.current,t=this.fileEditor?.text??this.text;if(!e||t===void 0)return;let i;try{i=JSON.parse(t)}catch{return}if(typeof i!="object"||i===null||Array.isArray(i))return;const s=d.pretty(d.withEventFields(i,e));s!==t&&(this.text=s,this.fileEditor?.replaceText(s,!1),this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{field:"transcript",event:e,text:s}})))}template(e){return d.pretty(d.withEventFields({version:1,language:this.language,speakers:{interviewer:{role:"interviewer"},witness:{role:"witness"}},segments:[]},e))}loadFileEditor(e){return this.fileEditorLoading??=(async()=>{try{const[{SightingFileEditor:t},{default:i},s]=await Promise.all([k(()=>import("./SightingFileEditor-C0NC8jbz.js"),__vite__mapDeps([0,1]),import.meta.url),k(()=>import("./interviewSchema-CMRZUnRy.js"),[],import.meta.url),I(this.language)]);return this.fileEditor=new t(this.shadow.getElementById("file-editor"),e,r=>this.onEdited(r),this.messages.editorLabel,{baseline:e,phrases:s.fileSearchPhrases,schema:i}),this.fileEditor}catch(t){throw this.fileEditorLoading=void 0,t}})(),this.fileEditorLoading}async showTranscript(){const e=this.current;if(!e||this.shownFor===e)return;this.note(this.messages.loading);let t=this.text;if(t===void 0){const i=this.transcriptUrl(e);if(i!==void 0)try{const s=await w.json(i);this.current===e&&typeof s=="object"&&s!==null&&!Array.isArray(s)?(this.applyFileToEvent(s,!1)&&this.fileChangedEvent(),t=d.pretty(d.withEventFields(s,e))):t=d.pretty(s)}catch{this.note(this.messages.loadFailed)}t??=this.template(e)}if(this.current===e)try{const i=await this.loadFileEditor(t);if(this.current!==e)return;i.replaceText(t,!1),this.shownFor=e,this.text!==void 0||this.transcriptUrl(e)===void 0?this.note(void 0):this.shadow.getElementById("file-note").textContent===this.messages.loading&&this.note(void 0)}catch{this.note(this.messages.loadFailed)}}onEdited(e){this.text=e;let t,i=!0;try{t=JSON.parse(e)}catch{i=!1}this.note(i?void 0:this.messages.invalid);const s=this.current;if(i&&s&&typeof t=="object"&&t!==null&&!Array.isArray(t)&&this.applyFileToEvent(t,!0)&&this.fileChangedEvent(),s&&!s.url&&e.trim()!==""){const r=s.id??"1";s.url=`${r.startsWith("interview")?r:`interview-${r}`}.json`,this.field("url").value=s.url,this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{field:"url",event:s}}))}this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{field:"transcript",event:s,text:e}})),this.group==="exchanges"&&this.showExchanges()}fileChangedEvent(){this.render(),this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{field:"file",event:this.current}}))}async take(e){if(typeof e!="object"||e===null||!Array.isArray(e.segments)){this.note(this.messages.notATranscript);return}const t=this.current;t&&this.applyFileToEvent(e,!1)&&this.fileChangedEvent();const i=d.pretty(t?d.withEventFields(e,t):e);await this.loadFileEditor(i).then(s=>s.replaceText(i,!1),()=>{}),this.shownFor=this.current,this.note(void 0),this.onEdited(i)}async importFromFile(){const e=this.field("import-file"),t=e.files?.[0];if(t){try{const i=await t.text();let s;try{s=JSON.parse(i)}catch{s=void 0}if(typeof s!="object"||s===null){const{InterviewImport:r}=await k(async()=>{const{InterviewImport:a}=await import("./interviewImport-C-TiARLK.js");return{InterviewImport:a}},[],import.meta.url),c=this.current,n=[c?.interviewOf].flat().filter(a=>typeof a=="string"),p=r.parse(i,{by:(c?.by??[]).map(a=>d.byText([a])).filter(a=>a!==""),witnesses:this.options.filter(a=>n.length===0||n.includes(a.id))});s=p&&{...p,transcription:{note:`Imported from ${t.name}: who speaks and when are as the file gave them, to be checked.`}}}s===void 0?this.note(this.messages.notATranscript):await this.take(s)}catch{this.note(this.messages.loadFailed)}e.value=""}}async importFromUrl(){const e=this.field("import-url").value.trim();if(e!=="")try{await this.take(await w.json(new URL(e,this.base??location.href).href))}catch{this.note(this.messages.loadFailed)}}save(){const e=this.fileEditor?.text??this.text;if(e===void 0)return;const t=(this.current?.url??"").split("/").pop()||`${this.current?.id??"interview"}.json`,i=URL.createObjectURL(new Blob([e],{type:"application/json"})),s=document.createElement("a");s.href=i,s.download=t,s.click(),URL.revokeObjectURL(i)}}function z(){B(),customElements.get(S)||customElements.define(S,d)}export{b as INTERVIEW_CHANGE_EVENT,S as INTERVIEW_EDITOR_ELEMENT_NAME,j as INTERVIEW_SEEK_EVENT,d as InterviewEditorElement,z as register};
@@ -0,0 +1 @@
1
+ class t{static LABELS={en:{"in-person":"In person",phone:"Phone",video:"Video call",chat:"Chat",email:"Email",letter:"Letter",other:"Other"},fr:{"in-person":"Face à face",phone:"Téléphone",video:"Visioconférence",chat:"Chat",email:"Mail",letter:"Courrier",other:"Autre"},es:{"in-person":"En persona",phone:"Teléfono",video:"Videollamada",chat:"Chat",email:"Correo electrónico",letter:"Carta",other:"Otro"},it:{"in-person":"Di persona",phone:"Telefono",video:"Videochiamata",chat:"Chat",email:"Email",letter:"Lettera",other:"Altro"}};static ALL=["in-person","phone","video","chat","email","letter","other"];static label(e,o){return t.LABELS[o][e]??e}}export{t as InterviewMedia};
@@ -0,0 +1 @@
1
+ const e={title:"Title",time:"When",by:"Interviewer",medium:"Medium",witness:"Witness",witnessNone:"—",summary:"Description",transcript:"Transcript",transcriptHint:"Address of the anonymised transcript file (optional)",summaryTab:"Summary",fileTab:"File",importFile:"Load a file (JSON, text, WebVTT, SRT)",importUrl:"Or load from URL",importButton:"Load",saveButton:"Save",loading:"Loading the transcript…",invalid:"This text is not valid JSON yet: the interview keeps the last transcript it understood.",notATranscript:"That file is not an interview transcript (it has no segments).",loadFailed:"That transcript could not be read.",editorLabel:"Interview transcript as JSON",byHint:"RR0 people ids, separated by commas",exchangesTab:"Exchanges",exchangesEmpty:"Nothing was said yet.",redacted:"Passage removed",proofreadAll:"Proofread by everyone.",proofreadPending:"Not proofread yet by: {names}",roles:{interviewer:"Interviewer",interviewee:"Interviewee",witness:"Witness"}};export{e as interviewMessages_en};
@@ -0,0 +1 @@
1
+ const e={title:"Título",time:"Fecha",by:"Entrevistador",medium:"Medio",witness:"Testigo",witnessNone:"—",summary:"Descripción",transcript:"Transcripción",transcriptHint:"Dirección del archivo de transcripción anonimizada (opcional)",summaryTab:"Resumen",fileTab:"Archivo",importFile:"Cargar un archivo (JSON, texto, WebVTT, SRT)",importUrl:"O desde una dirección",importButton:"Cargar",saveButton:"Guardar",loading:"Cargando la transcripción…",invalid:"Este texto aún no es JSON válido: la entrevista conserva la última transcripción que entendió.",notATranscript:"Ese archivo no es una transcripción de entrevista (no tiene turnos de palabra).",loadFailed:"No se pudo leer esa transcripción.",editorLabel:"Transcripción de la entrevista en JSON",byHint:"Identificadores de personas de RR0, separados por comas",exchangesTab:"Intercambios",exchangesEmpty:"Todavía no se ha dicho nada.",redacted:"Pasaje eliminado",proofreadAll:"Revisado por todos.",proofreadPending:"Aún no revisado por: {names}",roles:{interviewer:"Entrevistador",interviewee:"Entrevistado",witness:"Testigo"}};export{e as interviewMessages_es};
@@ -0,0 +1 @@
1
+ const e={title:"Titre",time:"Date",by:"Enquêteur",medium:"Moyen",witness:"Témoin",witnessNone:"—",summary:"Description",transcript:"Transcription",transcriptHint:"Adresse du fichier de transcription anonymisée (facultative)",summaryTab:"Résumé",fileTab:"Fichier",importFile:"Charger un fichier (JSON, texte, WebVTT, SRT)",importUrl:"Ou depuis une adresse",importButton:"Charger",saveButton:"Sauver",loading:"Chargement de la transcription…",invalid:"Ce texte n'est pas encore du JSON valide : l'interview garde la dernière transcription qu'elle a comprise.",notATranscript:"Ce fichier n'est pas une transcription d'interview (il n'a pas de tours de parole).",loadFailed:"Cette transcription n'a pas pu être lue.",editorLabel:"Transcription de l'interview en JSON",byHint:"Identifiants de personnes RR0, séparés par des virgules",exchangesTab:"Échanges",exchangesEmpty:"Rien n'a encore été dit.",redacted:"Passage retiré",proofreadAll:"Relu par tous les participants.",proofreadPending:"Pas encore relu par : {names}",roles:{interviewer:"Intervieweur",interviewee:"Interviewé",witness:"Témoin"}};export{e as interviewMessages_fr};
@@ -0,0 +1 @@
1
+ const i={title:"Titolo",time:"Data",by:"Intervistatore",medium:"Mezzo",witness:"Testimone",witnessNone:"—",summary:"Descrizione",transcript:"Trascrizione",transcriptHint:"Indirizzo del file di trascrizione anonimizzata (facoltativo)",summaryTab:"Riepilogo",fileTab:"File",importFile:"Carica un file (JSON, testo, WebVTT, SRT)",importUrl:"O da un indirizzo",importButton:"Carica",saveButton:"Salva",loading:"Caricamento della trascrizione…",invalid:"Questo testo non è ancora JSON valido: l'intervista conserva l'ultima trascrizione che ha capito.",notATranscript:"Quel file non è una trascrizione di intervista (non ha turni di parola).",loadFailed:"Impossibile leggere quella trascrizione.",editorLabel:"Trascrizione dell'intervista in JSON",byHint:"Identificatori di persone RR0, separati da virgole",exchangesTab:"Scambi",exchangesEmpty:"Non è stato ancora detto nulla.",redacted:"Passaggio rimosso",proofreadAll:"Rivisto da tutti.",proofreadPending:"Non ancora rivisto da: {names}",roles:{interviewer:"Intervistatore",interviewee:"Intervistato",witness:"Testimone"}};export{i as interviewMessages_it};
@@ -1,4 +1,4 @@
1
- import{L as h,c as r,U as p,d as m,P as c,E as u,b as g}from"./rr0-sighting-editor.mjs";import{launchEditorMessages_en as d}from"./LaunchEditorMessages_en-j4RgQPZu.js";class n{static plumeValue(e){return t=>h.plumeOf(t)[e]}static plume(e,t){return{type:"number",key:`plume.${e}`,effective:n.plumeValue(e),...t}}static burn(e,t){return{type:"number",key:e,min:-3600,max:36e3,step:.1,unit:"s",scale:.001,label:t.label,hint:t.hint,group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"},effective:a=>t.ends(a.track??[])?.t}}static nextPlace(e){const t=e[e.length-1]??{t:0,lat:0,lng:0,altitudeKm:0},a=e[e.length-2]??t,i=(s,l=0)=>e.length>1?t[s]-a[s]:l;return{t:t.t+(e.length>1?i("t"):1e4),lat:t.lat+i("lat"),lng:t.lng+i("lng"),altitudeKm:Math.max(0,t.altitudeKm+i("altitudeKm"))}}static SET={kind:"launch",title:{en:"Launch",fr:"Lancement",es:"Lanzamiento",it:"Lancio"},parameters:[{type:"said",key:"title",label:{en:"Name",fr:"Nom",es:"Nombre",it:"Nome"},group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"text",key:"vehicle.name",label:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"},placeholder:"Falcon 9",group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"text",key:"vehicle.mission",label:{en:"Mission",fr:"Mission",es:"Misión",it:"Missione"},placeholder:"Starlink Group 10-49",group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"number",key:"vehicle.engine.thrustKN",min:1,max:1e5,step:1,unit:"kN",label:{en:"Thrust (vacuum)",fr:"Poussée (dans le vide)",es:"Empuje (en el vacío)",it:"Spinta (nel vuoto)"},hint:{en:"Merlin Vacuum 934, RL10 110, a solid booster several thousand. With the specific impulse, it sets how much exhaust leaves each second.",fr:"Merlin Vacuum 934, RL10 110, un booster à poudre plusieurs milliers. Avec l'impulsion spécifique, elle fixe le débit d'échappement.",es:"Merlin Vacuum 934, RL10 110, un propulsor sólido varios miles. Con el impulso específico, fija el caudal de escape.",it:"Merlin Vacuum 934, RL10 110, un booster solido diverse migliaia. Con l'impulso specifico, fissa la portata dello scarico."},group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},{type:"number",key:"vehicle.engine.specificImpulseS",min:100,max:500,step:1,unit:"s",label:{en:"Specific impulse (vacuum)",fr:"Impulsion spécifique (dans le vide)",es:"Impulso específico (en el vacío)",it:"Impulso specifico (nel vuoto)"},hint:{en:"Times 9.81 m/s² it is the exhaust velocity, which sets how fast the exhaust spreads round the stage: 348 s is 3.4 km/s.",fr:"Multipliée par 9,81 m/s², c'est la vitesse d'éjection, qui fixe la vitesse à laquelle l'échappement s'étale autour de l'étage : 348 s font 3,4 km/s.",es:"Multiplicado por 9,81 m/s² es la velocidad de escape, que fija la rapidez con que el escape se extiende alrededor de la etapa: 348 s son 3,4 km/s.",it:"Moltiplicato per 9,81 m/s² è la velocità di scarico, che fissa quanto in fretta lo scarico si allarga attorno allo stadio: 348 s sono 3,4 km/s."},group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},{type:"choice",key:"vehicle.engine.propellant",label:{en:"Propellant",fr:"Ergols",es:"Propelentes",it:"Propellenti"},hint:{en:"What the exhaust is made of decides how much of it turns into particles that scatter light.",fr:"Ce dont l'échappement est fait décide quelle part devient des particules qui diffusent la lumière.",es:"De qué está hecho el escape decide qué parte se vuelve partículas que difunden la luz.",it:"Di cosa è fatto lo scarico decide quanta parte diventa particelle che diffondono la luce."},choices:[{value:"rp1-lox",label:{en:"Kerosene and oxygen",fr:"Kérosène et oxygène",es:"Queroseno y oxígeno",it:"Cherosene e ossigeno"}},{value:"methane-lox",label:{en:"Methane and oxygen",fr:"Méthane et oxygène",es:"Metano y oxígeno",it:"Metano e ossigeno"}},{value:"hydrogen-lox",label:{en:"Hydrogen and oxygen",fr:"Hydrogène et oxygène",es:"Hidrógeno y oxígeno",it:"Idrogeno e ossigeno"}},{value:"hypergolic",label:{en:"Hypergolic",fr:"Hypergolique",es:"Hipergólico",it:"Ipergolico"}},{value:"solid",label:{en:"Solid",fr:"Poudre",es:"Sólido",it:"Solido"}}],group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},n.burn("burnFromT",{label:{en:"Engine start",fr:"Allumage du moteur",es:"Encendido del motor",it:"Accensione del motore"},hint:{en:"When the engine started, in seconds of the recording; it may be before it. Empty: the first point of the path.",fr:"Quand le moteur s'est allumé, en secondes de l'enregistrement ; avant lui si besoin. Vide : le premier point du chemin.",es:"Cuándo se encendió el motor, en segundos de la grabación; puede ser antes. Vacío: el primer punto de la trayectoria.",it:"Quando si è acceso il motore, in secondi della registrazione; può essere prima. Vuoto: il primo punto del percorso."},ends:e=>e[0]}),n.burn("burnUntilT",{label:{en:"Engine cut-off",fr:"Extinction du moteur",es:"Apagado del motor",it:"Spegnimento del motore"},hint:{en:"When the engine stopped, in seconds of the recording. Empty: the last point of the path. Nothing is let go after it.",fr:"Quand le moteur s'est éteint, en secondes de l'enregistrement. Vide : le dernier point du chemin. Rien n'est lâché après.",es:"Cuándo se apagó el motor, en segundos de la grabación. Vacío: el último punto de la trayectoria. Nada se suelta después.",it:"Quando si è spento il motore, in secondi della registrazione. Vuoto: l'ultimo punto del percorso. Dopo non si rilascia nulla."},ends:e=>e[e.length-1]}),n.plume("exhaustKgPerS",{min:.1,max:1e5,step:.1,unit:"kg/s",label:{en:"Exhaust flow",fr:"Débit d'échappement",es:"Caudal de escape",it:"Portata di scarico"},hint:{en:"How much exhaust leaves the engine each second: how bright the plume is. Thrust over exhaust velocity when the engine is stated.",fr:"La masse d'échappement qui sort du moteur chaque seconde : la luminosité du panache. La poussée sur la vitesse d'éjection quand le moteur est donné.",es:"La masa de escape que sale del motor cada segundo: el brillo de la estela. El empuje sobre la velocidad de escape cuando se da el motor.",it:"La massa di scarico che esce dal motore ogni secondo: la luminosità della scia. La spinta sulla velocità di scarico quando il motore è dato."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("condensedShare",{min:0,max:1,step:.01,label:{en:"Share that scatters",fr:"Part qui diffuse",es:"Parte que difunde",it:"Parte che diffonde"},hint:{en:"The share of the exhaust that ends up as particles that scatter the Sun's light. Nobody has measured it for a launch: the one number to fit against a photograph.",fr:"La part de l'échappement qui devient des particules diffusant la lumière du Soleil. Personne ne l'a mesurée pour un lancement : le seul nombre à caler sur une photographie.",es:"La parte del escape que acaba como partículas que difunden la luz del Sol. Nadie la ha medido para un lanzamiento: el único número que ajustar con una fotografía.",it:"La parte dello scarico che diventa particelle che diffondono la luce del Sole. Nessuno l'ha misurata per un lancio: l'unico numero da tarare su una fotografia."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("particleRadiusUm",{min:.05,max:5,step:.05,unit:"µm",label:{en:"Particle radius",fr:"Rayon des particules",es:"Radio de las partículas",it:"Raggio delle particelle"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("lifetimeS",{min:10,max:3600,step:10,unit:"s",label:{en:"Trail lifetime",fr:"Durée de la traînée",es:"Duración de la estela",it:"Durata della scia"},hint:{en:"How long the narrow trail lasts before the particles have gone.",fr:"Combien de temps la traînée étroite dure avant que les particules aient disparu.",es:"Cuánto dura la estela estrecha antes de que las partículas hayan desaparecido.",it:"Quanto dura la scia stretta prima che le particelle siano sparite."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("expansionKmPerS",{min:0,max:5,step:.01,unit:"km/s",label:{en:"Trail spreading",fr:"Étalement de la traînée",es:"Expansión de la estela",it:"Espansione della scia"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("initialRadiusKm",{min:0,max:50,step:.1,unit:"km",label:{en:"Radius at release",fr:"Rayon au lâcher",es:"Radio al soltar",it:"Raggio al rilascio"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("collarShare",{min:0,max:1,step:.01,label:{en:"Share in the collar",fr:"Part dans la collerette",es:"Parte en el collar",it:"Parte nel collare"},hint:{en:"The collar is the exhaust just let go, which spreads fast into a wide short-lived shell round the stage; the rest stays behind as the narrow trail.",fr:"La collerette est l'échappement qui vient d'être lâché, qui s'étale vite en une coque large et brève autour de l'étage ; le reste demeure derrière en traînée étroite.",es:"El collar es el escape recién soltado, que se extiende rápido en una envoltura ancha y breve alrededor de la etapa; el resto queda detrás como estela estrecha.",it:"Il collare è lo scarico appena rilasciato, che si allarga in fretta in un guscio largo e breve attorno allo stadio; il resto resta dietro come scia stretta."},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}}),n.plume("collarExpansionKmPerS",{min:0,max:10,step:.05,unit:"km/s",label:{en:"Collar spreading",fr:"Étalement de la collerette",es:"Expansión del collar",it:"Espansione del collare"},hint:{en:"How fast the collar widens: three quarters of the exhaust velocity when the engine is stated.",fr:"La vitesse à laquelle la collerette s'élargit : les trois quarts de la vitesse d'éjection quand le moteur est donné.",es:"La rapidez con que el collar se ensancha: tres cuartos de la velocidad de escape cuando se da el motor.",it:"Quanto in fretta il collare si allarga: tre quarti della velocità di scarico quando il motore è dato."},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}}),n.plume("collarLifetimeS",{min:1,max:300,step:1,unit:"s",label:{en:"Collar lifetime",fr:"Durée de la collerette",es:"Duración del collar",it:"Durata del collare"},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}})]};static PLACE={kind:"launch-place",title:{en:"Place of the path",fr:"Point du chemin",es:"Punto de la trayectoria",it:"Punto del percorso"},parameters:[{type:"number",key:"t",min:-3600,max:36e3,step:.1,unit:"s",scale:.001,required:!0,label:{en:"Time",fr:"Instant",es:"Instante",it:"Istante"},hint:{en:"Seconds of the recording; negative before it began: a stage seen minutes after its launch was already high when the recording started.",fr:"Secondes de l'enregistrement ; négatives avant son début : un étage vu des minutes après son lancement était déjà haut quand l'enregistrement a commencé.",es:"Segundos de la grabación; negativos antes de que empezara: una etapa vista minutos después de su lanzamiento ya estaba alta cuando empezó la grabación.",it:"Secondi della registrazione; negativi prima del suo inizio: uno stadio visto minuti dopo il lancio era già alto quando la registrazione è iniziata."}},{type:"number",key:"lat",min:-90,max:90,step:1e-4,unit:"°",required:!0,label:{en:"Latitude",fr:"Latitude",es:"Latitud",it:"Latitudine"}},{type:"number",key:"lng",min:-180,max:180,step:1e-4,unit:"°",required:!0,label:{en:"Longitude",fr:"Longitude",es:"Longitud",it:"Longitudine"}},{type:"number",key:"altitudeKm",min:0,max:2e3,step:.1,unit:"km",required:!0,label:{en:"Altitude",fr:"Altitude",es:"Altitud",it:"Altitudine"}}]};static publish(){r.publish(n.SET)}}class o{constructor(e,t,a){this.container=e,this.host=t,this.language=a,r.of("launch")||n.publish(),this.render(),this.setLanguage(a)}messages=d;languageToken=0;currentId;form;list;places;placeForm;placeIndex=0;language;shown=[];async setLanguage(e){const t=++this.languageToken;this.language=e;const a=p.includes(e)?e:"en",i=a==="en"?d:await m(a);t===this.languageToken&&(this.messages=i,this.render(),this.sync())}sync(){const e=this.launches;this.shown=[...e],e.some(i=>i.id===this.currentId)||(this.currentId=e[0]?.id),this.list?.setItems(e.map(i=>({id:i.id,label:this.labelOf(i)})),this.currentId),this.list?.setAddState(this.startOfNew()!==void 0,this.startOfNew()===void 0?this.messages.addLaunchNowhere:void 0),this.element("launch-none").hidden=e.length>0;const t=this.current;if(this.element("launch-fields").hidden=t===void 0,!t)return;this.syncPlaces(t);const a=r.of("launch");this.form??=new c(this.element("launch-parameters"),this.language,"",{said:()=>this.host.said(),writingLanguage:()=>this.host.writingLanguage()}),this.form.show(a,t,()=>this.written())}refresh(){const e=this.launches;e.length===this.shown.length&&e.every((t,a)=>t===this.shown[a])||this.sync()}get current(){return this.launches.find(e=>e.id===this.currentId)}show(e){this.currentId=e,this.placeIndex=0,this.sync()}render(){const e=this.messages;this.form=void 0,this.container.innerHTML=`<div class="launch-editor">
1
+ import{L as h,i as r,U as p,j as m,P as c,E as u,h as g}from"./rr0-sighting-editor.mjs";import{launchEditorMessages_en as d}from"./LaunchEditorMessages_en-j4RgQPZu.js";class n{static plumeValue(e){return t=>h.plumeOf(t)[e]}static plume(e,t){return{type:"number",key:`plume.${e}`,effective:n.plumeValue(e),...t}}static burn(e,t){return{type:"number",key:e,min:-3600,max:36e3,step:.1,unit:"s",scale:.001,label:t.label,hint:t.hint,group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"},effective:a=>t.ends(a.track??[])?.t}}static nextPlace(e){const t=e[e.length-1]??{t:0,lat:0,lng:0,altitudeKm:0},a=e[e.length-2]??t,i=(s,l=0)=>e.length>1?t[s]-a[s]:l;return{t:t.t+(e.length>1?i("t"):1e4),lat:t.lat+i("lat"),lng:t.lng+i("lng"),altitudeKm:Math.max(0,t.altitudeKm+i("altitudeKm"))}}static SET={kind:"launch",title:{en:"Launch",fr:"Lancement",es:"Lanzamiento",it:"Lancio"},parameters:[{type:"said",key:"title",label:{en:"Name",fr:"Nom",es:"Nombre",it:"Nome"},group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"text",key:"vehicle.name",label:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"},placeholder:"Falcon 9",group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"text",key:"vehicle.mission",label:{en:"Mission",fr:"Mission",es:"Misión",it:"Missione"},placeholder:"Starlink Group 10-49",group:{en:"Vehicle",fr:"Lanceur",es:"Lanzador",it:"Lanciatore"}},{type:"number",key:"vehicle.engine.thrustKN",min:1,max:1e5,step:1,unit:"kN",label:{en:"Thrust (vacuum)",fr:"Poussée (dans le vide)",es:"Empuje (en el vacío)",it:"Spinta (nel vuoto)"},hint:{en:"Merlin Vacuum 934, RL10 110, a solid booster several thousand. With the specific impulse, it sets how much exhaust leaves each second.",fr:"Merlin Vacuum 934, RL10 110, un booster à poudre plusieurs milliers. Avec l'impulsion spécifique, elle fixe le débit d'échappement.",es:"Merlin Vacuum 934, RL10 110, un propulsor sólido varios miles. Con el impulso específico, fija el caudal de escape.",it:"Merlin Vacuum 934, RL10 110, un booster solido diverse migliaia. Con l'impulso specifico, fissa la portata dello scarico."},group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},{type:"number",key:"vehicle.engine.specificImpulseS",min:100,max:500,step:1,unit:"s",label:{en:"Specific impulse (vacuum)",fr:"Impulsion spécifique (dans le vide)",es:"Impulso específico (en el vacío)",it:"Impulso specifico (nel vuoto)"},hint:{en:"Times 9.81 m/s² it is the exhaust velocity, which sets how fast the exhaust spreads round the stage: 348 s is 3.4 km/s.",fr:"Multipliée par 9,81 m/s², c'est la vitesse d'éjection, qui fixe la vitesse à laquelle l'échappement s'étale autour de l'étage : 348 s font 3,4 km/s.",es:"Multiplicado por 9,81 m/s² es la velocidad de escape, que fija la rapidez con que el escape se extiende alrededor de la etapa: 348 s son 3,4 km/s.",it:"Moltiplicato per 9,81 m/s² è la velocità di scarico, che fissa quanto in fretta lo scarico si allarga attorno allo stadio: 348 s sono 3,4 km/s."},group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},{type:"choice",key:"vehicle.engine.propellant",label:{en:"Propellant",fr:"Ergols",es:"Propelentes",it:"Propellenti"},hint:{en:"What the exhaust is made of decides how much of it turns into particles that scatter light.",fr:"Ce dont l'échappement est fait décide quelle part devient des particules qui diffusent la lumière.",es:"De qué está hecho el escape decide qué parte se vuelve partículas que difunden la luz.",it:"Di cosa è fatto lo scarico decide quanta parte diventa particelle che diffondono la luce."},choices:[{value:"rp1-lox",label:{en:"Kerosene and oxygen",fr:"Kérosène et oxygène",es:"Queroseno y oxígeno",it:"Cherosene e ossigeno"}},{value:"methane-lox",label:{en:"Methane and oxygen",fr:"Méthane et oxygène",es:"Metano y oxígeno",it:"Metano e ossigeno"}},{value:"hydrogen-lox",label:{en:"Hydrogen and oxygen",fr:"Hydrogène et oxygène",es:"Hidrógeno y oxígeno",it:"Idrogeno e ossigeno"}},{value:"hypergolic",label:{en:"Hypergolic",fr:"Hypergolique",es:"Hipergólico",it:"Ipergolico"}},{value:"solid",label:{en:"Solid",fr:"Poudre",es:"Sólido",it:"Solido"}}],group:{en:"Engine",fr:"Moteur",es:"Motor",it:"Motore"}},n.burn("burnFromT",{label:{en:"Engine start",fr:"Allumage du moteur",es:"Encendido del motor",it:"Accensione del motore"},hint:{en:"When the engine started, in seconds of the recording; it may be before it. Empty: the first point of the path.",fr:"Quand le moteur s'est allumé, en secondes de l'enregistrement ; avant lui si besoin. Vide : le premier point du chemin.",es:"Cuándo se encendió el motor, en segundos de la grabación; puede ser antes. Vacío: el primer punto de la trayectoria.",it:"Quando si è acceso il motore, in secondi della registrazione; può essere prima. Vuoto: il primo punto del percorso."},ends:e=>e[0]}),n.burn("burnUntilT",{label:{en:"Engine cut-off",fr:"Extinction du moteur",es:"Apagado del motor",it:"Spegnimento del motore"},hint:{en:"When the engine stopped, in seconds of the recording. Empty: the last point of the path. Nothing is let go after it.",fr:"Quand le moteur s'est éteint, en secondes de l'enregistrement. Vide : le dernier point du chemin. Rien n'est lâché après.",es:"Cuándo se apagó el motor, en segundos de la grabación. Vacío: el último punto de la trayectoria. Nada se suelta después.",it:"Quando si è spento il motore, in secondi della registrazione. Vuoto: l'ultimo punto del percorso. Dopo non si rilascia nulla."},ends:e=>e[e.length-1]}),n.plume("exhaustKgPerS",{min:.1,max:1e5,step:.1,unit:"kg/s",label:{en:"Exhaust flow",fr:"Débit d'échappement",es:"Caudal de escape",it:"Portata di scarico"},hint:{en:"How much exhaust leaves the engine each second: how bright the plume is. Thrust over exhaust velocity when the engine is stated.",fr:"La masse d'échappement qui sort du moteur chaque seconde : la luminosité du panache. La poussée sur la vitesse d'éjection quand le moteur est donné.",es:"La masa de escape que sale del motor cada segundo: el brillo de la estela. El empuje sobre la velocidad de escape cuando se da el motor.",it:"La massa di scarico che esce dal motore ogni secondo: la luminosità della scia. La spinta sulla velocità di scarico quando il motore è dato."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("condensedShare",{min:0,max:1,step:.01,label:{en:"Share that scatters",fr:"Part qui diffuse",es:"Parte que difunde",it:"Parte che diffonde"},hint:{en:"The share of the exhaust that ends up as particles that scatter the Sun's light. Nobody has measured it for a launch: the one number to fit against a photograph.",fr:"La part de l'échappement qui devient des particules diffusant la lumière du Soleil. Personne ne l'a mesurée pour un lancement : le seul nombre à caler sur une photographie.",es:"La parte del escape que acaba como partículas que difunden la luz del Sol. Nadie la ha medido para un lanzamiento: el único número que ajustar con una fotografía.",it:"La parte dello scarico che diventa particelle che diffondono la luce del Sole. Nessuno l'ha misurata per un lancio: l'unico numero da tarare su una fotografia."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("particleRadiusUm",{min:.05,max:5,step:.05,unit:"µm",label:{en:"Particle radius",fr:"Rayon des particules",es:"Radio de las partículas",it:"Raggio delle particelle"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("lifetimeS",{min:10,max:3600,step:10,unit:"s",label:{en:"Trail lifetime",fr:"Durée de la traînée",es:"Duración de la estela",it:"Durata della scia"},hint:{en:"How long the narrow trail lasts before the particles have gone.",fr:"Combien de temps la traînée étroite dure avant que les particules aient disparu.",es:"Cuánto dura la estela estrecha antes de que las partículas hayan desaparecido.",it:"Quanto dura la scia stretta prima che le particelle siano sparite."},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("expansionKmPerS",{min:0,max:5,step:.01,unit:"km/s",label:{en:"Trail spreading",fr:"Étalement de la traînée",es:"Expansión de la estela",it:"Espansione della scia"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("initialRadiusKm",{min:0,max:50,step:.1,unit:"km",label:{en:"Radius at release",fr:"Rayon au lâcher",es:"Radio al soltar",it:"Raggio al rilascio"},group:{en:"Plume",fr:"Panache",es:"Estela",it:"Scia"}}),n.plume("collarShare",{min:0,max:1,step:.01,label:{en:"Share in the collar",fr:"Part dans la collerette",es:"Parte en el collar",it:"Parte nel collare"},hint:{en:"The collar is the exhaust just let go, which spreads fast into a wide short-lived shell round the stage; the rest stays behind as the narrow trail.",fr:"La collerette est l'échappement qui vient d'être lâché, qui s'étale vite en une coque large et brève autour de l'étage ; le reste demeure derrière en traînée étroite.",es:"El collar es el escape recién soltado, que se extiende rápido en una envoltura ancha y breve alrededor de la etapa; el resto queda detrás como estela estrecha.",it:"Il collare è lo scarico appena rilasciato, che si allarga in fretta in un guscio largo e breve attorno allo stadio; il resto resta dietro come scia stretta."},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}}),n.plume("collarExpansionKmPerS",{min:0,max:10,step:.05,unit:"km/s",label:{en:"Collar spreading",fr:"Étalement de la collerette",es:"Expansión del collar",it:"Espansione del collare"},hint:{en:"How fast the collar widens: three quarters of the exhaust velocity when the engine is stated.",fr:"La vitesse à laquelle la collerette s'élargit : les trois quarts de la vitesse d'éjection quand le moteur est donné.",es:"La rapidez con que el collar se ensancha: tres cuartos de la velocidad de escape cuando se da el motor.",it:"Quanto in fretta il collare si allarga: tre quarti della velocità di scarico quando il motore è dato."},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}}),n.plume("collarLifetimeS",{min:1,max:300,step:1,unit:"s",label:{en:"Collar lifetime",fr:"Durée de la collerette",es:"Duración del collar",it:"Durata del collare"},group:{en:"Collar",fr:"Collerette",es:"Collar",it:"Collare"}})]};static PLACE={kind:"launch-place",title:{en:"Place of the path",fr:"Point du chemin",es:"Punto de la trayectoria",it:"Punto del percorso"},parameters:[{type:"number",key:"t",min:-3600,max:36e3,step:.1,unit:"s",scale:.001,required:!0,label:{en:"Time",fr:"Instant",es:"Instante",it:"Istante"},hint:{en:"Seconds of the recording; negative before it began: a stage seen minutes after its launch was already high when the recording started.",fr:"Secondes de l'enregistrement ; négatives avant son début : un étage vu des minutes après son lancement était déjà haut quand l'enregistrement a commencé.",es:"Segundos de la grabación; negativos antes de que empezara: una etapa vista minutos después de su lanzamiento ya estaba alta cuando empezó la grabación.",it:"Secondi della registrazione; negativi prima del suo inizio: uno stadio visto minuti dopo il lancio era già alto quando la registrazione è iniziata."}},{type:"number",key:"lat",min:-90,max:90,step:1e-4,unit:"°",required:!0,label:{en:"Latitude",fr:"Latitude",es:"Latitud",it:"Latitudine"}},{type:"number",key:"lng",min:-180,max:180,step:1e-4,unit:"°",required:!0,label:{en:"Longitude",fr:"Longitude",es:"Longitud",it:"Longitudine"}},{type:"number",key:"altitudeKm",min:0,max:2e3,step:.1,unit:"km",required:!0,label:{en:"Altitude",fr:"Altitude",es:"Altitud",it:"Altitudine"}}]};static publish(){r.publish(n.SET)}}class o{constructor(e,t,a){this.container=e,this.host=t,this.language=a,r.of("launch")||n.publish(),this.render(),this.setLanguage(a)}messages=d;languageToken=0;currentId;form;list;places;placeForm;placeIndex=0;language;shown=[];async setLanguage(e){const t=++this.languageToken;this.language=e;const a=p.includes(e)?e:"en",i=a==="en"?d:await m(a);t===this.languageToken&&(this.messages=i,this.render(),this.sync())}sync(){const e=this.launches;this.shown=[...e],e.some(i=>i.id===this.currentId)||(this.currentId=e[0]?.id),this.list?.setItems(e.map(i=>({id:i.id,label:this.labelOf(i)})),this.currentId),this.list?.setAddState(this.startOfNew()!==void 0,this.startOfNew()===void 0?this.messages.addLaunchNowhere:void 0),this.element("launch-none").hidden=e.length>0;const t=this.current;if(this.element("launch-fields").hidden=t===void 0,!t)return;this.syncPlaces(t);const a=r.of("launch");this.form??=new c(this.element("launch-parameters"),this.language,"",{said:()=>this.host.said(),writingLanguage:()=>this.host.writingLanguage()}),this.form.show(a,t,()=>this.written())}refresh(){const e=this.launches;e.length===this.shown.length&&e.every((t,a)=>t===this.shown[a])||this.sync()}get current(){return this.launches.find(e=>e.id===this.currentId)}show(e){this.currentId=e,this.placeIndex=0,this.sync()}render(){const e=this.messages;this.form=void 0,this.container.innerHTML=`<div class="launch-editor">
2
2
  <p class="launch-intro">${e.intro}</p>
3
3
  <p id="launch-none" class="launch-intro">${e.none}</p>
4
4
  <div id="launch-list"></div>
@@ -1 +1 @@
1
- import{G as d,j as c,k as l,M as f,m,n as u,o as w,p as M,q as g,H as y,s as S,t as k,u as v}from"./rr0-sighting-editor.mjs";class h{static key(e){return"url"in e?`url:${e.url}|${e.headingOffsetDeg??0}`:"shape"in e?`shape:${e.shape}`:`decor:${e.decorKind}`}static async build(e){const s=new d;if("url"in e){const t=await c(e.url);t.rotation.y=-(e.headingOffsetDeg??0)*Math.PI/180,s.add(t)}else"shape"in e?s.add(h.shapeOf(e.shape)):s.add(l.build({id:"preview",kind:e.decorKind,eastM:0,northM:0},!1));return s}static shapeOf(e){if(e==="figure")return l.build({id:"preview",kind:"entity",eastM:0,northM:0},!1);const s=new f(m.unitGeometry(e),new u({color:13158608,roughness:.5,metalness:0}));return e==="ellipsoid"&&s.scale.set(1,.55,1),s}static dispose(e){e.traverse(s=>{const t=s;if(t.isMesh){t.geometry?.dispose();for(const a of[t.material].flat())a.dispose()}})}static stage(e,s){const t=new w().setFromObject(e);if(t.isEmpty())return;const a=t.getBoundingSphere(new M),r=new d;e.position.sub(a.center),r.add(e);const n=new g;n.add(r),n.add(new y(16777215,6715272,1.6));const o=new S(16777215,2.5);o.position.set(1,2,1.5),n.add(o);const i=new k(30,s,a.radius*.05,a.radius*20),p=a.radius/Math.sin(i.fov*Math.PI/360)*1.05;return i.position.copy(new v(.55,.3,-.78).normalize().multiplyScalar(p)),i.lookAt(0,0,0),{scene:n,camera:i,pivot:r}}}export{h as M};
1
+ import{G as d,q as c,t as l,M as f,u as m,v as u,w,x as y,y as M,z as g,C as S,F as v,J as O}from"./rr0-sighting-editor.mjs";class h{static key(e){return"url"in e?`url:${e.url}|${e.headingOffsetDeg??0}`:"shape"in e?`shape:${e.shape}`:`decor:${e.decorKind}`}static async build(e){const s=new d;if("url"in e){const t=await c(e.url);t.rotation.y=-(e.headingOffsetDeg??0)*Math.PI/180,s.add(t)}else"shape"in e?s.add(h.shapeOf(e.shape)):s.add(l.build({id:"preview",kind:e.decorKind,eastM:0,northM:0},!1));return s}static shapeOf(e){if(e==="figure")return l.build({id:"preview",kind:"entity",eastM:0,northM:0},!1);const s=new f(m.unitGeometry(e),new u({color:13158608,roughness:.5,metalness:0}));return e==="ellipsoid"&&s.scale.set(1,.55,1),s}static dispose(e){e.traverse(s=>{const t=s;if(t.isMesh){t.geometry?.dispose();for(const a of[t.material].flat())a.dispose()}})}static stage(e,s){const t=new w().setFromObject(e);if(t.isEmpty())return;const a=t.getBoundingSphere(new y),r=new d;e.position.sub(a.center),r.add(e);const n=new M;n.add(r),n.add(new g(16777215,6715272,1.6));const o=new S(16777215,2.5);o.position.set(1,2,1.5),n.add(o);const i=new v(30,s,a.radius*.05,a.radius*20),p=a.radius/Math.sin(i.fov*Math.PI/360)*1.05;return i.position.copy(new O(.55,.3,-.78).normalize().multiplyScalar(p)),i.lookAt(0,0,0),{scene:n,camera:i,pivot:r}}}export{h as M};