gps-plus-slam-js 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts
CHANGED
|
@@ -166,6 +166,41 @@ interface RawAbsoluteOrientation {
|
|
|
166
166
|
*/
|
|
167
167
|
declare const eulerToQuaternion: (alpha: number, beta: number, gamma: number) => Quaternion;
|
|
168
168
|
//#endregion
|
|
169
|
+
//#region ../src/state/models/compass-trust.d.ts
|
|
170
|
+
/**
|
|
171
|
+
* Phase 4 Stage A — magnetometer consistency-trust state machine
|
|
172
|
+
* (CLOSED / INTERNAL ONLY).
|
|
173
|
+
*
|
|
174
|
+
* A pure, deterministic reducer that earns (or withholds) trust in the absolute
|
|
175
|
+
* compass by comparing it against the **GPS-only** alignment yaw over time. It
|
|
176
|
+
* exists to feed the *steady-state* Stage B/C use of the compass (detection /
|
|
177
|
+
* soft-prior correction) — it is built in the same iteration as Stage 0 but is
|
|
178
|
+
* **deliberately orthogonal to the Stage-0 cold-start handover**, which stays
|
|
179
|
+
* GPS-intrinsic and never consults trust (plan §7b "the circularity trap").
|
|
180
|
+
*
|
|
181
|
+
* The cardinal property (plan §4c item 9, §10): a **consistently-biased**
|
|
182
|
+
* magnetometer must NEVER reach "trusted" once GPS yaw is observable — its
|
|
183
|
+
* disagreement keeps it out of the trusted state, and a sustained disagreement
|
|
184
|
+
* raises the figure-8 recalibration recommendation instead.
|
|
185
|
+
*
|
|
186
|
+
* Trust ordering (plan §7b Stage A):
|
|
187
|
+
* - Before GPS yaw is observable there is nothing trustworthy to validate
|
|
188
|
+
* against ⇒ the machine is `dormant` (Stage 0's unconditional override holds).
|
|
189
|
+
* - Once observable, agreement within tolerance for a sustained streak ⇒
|
|
190
|
+
* `trusted`; a later large disagreement drops it back to `untrusted`.
|
|
191
|
+
*
|
|
192
|
+
* See the colocated `.md` sidecar for the API, invariants and test strategy.
|
|
193
|
+
*/
|
|
194
|
+
type TrustState = 'dormant' | 'untrusted' | 'trusted';
|
|
195
|
+
/** Serializable trust memory (survives Redux round-trips). */
|
|
196
|
+
interface TrustMemory {
|
|
197
|
+
readonly state: TrustState;
|
|
198
|
+
readonly agreeStreak: number;
|
|
199
|
+
readonly disagreeStreak: number;
|
|
200
|
+
/** Derived per-step: surface the figure-8 prompt (observable + sustained disagreement). */
|
|
201
|
+
readonly recommendRecalibration: boolean;
|
|
202
|
+
}
|
|
203
|
+
//#endregion
|
|
169
204
|
//#region ../src/state/models/gpsEvents.d.ts
|
|
170
205
|
/**
|
|
171
206
|
* Plain object representing GPS events state.
|
|
@@ -200,6 +235,23 @@ interface GpsEventsState {
|
|
|
200
235
|
*/
|
|
201
236
|
lastAdmittedOdomPos: Vector3 | null;
|
|
202
237
|
lastAdmittedTs: number | null;
|
|
238
|
+
/**
|
|
239
|
+
* Phase-4 Stage 0 (only present when `useCompassColdStartOverride` is on):
|
|
240
|
+
* ring buffer of the last N GPS-only solved yaw bearings (deg) feeding the
|
|
241
|
+
* intrinsic observability gate, and the last applied override bearing driving
|
|
242
|
+
* the snap-correction across incremental calls. **Absent** when the override is
|
|
243
|
+
* off ⇒ byte-identical state shape for every existing consumer. Reset on
|
|
244
|
+
* origin-jump rebuilds (the batch path rebuilds the window from prefixes).
|
|
245
|
+
*/
|
|
246
|
+
coldStartYawWindowDeg?: number[];
|
|
247
|
+
coldStartAppliedBearingDeg?: number | null;
|
|
248
|
+
/**
|
|
249
|
+
* Phase-4 Stage C (only present when `useCompassRotationPrior` is on): the
|
|
250
|
+
* compass consistency-trust memory, updated each observation from the windowed
|
|
251
|
+
* compass-vs-GPS-only-yaw agreement (gated on observability). Absent otherwise
|
|
252
|
+
* ⇒ byte-identical state shape. Reset to dormant on origin-jump rebuilds.
|
|
253
|
+
*/
|
|
254
|
+
compassTrust?: TrustMemory;
|
|
203
255
|
}
|
|
204
256
|
//#endregion
|
|
205
257
|
//#region ../src/state/types.d.ts
|
|
@@ -353,6 +405,34 @@ interface GpsModel {
|
|
|
353
405
|
zero: LatLong;
|
|
354
406
|
gpsEvents: GpsEventsType;
|
|
355
407
|
odometryPath: OdometryPath;
|
|
408
|
+
/**
|
|
409
|
+
* Runtime opt-in for the Phase-4 Stage-0 cold-start compass yaw override
|
|
410
|
+
* (closed/internal alignment feature). Set via `setColdStartOverrideEnabled`
|
|
411
|
+
* — must be dispatched **after** `setZeroPos` (state is null before it). When
|
|
412
|
+
* truthy the reducer threads `{ useCompassColdStartOverride: true }` into the
|
|
413
|
+
* solve; absent/false ⇒ byte-identical to today. A debug/experiment flag —
|
|
414
|
+
* keep OFF until the §6a field matrix re-tunes the thresholds. See
|
|
415
|
+
* GpsPlusSlamJs_Docs/docs/2026-06-26-absolute-orientation-sensor-phase4-stage0-followup.md.
|
|
416
|
+
*/
|
|
417
|
+
coldStartOverrideEnabled?: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Runtime opt-in for the Phase-4 **Stage C** trust-gated compass rotation prior
|
|
420
|
+
* (closed/internal). Set via `setCompassRotationPriorEnabled` (after
|
|
421
|
+
* `setZeroPos`). When truthy the reducer threads
|
|
422
|
+
* `{ useCompassRotationPrior: true }` into the solve (it supersedes Stage 0,
|
|
423
|
+
* keeping a steady-state vote once observable+trusted). Absent/false ⇒
|
|
424
|
+
* byte-identical. Debug/experiment flag.
|
|
425
|
+
*/
|
|
426
|
+
compassRotationPriorEnabled?: boolean;
|
|
427
|
+
/**
|
|
428
|
+
* Runtime opt-in for the GPS-free compass↔WebXR consistency gate
|
|
429
|
+
* (closed/internal). Set via `setCompassWebXRConsistencyEnabled` (after
|
|
430
|
+
* `setZeroPos`). When truthy the reducer threads
|
|
431
|
+
* `{ requireCompassWebXRConsistency: true }` into the solve, so the compass
|
|
432
|
+
* override (Stage 0 / Stage C) abstains unless the compass is rotating in
|
|
433
|
+
* lock-step with WebXR. Absent/false ⇒ byte-identical. Debug/experiment flag.
|
|
434
|
+
*/
|
|
435
|
+
compassWebXRConsistencyEnabled?: boolean;
|
|
356
436
|
}
|
|
357
437
|
interface GpsSlamState {
|
|
358
438
|
gpsData: GpsModel | null;
|
|
@@ -476,6 +556,9 @@ declare const recordGpsEvent: _$_reduxjs_toolkit0.ActionCreatorWithPayload<Recor
|
|
|
476
556
|
declare const odometryTrackingRestarted: _$_reduxjs_toolkit0.ActionCreatorWithPayload<OdometryTrackingRestartedPayload, "gpsData/odometryTrackingRestarted">;
|
|
477
557
|
declare const arLoopClosureDetected: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArLoopClosureDetectedPayload, "gpsData/arLoopClosureDetected">;
|
|
478
558
|
declare const add2dImage: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArImageCapture, "gpsData/add2dImage">;
|
|
559
|
+
declare const setColdStartOverrideEnabled: _$_reduxjs_toolkit0.ActionCreatorWithPayload<boolean, "gpsData/setColdStartOverrideEnabled">;
|
|
560
|
+
declare const setCompassRotationPriorEnabled: _$_reduxjs_toolkit0.ActionCreatorWithPayload<boolean, "gpsData/setCompassRotationPriorEnabled">;
|
|
561
|
+
declare const setCompassWebXRConsistencyEnabled: _$_reduxjs_toolkit0.ActionCreatorWithPayload<boolean, "gpsData/setCompassWebXRConsistencyEnabled">;
|
|
479
562
|
declare const gpsDataReducer: (state: GpsModel | null | undefined, action: _$redux.UnknownAction) => GpsModel | null;
|
|
480
563
|
//#endregion
|
|
481
564
|
//#region ../src/state/gpsElementsSlice.d.ts
|
|
@@ -681,4 +764,4 @@ declare function validateLicenseKey(key: string): LicenseValidationResult;
|
|
|
681
764
|
//#region ../src/index.d.ts
|
|
682
765
|
declare const LIB_VERSION = "1.0.0";
|
|
683
766
|
//#endregion
|
|
684
|
-
export { type Add2dImagePayload, type ArElementsState, type ArImageCapture, type ArLoopClosureDetectedPayload, type AreaPolygon, type CreateGpsSlamStoreOptions, type DetectedArPlane, type EventArea, type FloorDetection, type GpsElementsState, type GpsLine, type GpsMarker, type GpsModel, type GpsPoint, type GpsSlamDispatch, type GpsSlamState, type GpsSlamStore, type HeatArea, type HeatMapTile, IDENTITY_MATRIX4, IDENTITY_QUATERNION, LIB_VERSION, type LatLong, type LatLongAlt, type LicenseValidationResult, type Matrix4, type OdometryPath, type OdometryTrackingRestartedPayload, type Quaternion, type RawAbsoluteOrientation, type RawDeviceOrientation, type RawGpsPoint, type RecordGpsEventPayload, type RootState, type Vector3, type Vector4, WMM2025_EPOCH, WMM2025_VALID_FROM, WMM2025_VALID_TO, ZERO_VECTOR3, add2dImage, addArea, addCornerToEventArea, addHeatMapArea, addLine, addMarker, addOrUpdateArPlane, addToHeatMaps, anchorEventAreaInWorldSpace, arElementsReducer, arLoopClosureDetected, arNorthBearingDeg, arToEnuRotation, bearingDeltaDeg, calcGeoHash, calcGpsCoords, calcQuadKey, calcRelativeCoordsInMeters, cloneMatrix4, cloneQuaternion, cloneVector3, correctArDriftForEventArea, createGpsSlamStore, distanceInMeters, distanceInMetersRelative, enuQuaternionToNUE, eulerToQuaternion, finishEventArea, fromMatrix4, fromQuaternion, fromVector3, fusedGpsFromOdom, geoHashToLatLong, getAlignmentMatrix, getAlignmentRotation, getGoogleMapsDirectionsLink, getGoogleMapsLink, getGpsAccuracyStats, getGpsPositions, getOdometryPositions, getOdometryRotations, getOpenStreetMapLink, getZeroReference, gpsDataReducer, gpsElementsReducer, invertQuaternion, isIdentityMatrix4, isIdentityQuaternion, isNearIdentityQuaternion, magneticDeclinationDeg, magneticHeadingFromEnuQuat, magneticToTrueHeadingDeg, multiplyQuaternions, normalizeQuaternion, nueQuaternionToENU, nueQuaternionToWebXR, nueToWebXR, odometryTrackingRestarted, quadKeyToLatLong, quaternionMagnitude, quaternionsEquivalent, recordGpsEvent, recordPhoneHeight, resetArElements, resetGpsElements, sanitizeForDevTools, setZeroPos, startEventArea, toEarthCenteredCoordinates, toMatrix4, toQuaternion, toVector3, validateLicenseKey, webxrQuaternionToNUE, webxrToNUE };
|
|
767
|
+
export { type Add2dImagePayload, type ArElementsState, type ArImageCapture, type ArLoopClosureDetectedPayload, type AreaPolygon, type CreateGpsSlamStoreOptions, type DetectedArPlane, type EventArea, type FloorDetection, type GpsElementsState, type GpsLine, type GpsMarker, type GpsModel, type GpsPoint, type GpsSlamDispatch, type GpsSlamState, type GpsSlamStore, type HeatArea, type HeatMapTile, IDENTITY_MATRIX4, IDENTITY_QUATERNION, LIB_VERSION, type LatLong, type LatLongAlt, type LicenseValidationResult, type Matrix4, type OdometryPath, type OdometryTrackingRestartedPayload, type Quaternion, type RawAbsoluteOrientation, type RawDeviceOrientation, type RawGpsPoint, type RecordGpsEventPayload, type RootState, type Vector3, type Vector4, WMM2025_EPOCH, WMM2025_VALID_FROM, WMM2025_VALID_TO, ZERO_VECTOR3, add2dImage, addArea, addCornerToEventArea, addHeatMapArea, addLine, addMarker, addOrUpdateArPlane, addToHeatMaps, anchorEventAreaInWorldSpace, arElementsReducer, arLoopClosureDetected, arNorthBearingDeg, arToEnuRotation, bearingDeltaDeg, calcGeoHash, calcGpsCoords, calcQuadKey, calcRelativeCoordsInMeters, cloneMatrix4, cloneQuaternion, cloneVector3, correctArDriftForEventArea, createGpsSlamStore, distanceInMeters, distanceInMetersRelative, enuQuaternionToNUE, eulerToQuaternion, finishEventArea, fromMatrix4, fromQuaternion, fromVector3, fusedGpsFromOdom, geoHashToLatLong, getAlignmentMatrix, getAlignmentRotation, getGoogleMapsDirectionsLink, getGoogleMapsLink, getGpsAccuracyStats, getGpsPositions, getOdometryPositions, getOdometryRotations, getOpenStreetMapLink, getZeroReference, gpsDataReducer, gpsElementsReducer, invertQuaternion, isIdentityMatrix4, isIdentityQuaternion, isNearIdentityQuaternion, magneticDeclinationDeg, magneticHeadingFromEnuQuat, magneticToTrueHeadingDeg, multiplyQuaternions, normalizeQuaternion, nueQuaternionToENU, nueQuaternionToWebXR, nueToWebXR, odometryTrackingRestarted, quadKeyToLatLong, quaternionMagnitude, quaternionsEquivalent, recordGpsEvent, recordPhoneHeight, resetArElements, resetGpsElements, sanitizeForDevTools, setColdStartOverrideEnabled, setCompassRotationPriorEnabled, setCompassWebXRConsistencyEnabled, setZeroPos, startEventArea, toEarthCenteredCoordinates, toMatrix4, toQuaternion, toVector3, validateLicenseKey, webxrQuaternionToNUE, webxrToNUE };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! gps-plus-slam-js | (c) 2026 cs-util-com | UNLICENSED — see EULA.md */
|
|
2
|
-
import{configureStore as e,createSlice as t}from"@reduxjs/toolkit";import{ed25519 as n}from"@noble/curves/ed25519.js";import{hexToBytes as r}from"@noble/curves/utils.js";import{mat4 as i,quat as a,vec3 as o,vec4 as s}from"gl-matrix";import{castDraft as c}from"immer";let l=!1;function u(){l=!0}function d(){if(!l)throw Error(`gps-plus-slam-js: license not activated. Construct your store via createRecorderStore() from gps-plus-slam-app-framework, or pass a valid licenseKey to createGpsSlamStore(). See EULA §3.`)}function f(e){return((...t)=>(d(),e(...t)))}function p(e){let t=((...t)=>(d(),e(...t)));return Object.assign(t,e),t.toString=()=>e.type,t}function m(e){return(t,n)=>(d(),e(t,n))}function h(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=`=`.repeat((4-t.length%4)%4),r=atob(t+n);return Uint8Array.from(r,e=>e.charCodeAt(0))}function g(e){let t=new Date,i=e.indexOf(`.`);if(i<=0||i>=e.length-1)throw Error(`Invalid license key format: expected "payload.signature" with base64url-encoded parts.`);let a,o;try{a=h(e.substring(0,i)),o=h(e.substring(i+1))}catch{throw Error(`Invalid license key format: base64url decoding failed.`)}let s=r(`dfe5c62120b7a0ce962b17907a15b27cf1b056e6619bf6ce55e6e094b322a470`);if(!n.verify(o,a,s))throw Error(`Invalid license key: signature verification failed.`);let c=JSON.parse(new TextDecoder().decode(a));if(typeof c!=`object`||!c)throw Error(`Invalid license key: payload must be a JSON object.`);let{type:l,exp:d}=c;if(l!==`community`)throw Error(`Invalid license key: "type" must be "community".`);if(typeof d!=`number`||!Number.isFinite(d))throw Error(`Invalid license key: "exp" must be a finite number (Unix timestamp in seconds).`);if(d<Math.floor(t.getTime()/1e3)){let e=new Date(d*1e3);throw Error(`License key expired on ${e.toISOString()}. Update to the latest version for a renewed community key.`)}return u(),{type:l,expiresAt:new Date(d*1e3)}}const _=180/Math.PI,v=e=>{let t=e[0],n=e[1],r=e[2],i=e[3],a=2*(i*t+n*r),o=1-2*(t*t+n*n),s=Math.atan2(a,o)*_,c=2*(i*n-r*t),l=Math.abs(c)>=1?Math.sign(c)*90:Math.asin(c)*_,u=2*(i*r+t*n),d=1-2*(n*n+r*r);return{pitch:l,yaw:Math.atan2(u,d)*_,roll:s}},y=1/298.257223563,b=y*(2-y),x=40075016.6856/360,S=39940652.7422/360,C=Math.PI/180,w=180/Math.PI,T=`0123456789bcdefghjkmnpqrstuvwxyz`,E=[16,8,4,2,1],D=(e,t,n)=>Math.min(Math.max(e,t),n),O=e=>D(e,-180,180),k=e=>e*C,A=e=>e*w,j=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},M=e=>({lat:j(e.lat),lon:j(e.lon)}),ee=(e,t=0)=>{let n=k(e.lat),r=k(e.lon),i=Math.sin(n),a=Math.cos(n),s=Math.sin(r),c=Math.cos(r),l=6378137/Math.sqrt(1-b*i*i),u=(l+t)*a*c,d=(l+t)*a*s,f=(l*(1-b)+t)*i;return o.fromValues(u,d,f)},te=f((e,t)=>{if(t<1||t>23)throw RangeError(`levelOfDetail must be between 1 and 23 (inclusive)`);let n=D(e.lat,-85.05112878,85.05112878),r=O(e.lon),i=Math.sin(k(n)),a=256*2**t,o=(r+180)/360*a,s=(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*a,c=2**t-1,l=D(Math.floor(o/256),0,c),u=D(Math.floor(s/256),0,c),d=``;for(let e=t;e>0;--e){let t=0,n=1<<e-1;(l&n)!==0&&(t+=1),(u&n)!==0&&(t+=2),d+=t.toString()}return d}),ne=f(e=>{if(!/^[0-3]+$/.test(e))throw Error(`QuadKey must consist of digits 0-3`);let t=e.length;if(t===0)throw Error(`QuadKey must not be empty`);let n=0,r=0;for(let i=0;i<t;i+=1){let a=Number.parseInt(e[i],10),o=1<<t-i-1;a&1&&(n+=o),a&2&&(r+=o)}let i=256*2**t,a=(n+.5)*256,o=(r+.5)*256,s=a/i,c=o/i,l=s*360-180;return{lat:A(Math.atan(Math.sinh(Math.PI*(1-2*c)))),lon:l}}),re=f((e,t)=>{if(t<=0)throw RangeError(`precision must be greater than 0`);let n=-90,r=90,i=-180,a=180,o=``,s=0,c=0,l=!0;for(;o.length<t;){if(l){let t=(i+a)/2;e.lon>=t?(c|=E[s],i=t):a=t}else{let t=(n+r)/2;e.lat>=t?(c|=E[s],n=t):r=t}l=!l,s<4?s+=1:(o+=T[c],s=0,c=0)}return o}),ie=f(e=>{if(e.length===0)throw Error(`geoHash must not be empty`);let t=-90,n=90,r=-180,i=180,a=!0;for(let o of e){let e=T.indexOf(o);if(e===-1)throw Error(`Invalid geohash character: ${o}`);for(let o of E){if(a){let t=(r+i)/2;(e&o)===0?i=t:r=t}else{let r=(t+n)/2;(e&o)===0?n=r:t=r}a=!a}}return{lat:(t+n)/2,lon:(r+i)/2}}),ae=f((e,t)=>{let n=k(e.lat),r=k(t.lat),i=r-n,a=k(t.lon-e.lon),o=Math.sin(i/2),s=Math.sin(a/2),c=o*o+Math.cos(n)*Math.cos(r)*s*s,l=Math.min(1,Math.max(0,c));return 6371008.8*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}),oe=f((e,t)=>{let n=N(e,t);return Math.hypot(n[0],n[2])}),N=f((e,t,n=0,r=0)=>{let i=(t.lon-e.lon)*x*Math.cos(k(e.lat)),a=(t.lat-e.lat)*S,s=n-r;return o.fromValues(a,s,i)}),P=f((e,t)=>{let n=t[0],r=t[2];return{lat:n/S+e.lat,lon:r/(x*Math.cos(k(e.lat)))+e.lon}}),se=f((e,t=0)=>ee(e,t)),F=e=>{let{lat:t,lon:n}=M(e);return`${t}%2C${n}`},ce=f(e=>`https://www.google.com/maps/search/?api=1&query=${F(e)}`),le=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${F(t)}&destination=${F(e)}`),ue=f((e,t=19)=>{let{lat:n,lon:r}=M(e);return`https://www.openstreetmap.org/query?lat=${n}&lon=${r}#map=${t}/${n}/${r}`}),de=f((e,t,n)=>{let r=i.fromValues(...e),a=o.fromValues(t[0],t[1],t[2]),s=o.create();o.transformMat4(s,a,r);let{lat:c,lon:l}=P(n,s);return{lat:c,lon:l,altitude:s[1]}}),fe=()=>({points:[]}),pe=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),me=()=>({arPlanes:{},floorDetections:[],eventAreas:[],currentEventAreaId:null,currentEventAreaPoints:[]}),I=e=>o.fromValues(e[0],e[1],e[2]),L=e=>a.fromValues(e[0],e[1],e[2],e[3]),he=e=>i.fromValues(...e),R=e=>[e[0],e[1],e[2]],z=e=>[e[0],e[1],e[2],e[3]],ge=e=>[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]],B=e=>[e[0],e[1],e[2]],_e=e=>[e[0],e[1],e[2],e[3]],ve=e=>[...e],V=Object.freeze([0,0,0,1]),H=Object.freeze([0,0,0]),ye=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),U=e=>{let t=xe(e);if(t===0)return V;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},be=e=>{for(let t=0;t<16;t++)if(e[t]!==ye[t])return!1;return!0},xe=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),Se=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,Ce=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,we=(e,t,n=1e-10)=>{let r=Math.abs(e[0]-t[0])<n&&Math.abs(e[1]-t[1])<n&&Math.abs(e[2]-t[2])<n&&Math.abs(e[3]-t[3])<n,i=Math.abs(e[0]+t[0])<n&&Math.abs(e[1]+t[1])<n&&Math.abs(e[2]+t[2])<n&&Math.abs(e[3]+t[3])<n;return r||i},Te=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},Ee=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},W=e=>[-e[2],e[1],e[0]],De=e=>[e[2],e[1],-e[0]],G=e=>[-e[2],e[1],e[0],e[3]],Oe=e=>[e[2],e[1],-e[0],e[3]],K=e=>[e[1],e[2],e[0],e[3]],ke=e=>[e[2],e[0],e[1],e[3]],Ae=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))throw Error(`eulerToQuaternion: non-finite input (alpha=${e}, beta=${t}, gamma=${n})`);let r=e*Math.PI/180,i=t*Math.PI/180,o=n*Math.PI/180,s=a.create(),c=a.create(),l=a.create();a.setAxisAngle(s,[0,0,1],r),a.setAxisAngle(c,[1,0,0],i),a.setAxisAngle(l,[0,1,0],o);let u=a.create();return a.multiply(u,s,c),a.multiply(u,u,l),[u[0],u[1],u[2],u[3]]},je=t({name:`arElements`,initialState:me(),reducers:{recordPhoneHeight:(e,t)=>{e.floorDetections.push(t.payload)},addOrUpdateArPlane:(e,t)=>{let n=t.payload;if(n.parentPlaneId){delete e.arPlanes[n.planeId];return}e.arPlanes[n.planeId]=c(n)},startEventArea:(e,t)=>{e.currentEventAreaId=t.payload.id,e.currentEventAreaPoints=[]},addCornerToEventArea:(e,t)=>{e.currentEventAreaId&&e.currentEventAreaPoints.push(c(B(t.payload.position)))},correctArDriftForEventArea:(e,t)=>{let n=t.payload.drift;for(let t of e.currentEventAreaPoints)t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]},finishEventArea:(e,t)=>{e.currentEventAreaId&&(e.eventAreas.push({id:e.currentEventAreaId,label:t.payload.label,polygon:[],isInArSpace:!0,arPoints:e.currentEventAreaPoints}),e.currentEventAreaId=null,e.currentEventAreaPoints=[])},anchorEventAreaInWorldSpace:(e,t)=>{let{areaId:n,alignmentMatrix:r,zeroRef:i}=t.payload,a=e.eventAreas.findIndex(e=>e.id===n);if(a===-1)return;let s=e.eventAreas[a];if(!s.isInArSpace||!s.arPoints)throw Error(`The area ${s.id} is already anchored in world space`);let c=he(r),l=s.arPoints.map(e=>{let t=I(e);return P(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>me()}}),{recordPhoneHeight:Me,addOrUpdateArPlane:Ne,startEventArea:Pe,addCornerToEventArea:Fe,correctArDriftForEventArea:Ie,finishEventArea:Le,anchorEventAreaInWorldSpace:Re,resetArElements:ze}=je.actions,Be=p(Me),Ve=p(Ne),He=p(Pe),Ue=p(Fe),We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=m(je.reducer);function Ye(e,t,n,r){let{inCentroid:i,refCentroid:a,refVec:s,tmp:c}=r;o.set(i,0,0,0),o.set(a,0,0,0);let l=0;for(let n=0;n<e.length;n++){let r=t[n][3];o.scaleAndAdd(i,i,e[n],r),$e(s,t[n]),o.scaleAndAdd(a,a,s,r),l+=r}if(l===0)throw Error(`Weights must not sum to zero when solving Kabsch`);let u=1/l;if(o.scale(i,i,u),o.scale(a,a,u),!n)return{inCentroid:i,refCentroid:a,scaleRatio:1};let d=0,f=0;for(let n=0;n<e.length;n++)o.subtract(c,e[n],i),d+=o.length(c),$e(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function Xe(e,t,n,r,a,s,c){let{negCentroid:l,scaleVec:u}=c;return i.fromRotationTranslation(e,r,n),s&&(o.set(u,a,a,a),i.scale(e,e,u)),o.negate(l,t),i.translate(e,e,l),e}function Ze(e,t,n={}){let r=e.length;if(r!==t.length)throw Error(`Length of the point lists was not equal: ${r} vs ${t.length}`);if(r===0)return i.create();let s=n.solveRotation??!0,c=n.solveScale??!1,l=n.ignoreYAxisForRotation??!1,u=n.rotationIterations??9,{inCentroid:d,refCentroid:f,scaleRatio:p}=Ye(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new Qe(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return Xe(i.create(),d,f,m,p,c,h)}var Qe=class e{ignoreYAxis;static twoPi=Math.PI*2;static basisX=o.fromValues(1,0,0);static basisY=o.fromValues(0,1,0);static basisZ=o.fromValues(0,0,1);constructor(e){this.ignoreYAxis=e}solve(t,n,r,i,o,s){let c=this.transposeMultSubtract(t,n,r,i);if(this.ignoreYAxis){let t=c[0][0],n=c[0][2],r=c[2][0],i=c[2][2],s=Math.atan2(r-n,t+i);a.setAxisAngle(o,e.basisY,s)}else this.extractRotation(c,o,s)}transposeMultSubtract(e,t,n,r){let i=[o.create(),o.create(),o.create()],a=o.clone(n),s=o.clone(r);this.ignoreYAxis&&(a[1]=0,s[1]=0);let c=o.create(),l=o.create(),u=o.create();for(let n=0;n<e.length;n++){o.copy(c,e[n]),$e(u,t[n]),this.ignoreYAxis&&(c[1]=0,u[1]=0);let r=t[n][3];o.subtract(c,c,a),o.scale(c,c,r),o.subtract(l,u,s),i[0][0]+=c[0]*l[0],i[1][0]+=c[1]*l[0],i[2][0]+=c[2]*l[0],i[0][1]+=c[0]*l[1],i[1][1]+=c[1]*l[1],i[2][1]+=c[2]*l[1],i[0][2]+=c[0]*l[2],i[1][2]+=c[1]*l[2],i[2][2]+=c[2]*l[2]}return i}extractRotation(t,n,r){let i=[o.create(),o.create(),o.create()],s=o.create(),c=o.create(),l=o.create();for(let u=0;u<r;u++){this.fillMatrixFromQuaternion(n,i),o.cross(s,i[0],t[0]),o.cross(l,i[1],t[1]),o.add(s,s,l),o.cross(l,i[2],t[2]),o.add(s,s,l);let r=o.dot(i[0],t[0])+o.dot(i[1],t[1])+o.dot(i[2],t[2])+1e-9;r=Math.abs(r),o.scale(s,s,1/r);let u=o.length(s);if(u<1e-9)break;o.scale(c,s,1/u);let d=u%e.twoPi,f=a.create();a.setAxisAngle(f,c,d),a.multiply(n,f,n),a.normalize(n,n)}}fillMatrixFromQuaternion(t,n){o.transformQuat(n[0],e.basisX,t),o.transformQuat(n[1],e.basisY,t),o.transformQuat(n[2],e.basisZ,t)}};const $e=(e,t)=>(e[0]=t[0],e[1]=t[1],e[2]=t[2],e);function et(e,t,n,r,i,a,o=Math.random){let s=Array.from(e);if(n>s.length)throw RangeError(`minSampleSize must be smaller than the number of elements: minSampleSize=${n}, elements=${s.length}`);return rt(s,tt(s,t,n,r,i,a,o),i,a)}function tt(e,t,n,r,i,a,o){let s=null,c=Array(n),l=new Uint8Array(e.length);for(let u=0;u<r;u+=1){at(e,n,o,c,l);let{inliers:r,outliers:u}=nt(e,l,i(c),a);if(s===null||n+r.length>=t){let e=[...c,...r],t=i(e),n=it(t,`createModel must assign totalModelError for comparison during RANSAC`);(s===null||n<s.error)&&(t.inliers=e,t.outliers=u,s={model:t,error:n})}}return s?.model??null}function nt(e,t,n,r){let i=[],a=[];for(let o=0;o<e.length;o+=1){if(t?.[o])continue;let s=e[o];(r(n,s)?i:a).push(s)}return{inliers:i,outliers:a}}function rt(e,t,n,r){let i=t??n(e);it(i,`RANSAC failed to produce a model with totalModelError`);let{inliers:a,outliers:o}=nt(e,null,i,r);return a.length>0&&(i=n(a),it(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function it(e,t){let{totalModelError:n}=e;if(n==null)throw Error(t);return n}function at(e,t,n,r,i){i.fill(0);let a=0;for(;a<t;){let t=Math.floor(n()*e.length);i[t]||(i[t]=1,r[a]=e[t],a+=1)}}const ot={useOnlyRecentData:!1,recentSeconds:180,includeTimeWeight:!0,weightByTimeFactor:2500,ignoreYAxisForRotation:!0,useRansac:!1,ransacInlierRatio:.95,ransacSampleRatio:.3,ransacMaxIterations:230,ransacErrorTolerance:1,geohashPrecision:8,geohashWindowSize:10,gpsAccuracyExponent:.1,altitudeAlignmentMode:`separate1D`,altitudeAggregator:`mean`,altitudeSampleSet:`all`,gpsVerticalAccuracyExponent:5,useOutlierRejection:!1,outlierThresholdMeters:10,outlierRetainRatio:.6,useDistanceGating:!1,minSampleDistanceMeters:1,maxSampleIntervalMs:3e3},st=e=>e.map(e=>B(e)),ct=e=>e.map(e=>U(e)),lt=e=>e.map(Rt),ut=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),q=e=>Array.isArray(e)?e:R(e),J=e=>Array.isArray(e)?e:z(e),dt=(e,t,n,r)=>({odometryPosOffset:B(q(e)),odometryRotOffset:U(J(t)),latestLoopClosureFixPointPos:n?B(q(n)):null,latestLoopClosureFixPointRot:r?U(J(r)):null}),ft=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...ye],alignmentRotation:[...V],alignmentTranslation:[...H],alignmentRotationInDegree:[...H],...dt(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null,lastAdmittedOdomPos:null,lastAdmittedTs:null}),pt=()=>ft(H,V,null,null),mt=(e,t,n,r)=>{let i=e.map(e=>q(e)),a=t.map(e=>U(J(e))),o=n.map(Rt),s=r.gpsAccuracyExponent;for(let e of o)e.weight=vt(e.latLongAccuracy,s);let c=o.map(It),l=r.includeTimeWeight?Mt(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?At(o,r.recentSeconds):0,d=i.slice(u).map(I),f=o.slice(u);return{allPositionTuples:i,allRotationTuples:a,allGpsPoints:o,allVec4Tuples:l,solverPositionsTyped:d,solverGpsPoints:f,solverWeightedVec4Tuples:l.slice(u),solverVerticalWeights:jt(f,r)}},ht=(e,t,n,r,i)=>{if(e==null||t==null)return!0;let a=n[0]-e[0],o=n[2]-e[2],s=i.minSampleDistanceMeters*i.minSampleDistanceMeters;return a*a+o*o>=s||r-t>=i.maxSampleIntervalMs},gt=(e,t,n,r)=>{if(!r.useDistanceGating)return{odometryPositions:e,odometryRotations:t,gpsPoints:n};let i=[],a=[],o=[],s=null,c=null;for(let l=0;l<n.length;l+=1){let u=q(e[l]),d=n[l].timestamp;ht(s,c,u,d,r)&&(i.push(e[l]),a.push(t[l]),o.push(n[l]),s=u,c=d)}return{odometryPositions:i,odometryRotations:a,gpsPoints:o}},_t=e=>{let{odometryPositions:t,odometryRotations:n,gpsPoints:r,odometryPosOffset:i=H,odometryRotOffset:s=V,latestLoopClosureFixPointPos:c=null,latestLoopClosureFixPointRot:l=null,alignmentConfig:u,random:d}=e;if(t.length!==n.length||t.length!==r.length)throw Error(`GpsEvents requires odometry positions, rotations, and gps points to have identical lengths`);let f={...ot,...u??{}};if(t.length===0)return ft(i,s,c,l);let p=gt(t,n,r,f),{allPositionTuples:m,allRotationTuples:h,allGpsPoints:g,allVec4Tuples:_,solverPositionsTyped:v,solverGpsPoints:y,solverWeightedVec4Tuples:b,solverVerticalWeights:x}=mt(p.odometryPositions,p.odometryRotations,p.gpsPoints,f),S=St(v,b,x,f,d??Math.random),C=a.create(),w=o.create(),T=o.create();bt(S.matrix,C,w,T);let{mean:E,median:D}=Pt(g),O=Nt(p.gpsPoints,f.geohashPrecision,f.geohashWindowSize),k=m.length-1,A=k>=0?B(m[k]):null,j=k>=0?p.gpsPoints[k]?.timestamp??null:null;return{odometryPositions:st(m),odometryRotations:ct(h),gpsPositions:lt(g),gpsPositionsVec4:ut(_),alignmentMatrix:ge(S.matrix),alignmentRotation:z(C),alignmentTranslation:R(w),alignmentRotationInDegree:R(T),...dt(i,s,c,l),gpsAccuracyMedian:D,gpsAccuracyMean:E,currentGpsPosGeoHash:O,lastAdmittedOdomPos:A,lastAdmittedTs:j}},vt=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,yt=(e,t,n,r,i,s)=>{let c={...ot,...i??{}},l=q(t);if(c.useDistanceGating&&!ht(e.lastAdmittedOdomPos,e.lastAdmittedTs,l,r.timestamp,c))return;let u=e.odometryPositions,d=e.odometryRotations,f=e.gpsPositions,p=e.gpsPositionsVec4;u.push(l),d.push(U(J(n)));let m=Rt(r);f.push(m),m.weight=vt(m.latLongAccuracy,c.gpsAccuracyExponent);let h=It(m);if(c.includeTimeWeight){p.push(h);let e=Mt(p,f,c.weightByTimeFactor);for(let t=0;t<e.length;t++)p[t]=e[t]}else p.push(h);let g=0;c.useOnlyRecentData&&(g=At(f,c.recentSeconds));let _=St(u.slice(g).map(I),p.slice(g),jt(f.slice(g),c),c,s??Math.random);e.alignmentMatrix=ge(_.matrix);let v=a.create(),y=o.create(),b=o.create();bt(_.matrix,v,y,b),e.alignmentRotation=z(v),e.alignmentTranslation=R(y),e.alignmentRotationInDegree=R(b);let{mean:x,median:S}=Pt(f);e.gpsAccuracyMean=x,e.gpsAccuracyMedian=S,e.currentGpsPosGeoHash=Nt(f,c.geohashPrecision,c.geohashWindowSize),e.lastAdmittedOdomPos=B(l),e.lastAdmittedTs=r.timestamp},bt=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),Ft(t,r)},Y=o.create(),xt=o.create(),St=(e,t,n,r,a)=>{if(e.length===0)return{matrix:i.create(),meanError:0};let o=e.length,c=[];for(let r=0;r<o;r+=1){let i=t[r];c.push({odom:e[r],ref:s.fromValues(i[0],i[1],i[2],i[3]),verticalWeight:n[r]??1})}let l,u,d;if(r.useRansac&&c.length>=3){let e=c.length,t=Math.max(3,Math.min(e,Math.ceil(e*r.ransacSampleRatio))),n=et(c,Math.max(t,Math.min(e,Math.ceil(e*r.ransacInlierRatio))),t,r.ransacMaxIterations,e=>X(e,r.ignoreYAxisForRotation),(e,t)=>Et(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else if(r.useOutlierRejection&&c.length>=4){let{model:e,inliers:t}=kt(c,r);l=e.alignmentMatrix,u=e.meanAlignmentError,d=t}else{let e=X(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&Ct(l,c,d,r),{matrix:l,meanError:u}},Ct=(e,t,n,r)=>{let i=r.altitudeSampleSet===`horizontalInliers`&&n!==void 0&&n.length>0?n:t;if(i.length===0)return;let a=Array(i.length),o=Array(i.length);for(let e=0;e<i.length;e+=1){let t=i[e];a[e]=t.ref[1]-t.odom[1];let n=t.verticalWeight;o[e]=n>0&&Number.isFinite(n)?n:0}e[13]=r.altitudeAggregator===`median`?Tt(a,o):wt(a,o)},wt=(e,t)=>{let n=0,r=0;for(let i=0;i<e.length;i+=1)n+=e[i]*t[i],r+=t[i];if(r>0&&Number.isFinite(r))return n/r;let i=0;for(let t=0;t<e.length;t+=1)i+=e[t];return e.length===0?0:i/e.length},Tt=(e,t)=>{if(e.length===0)return 0;if(e.length===1)return e[0];let n=e.map((e,t)=>t);n.sort((t,n)=>e[t]-e[n]);let r=0;for(let e=0;e<t.length;e+=1)r+=t[e];if(!(r>0)||!Number.isFinite(r)){let t=n.map(t=>e[t]);return t[Math.floor((t.length-1)/2)]}let i=r/2,a=0;for(let r=0;r<n.length;r+=1)if(a+=t[n[r]],a>=i)return e[n[r]];return e[n[n.length-1]]},X=(e,t)=>{let n=Array.from(e),r=n.length,i=Array(r),a=Array(r);for(let e=0;e<r;e+=1)i[e]=n[e].odom,a[e]=n[e].ref;let s=Ze(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(Y,i[e],s),c+=Dt(Y,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},Et=(e,t)=>(o.transformMat4(Y,t.odom,e.alignmentMatrix),Dt(Y,t.ref)),Dt=(e,t)=>(o.set(xt,t[0],t[1],t[2]),o.squaredDistance(e,xt)),Ot=(e,t)=>{o.transformMat4(Y,t.odom,e.alignmentMatrix);let n=Y[0]-t.ref[0],r=Y[2]-t.ref[2];return n*n+r*r},kt=(e,t)=>{let n=e.length,r=Math.max(3,Math.ceil(t.outlierRetainRatio*n)),i=t.outlierThresholdMeters*t.outlierThresholdMeters,a=Array.from(e),o=X(a,t.ignoreYAxisForRotation);for(;a.length>r;){let e=-1,n=-1;for(let t=0;t<a.length;t+=1){let r=Ot(o,a[t]);r>n&&(n=r,e=t)}if(n<=i||e<0)break;a=a.filter((t,n)=>n!==e),o=X(a,t.ignoreYAxisForRotation)}return{model:o,inliers:a}},At=(e,t)=>{if(e.length===0||t<=0)return 0;let n=e[e.length-1].timestamp-t*1e3;for(let t=0;t<e.length;t+=1)if(e[t].timestamp>=n)return t;return 0},jt=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return vt(t!=null&&Number.isFinite(t)&&t>0?t:e.latLongAccuracy,n)});if(!t.includeTimeWeight||e.length<2)return r;let i=e[e.length-1].timestamp,a=e[0].timestamp,o=Math.max(1,i-a),s=t.weightByTimeFactor;return r.map((t,n)=>{if(!(t>0&&Number.isFinite(t)))return 0;let r=s*((i-e[n].timestamp)/o)+1;return 1/(1/t+r)})},Mt=(e,t,n)=>{if(e.length<2)return e.map(e=>[e[0],e[1],e[2],e[3]]);let r=t[t.length-1].timestamp,i=t[0].timestamp,a=Math.max(1,r-i);return e.map((e,i)=>{let o=n*((r-t[i].timestamp)/a)+1,s=t[i].weight;if(!(s>0&&Number.isFinite(s)))return[e[0],e[1],e[2],0];let c=1/(1/s+o);return[e[0],e[1],e[2],c]})},Z=new Map,Nt=(e,t,n)=>{if(e.length===0)return null;let r=Math.max(0,e.length-n);Z.clear();for(let n=r;n<e.length;n+=1){let r=e[n],i=re(Lt(r),t),a=Z.get(i);a?(a.count+=1,a.index=n):Z.set(i,{count:1,index:n})}let i=null,a=-1,o=-1;for(let[e,{count:t,index:n}]of Z)(t>a||t===a&&n>o)&&(i=e,a=t,o=n);return i},Pt=e=>{let t=e.map(e=>e.latLongAccuracy).filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length===0)return{mean:null,median:null};let n=t.reduce((e,t)=>e+t,0)/t.length,r=t.slice().sort((e,t)=>e-t),i=Math.floor(r.length/2);return{mean:n,median:r.length%2==0?(r[i-1]+r[i])/2:r[i]}},Ft=(e,t)=>{let n=e[0],r=e[1],i=e[2],a=e[3],s=2*(a*n+r*i),c=1-2*(n*n+r*r),l=Math.atan2(s,c),u=2*(a*r-i*n),d;d=Math.abs(u)>=1?Math.PI/2*Math.sign(u):Math.asin(u);let f=2*(a*i+n*r),p=1-2*(r*r+i*i),m=Math.atan2(f,p),h=180/Math.PI,g=t??o.create();return g[0]=l*h,g[1]=d*h,g[2]=m*h,g},It=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Lt=e=>({lat:e.latitude,lon:e.longitude}),Rt=e=>({...e,zeroRef:{lat:e.zeroRef.lat,lon:e.zeroRef.lon},coordinates:[e.coordinates[0],e.coordinates[1],e.coordinates[2]],timestamp:e.timestamp,deviceRotation:e.deviceRotation?U(J(e.deviceRotation)):void 0,absoluteOrientation:e.absoluteOrientation?{...e.absoluteOrientation,quaternion:[e.absoluteOrientation.quaternion[0],e.absoluteOrientation.quaternion[1],e.absoluteOrientation.quaternion[2],e.absoluteOrientation.quaternion[3]]}:void 0}),zt=({lat:e,lon:t})=>{if(!Number.isFinite(e))throw Error(`Invalid latitude value: ${e}`);if(!Number.isFinite(t))throw Error(`Invalid longitude value: ${t}`);if(e<-90||e>90)throw Error(`Invalid latitude range: ${e}`);if(t<-180||t>180)throw Error(`Invalid longitude range: ${t}`)},Bt=o.fromValues(1,1,1),Vt=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],Ht=(e,t,n,r)=>{let i=N(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),a=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?K(Ae(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:R(i),weight:1,deviceRotation:a,absoluteOrientation:r}},Ut=(e,t,n)=>{if(e)return Ae(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},Wt=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},Gt=e=>{let t=Wt(a.normalize(a.create(),L(e.lastSensorRot))),n=a.normalize(a.create(),L(e.lastValidOdomRot)),r=a.multiply(a.create(),t,n),i=a.normalize(a.create(),L(e.newSensorRot)),o=a.multiply(a.create(),i,r),s=a.normalize(a.create(),L(e.newOdomRot)),c=a.multiply(a.create(),o,s);return a.normalize(c,c),z(c)},Kt=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),L(t)),I(e),Bt),n},qt=(e,t,n)=>{let r=o.create(),s=o.create(),c=a.create(),l=a.create();i.getTranslation(r,e),i.getTranslation(s,t),i.getRotation(c,e),i.getRotation(l,t);let u=o.create();o.lerp(u,r,s,n);let d=a.create();return a.slerp(d,c,l,n),i.fromRotationTranslation(i.create(),d,u)},Jt=(e,t)=>{if(e.length===0)return[];let n=e[e.length-1],r=i.invert(i.create(),n);if(!r)throw Error(`End pose matrix is not invertible`);let a=i.multiply(i.create(),t,r),o=i.create(),s=e.length-1;return e.map((e,t)=>{let n=qt(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},Yt=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},Xt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],Zt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3],Qt=t({name:`gpsData`,initialState:null,reducers:{setZeroPos:{reducer:(e,t)=>e===null?{zero:t.payload,gpsEvents:pt(),odometryPath:fe()}:e,prepare:e=>(zt(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a,rawAbsoluteOrientation:o}=t.payload,s=Ht(i,e.zero,a,o);yt(e.gpsEvents,W(n),G(r),s)},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=Vt(e.gpsEvents.odometryPosOffset,W(t.payload.lastValidOdomPos)),r=Ut(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=Ut(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(_t({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:Gt({...t.payload,lastValidOdomRot:G(t.payload.lastValidOdomRot),newOdomRot:G(t.payload.newOdomRot),lastSensorRot:K(r),newSensorRot:K(i)}),latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},arLoopClosureDetected:(e,t)=>{if(!e)return e;let n=e.gpsEvents;if(n.odometryPositions.length===0)return e;let r=n.latestLoopClosureFixPointPos?Yt(n.odometryPositions,n.latestLoopClosureFixPointPos,Xt):0,s=n.latestLoopClosureFixPointRot?Yt(n.odometryRotations,n.latestLoopClosureFixPointRot,Zt):0;if(r<0||s<0)throw Error(`Loop closure fix point could not be located in history`);if(r!==s)throw Error(`Loop closure fix point indices for position and rotation diverged`);let l=n.odometryPositions.slice(0,r).map(e=>B(e)),u=n.odometryRotations.slice(0,r).map(e=>U(e)),d=n.odometryPositions.slice(r).map(e=>B(e)),f=n.odometryRotations.slice(r).map(e=>U(e)),p=d.map((e,t)=>Kt(e,f[t])),m=Kt(W(t.payload.lastPos),U(G(t.payload.lastRot)));p.push(m);let h=Jt(p,Kt(W(t.payload.newPos),U(G(t.payload.newRot)))),g=[],_=[],v=o.create();for(let e=0;e<h.length-1;e+=1){let t=h[e],n=o.create();i.getTranslation(n,t);let r=a.create();if(i.getRotation(r,t),a.normalize(r,r),i.getScaling(v,t),Math.hypot(v[0]-1,v[1]-1,v[2]-1)>.05)throw Error(`Unexpected scale drift encountered during loop closure correction`);g.push(R(n)),_.push(z(r))}e.gpsEvents=c(_t({odometryPositions:l.concat(g),odometryRotations:u.concat(_),gpsPoints:n.gpsPositions,odometryPosOffset:n.odometryPosOffset,odometryRotOffset:n.odometryRotOffset,latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},add2dImage:(e,t)=>{if(!e)return e;e.odometryPath.points.push(c({imageFile:t.payload.imageFile,screenRotation:t.payload.screenRotation,position:W(t.payload.position),rotation:U(G(t.payload.rotation)),capturedAt:t.payload.capturedAt,width:t.payload.width,height:t.payload.height}))}}}),{setZeroPos:$t,recordGpsEvent:en,odometryTrackingRestarted:tn,arLoopClosureDetected:nn,add2dImage:rn}=Qt.actions,an=p($t),on=p(en),sn=p(tn),cn=p(nn),ln=p(rn),un=m(Qt.reducer),dn=t({name:`gpsElements`,initialState:pe(),reducers:{addMarker:(e,t)=>{e.gpsMarkers.push(t.payload)},addLine:(e,t)=>{e.gpsLines.push(t.payload)},addArea:(e,t)=>{e.areas.push(t.payload)},addToHeatMaps:(e,t)=>{let{category:n,tiles:r}=t.payload,i=e.heatMap[n]??{};e.heatMap[n]={...i,...r}},addHeatMapArea:(e,t)=>{let n=t.payload,r=n.category;if(e.heatAreas[r]||(e.heatAreas[r]={}),e.heatAreas[r][n.geoHash])throw Error(`HeatArea collision detected for GeoHash: ${n.geoHash}`);e.heatAreas[r][n.geoHash]=n},resetGpsElements:()=>pe()}}),{addMarker:fn,addLine:pn,addArea:mn,addToHeatMaps:hn,addHeatMapArea:gn,resetGpsElements:_n}=dn.actions,vn=p(fn),yn=p(pn),bn=p(mn),xn=p(hn),Sn=p(gn),Cn=p(_n),wn=m(dn.reducer),Tn=()=>({gpsData:null,gpsElements:pe(),arElements:me()}),En=e=>{let t=Array.from({length:Math.min(e.length,4)},(t,n)=>e[n].toFixed(2));e.length>4&&t.push(`…`);let n=`[${t.join(`, `)}]`;if(e.length===4){let{pitch:t,yaw:r,roll:i}=v(e);return`${n} (pitch=${t.toFixed(0)}°, yaw=${r.toFixed(0)}°, roll=${i.toFixed(0)}°)`}return n},Dn=e=>(e.length===3||e.length===4||e.length===16)&&e.every(e=>typeof e==`number`),Q=(e,t=0)=>{if(t>10||e==null)return e;if(Array.isArray(e))return Dn(e)?En(e):e.map(e=>Q(e,t+1));if(typeof e==`object`){let n={};for(let[r,i]of Object.entries(e))n[r]=Q(i,t+1);return n}return e},On=(t={})=>{let{preloadedState:n,enableDevToolsSanitizers:r=!0,enableDevChecks:i=!0,licenseKey:a}=t;if(a==null)throw Error(`License key required. Pass options.licenseKey or use createRecorderStore() from gps-plus-slam-app-framework. See EULA §3.`);g(a);let o=Tn(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:un,gpsElements:wn,arElements:Je},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:Q,stateSanitizer:Q}:!0})},kn=Math.PI/180,An=180/Math.PI,jn=2025,Mn=2025,Nn=2030,Pn=6378137;Pn*(1-1/298.257223563);const Fn=[[1,0,-29351.8,0,12,0],[1,1,-1410.8,4545.4,9.7,-21.5],[2,0,-2556.6,0,-11.6,0],[2,1,2951.1,-3133.6,-5.2,-27.7],[2,2,1649.3,-815.1,-8,-12.1],[3,0,1361,0,-1.3,0],[3,1,-2404.1,-56.6,-4.2,4],[3,2,1243.8,237.5,.4,-.3],[3,3,453.6,-549.5,-15.6,-4.1],[4,0,895,0,-1.6,0],[4,1,799.5,278.6,-2.4,-1.1],[4,2,55.7,-133.9,-6,4.1],[4,3,-281.1,212,5.6,1.6],[4,4,12.1,-375.6,-7,-4.4],[5,0,-233.2,0,.6,0],[5,1,368.9,45.4,1.4,-.5],[5,2,187.2,220.2,0,2.2],[5,3,-138.7,-122.9,.6,.4],[5,4,-142,43,2.2,1.7],[5,5,20.9,106.1,.9,1.9],[6,0,64.4,0,-.2,0],[6,1,63.8,-18.4,-.4,.3],[6,2,76.9,16.8,.9,-1.6],[6,3,-115.7,48.8,1.2,-.4],[6,4,-40.9,-59.8,-.9,.9],[6,5,14.9,10.9,.3,.7],[6,6,-60.7,72.7,.9,.9],[7,0,79.5,0,-0,0],[7,1,-77,-48.9,-.1,.6],[7,2,-8.8,-14.4,-.1,.5],[7,3,59.3,-1,.5,-.8],[7,4,15.8,23.4,-.1,0],[7,5,2.5,-7.4,-.8,-1],[7,6,-11.1,-25.1,-.8,.6],[7,7,14.2,-2.3,.8,-.2],[8,0,23.2,0,-.1,0],[8,1,10.8,7.1,.2,-.2],[8,2,-17.5,-12.6,0,.5],[8,3,2,11.4,.5,-.4],[8,4,-21.7,-9.7,-.1,.4],[8,5,16.9,12.7,.3,-.5],[8,6,15,.7,.2,-.6],[8,7,-16.8,-5.2,-0,.3],[8,8,.9,3.9,.2,.2],[9,0,4.6,0,-0,0],[9,1,7.8,-24.8,-.1,-.3],[9,2,3,12.2,.1,.3],[9,3,-.2,8.3,.3,-.3],[9,4,-2.5,-3.3,-.3,.3],[9,5,-13.1,-5.2,0,.2],[9,6,2.4,7.2,.3,-.1],[9,7,8.6,-.6,-.1,-.2],[9,8,-8.7,.8,.1,.4],[9,9,-12.9,10,-.1,.1],[10,0,-1.3,0,.1,0],[10,1,-6.4,3.3,0,0],[10,2,.2,0,.1,-0],[10,3,2,2.4,.1,-.2],[10,4,-1,5.3,-0,.1],[10,5,-.6,-9.1,-.3,-.1],[10,6,-.9,.4,0,.1],[10,7,1.5,-4.2,-.1,0],[10,8,.9,-3.8,-.1,-.1],[10,9,-2.7,.9,-0,.2],[10,10,-3.9,-9.1,-0,-0],[11,0,2.9,0,0,0],[11,1,-1.5,0,-0,-0],[11,2,-2.5,2.9,0,.1],[11,3,2.4,-.6,0,-0],[11,4,-.6,.2,0,.1],[11,5,-.1,.5,-.1,-0],[11,6,-.6,-.3,0,-0],[11,7,-.1,-1.2,-0,.1],[11,8,1.1,-1.7,-.1,-0],[11,9,-1,-2.9,-.1,0],[11,10,-.2,-1.8,-.1,0],[11,11,2.6,-2.3,-.1,0],[12,0,-2,0,0,0],[12,1,-.2,-1.3,0,-0],[12,2,.3,.7,-0,0],[12,3,1.2,1,-0,-.1],[12,4,-1.3,-1.4,-0,.1],[12,5,.6,-0,-0,-0],[12,6,.6,.6,.1,-0],[12,7,.5,-.1,-0,-0],[12,8,-.1,.8,0,0],[12,9,-.4,.1,0,-0],[12,10,-.2,-1,-.1,-0],[12,11,-1.3,.1,-0,0],[12,12,-.7,.2,-.1,-.1]];function In(){let e=()=>Array.from({length:13},()=>Array(13).fill(0)),t={g:e(),h:e(),gdot:e(),hdot:e()};for(let[e,n,r,i,a,o]of Fn)t.g[e][n]=r,t.h[e][n]=i,t.gdot[e][n]=a,t.hdot[e][n]=o;return t}const $=In();function Ln(){let e=Array(169).fill(0),t=Array(169).fill(0),n=Array(13).fill(0),r=Array(13).fill(0),i=Array(169).fill(0),a=Array(169).fill(0),o=(e,t)=>e*13+t;for(let e=1;e<=12;e++)for(let t=0;t<=e;t++){let n=$.g[e][t],r=$.h[e][t],s=$.gdot[e][t],c=$.hdot[e][t];i[o(t,e)]=n,a[o(t,e)]=s,t!==0&&(i[o(e,t-1)]=r,a[o(e,t-1)]=c)}e[o(0,0)]=1;for(let s=1;s<=12;s++){e[o(0,s)]=e[o(0,s-1)]*(2*s-1)/s;let c=2;for(let n=0,r=(s-n+1)/1;r>0;r--,n+=1){if(t[o(n,s)]=((s-1)*(s-1)-n*n)/((2*s-1)*(2*s-3)),n>0){let t=(s-n+1)*c/(s+n);e[o(n,s)]=e[o(n-1,s)]*Math.sqrt(t),c=1,i[o(s,n-1)]=e[o(n,s)]*i[o(s,n-1)],a[o(s,n-1)]=e[o(n,s)]*a[o(s,n-1)]}i[o(n,s)]=e[o(n,s)]*i[o(n,s)],a[o(n,s)]=e[o(n,s)]*a[o(n,s)]}n[s]=s+1,r[s]=s}return t[o(1,1)]=0,r[0]=0,{snorm:e,k:t,fn:n,fm:r,c:i,cd:a,idx:o}}const Rn=Ln();function zn(e){return e%4==0&&e%100!=0||e%400==0?366:365}function Bn(e){let t=e.getUTCFullYear(),n=Date.UTC(t,0,1);return t+Math.floor((e.getTime()-n)/864e5)/zn(t)}let Vn=!1;function Hn(e){return e===void 0?2027.5:typeof e==`number`?e>1e4?Bn(new Date(e)):e:Bn(e)}function Un(e,t,n){let r=Pn/1e3,i=6356752.314245179/1e3,a=r*r,o=i*i,s=a-o,c=a*a;c-o*o;let l=t*t,u=n*n,d=Math.sqrt(a-s*l),f=e*d,p=(f+a)/(f+o)*((f+a)/(f+o)),m=t/Math.sqrt(p*u+l),h=Math.sqrt(1-m*m),g=Math.sqrt(e*e+2*f+(c-22083078973482.75*l)/(d*d)),_=Math.sqrt(a*u+o*l);return{r:g,ct:m,st:h,ca:(e+_)/g,sa:s/_*t*n/g}}function Wn(e,t,n,r,i,a,o,s){if(i===a){e[r(a,i)]=o*e[r(a-1,i-1)],t[r(a,i)]=o*t[r(a-1,i-1)]+s*e[r(a-1,i-1)];return}if(i===1&&a===0){e[r(a,i)]=s*e[r(a,i-1)],t[r(a,i)]=s*t[r(a,i-1)]-o*e[r(a,i-1)];return}a>i-2&&(e[r(a,i-2)]=0,t[r(a,i-2)]=0),e[r(a,i)]=s*e[r(a,i-1)]-n[r(a,i)]*e[r(a,i-2)],t[r(a,i)]=s*t[r(a,i-1)]-o*e[r(a,i-1)]-n[r(a,i)]*t[r(a,i-2)]}function Gn(e,t,n,r){let i=r-jn;(r<2025||r>=2030)&&!Vn&&(Vn=!0,console.warn(`magneticDeclinationDeg: date ${r.toFixed(3)} is outside the WMM2025 validity window [${Mn}, ${Nn}); using linear secular extrapolation (accuracy degrades).`));let{snorm:a,k:o,fn:s,fm:c,c:l,cd:u,idx:d}=Rn,f=t*kn,p=e*kn,m=Math.sin(f),h=Math.sin(p),g=Math.cos(f),_=Math.cos(p),v=Array(13).fill(0),y=Array(13).fill(0);v[0]=0,y[0]=1,v[1]=m,y[1]=g;let{r:b,ct:x,st:S,ca:C,sa:w}=Un(n,h,_);for(let e=2;e<=12;e++)v[e]=m*y[e-1]+g*v[e-1],y[e]=g*y[e-1]-m*v[e-1];let T=6371.2/b,E=T*T,D=0,O=0,k=0,A=a.slice(),j=Array(169).fill(0);for(let e=1;e<=12;e++){E*=T;for(let t=0,n=(e+t+1)/1;n>0;n--,t+=1){Wn(A,j,o,d,e,t,S,x);let n=l[d(t,e)]+i*u[d(t,e)],r=E*A[d(t,e)],a,f;if(t===0)a=n*y[t],f=n*v[t];else{let r=l[d(e,t-1)]+i*u[d(e,t-1)];a=n*y[t]+r*v[t],f=n*v[t]-r*y[t]}D-=E*a*j[d(t,e)],O+=c[t]*f*r,k+=s[e]*a*r}}let M;return M=S===0?0:O/S,{x:-D*C-k*w,y:M,z:D*w-k*C}}function Kn(e){let t=e%360;return t<0?t+360:t}function qn(e,t,n){if(!Number.isFinite(e)||!Number.isFinite(t))return NaN;let r=n?.altitudeKm??0;if(!Number.isFinite(r))return NaN;let{x:i,y:a}=Gn(e,t,r,Hn(n?.date));return Math.atan2(a,i)*An}function Jn(e,t,n,r){return Kn(e+qn(t,n,r))}const Yn=.08,Xn=180/Math.PI,Zn=e=>(e%360+360)%360,Qn=(e,t)=>{let[n,r,i,a]=e,[o,s,c]=t,l=2*(r*c-i*s),u=2*(i*o-n*c),d=2*(n*s-r*o);return[o+a*l+(r*d-i*u),s+a*u+(i*l-n*d),c+a*d+(n*u-r*l)]};function $n(e){let[t,n,r,i]=e,a=-2*(t*r+i*n),o=-2*(n*r-i*t);return Math.hypot(a,o)<Yn?null:Zn(Math.atan2(a,o)*Xn)}const er=[0,0,-1];function tr(e,t){return Te(e,Ee(t))}function nr(e,t){let[n,r]=Qn(tr(e,t),er);return Math.hypot(n,r)<Yn?null:Zn(Math.atan2(n,r)*Xn)}function rr(e,t){let n=((e-t+180)%360+360)%360-180;return n===-180&&(n=180),n}const ir=[],ar=[],or=[],sr={median:null,mean:null},cr=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),lr=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),ur=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??ir}),dr=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??ar}),fr=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??or}),pr=f(function(e){return e.gpsData?.zero??null}),mr=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?sr:{median:t,mean:n}}),hr=`1.0.0`;export{ye as IDENTITY_MATRIX4,V as IDENTITY_QUATERNION,hr as LIB_VERSION,jn as WMM2025_EPOCH,Mn as WMM2025_VALID_FROM,Nn as WMM2025_VALID_TO,H as ZERO_VECTOR3,ln as add2dImage,bn as addArea,Ue as addCornerToEventArea,Sn as addHeatMapArea,yn as addLine,vn as addMarker,Ve as addOrUpdateArPlane,xn as addToHeatMaps,Ke as anchorEventAreaInWorldSpace,Je as arElementsReducer,cn as arLoopClosureDetected,nr as arNorthBearingDeg,tr as arToEnuRotation,rr as bearingDeltaDeg,re as calcGeoHash,P as calcGpsCoords,te as calcQuadKey,N as calcRelativeCoordsInMeters,ve as cloneMatrix4,_e as cloneQuaternion,B as cloneVector3,We as correctArDriftForEventArea,On as createGpsSlamStore,ae as distanceInMeters,oe as distanceInMetersRelative,K as enuQuaternionToNUE,Ae as eulerToQuaternion,Ge as finishEventArea,he as fromMatrix4,L as fromQuaternion,I as fromVector3,de as fusedGpsFromOdom,ie as geoHashToLatLong,cr as getAlignmentMatrix,lr as getAlignmentRotation,le as getGoogleMapsDirectionsLink,ce as getGoogleMapsLink,mr as getGpsAccuracyStats,fr as getGpsPositions,ur as getOdometryPositions,dr as getOdometryRotations,ue as getOpenStreetMapLink,pr as getZeroReference,un as gpsDataReducer,wn as gpsElementsReducer,Ee as invertQuaternion,be as isIdentityMatrix4,Se as isIdentityQuaternion,Ce as isNearIdentityQuaternion,qn as magneticDeclinationDeg,$n as magneticHeadingFromEnuQuat,Jn as magneticToTrueHeadingDeg,Te as multiplyQuaternions,U as normalizeQuaternion,ke as nueQuaternionToENU,Oe as nueQuaternionToWebXR,De as nueToWebXR,sn as odometryTrackingRestarted,ne as quadKeyToLatLong,xe as quaternionMagnitude,we as quaternionsEquivalent,on as recordGpsEvent,Be as recordPhoneHeight,qe as resetArElements,Cn as resetGpsElements,Q as sanitizeForDevTools,an as setZeroPos,He as startEventArea,se as toEarthCenteredCoordinates,ge as toMatrix4,z as toQuaternion,R as toVector3,g as validateLicenseKey,G as webxrQuaternionToNUE,W as webxrToNUE};
|
|
2
|
+
import{configureStore as e,createSlice as t}from"@reduxjs/toolkit";import{ed25519 as n}from"@noble/curves/ed25519.js";import{hexToBytes as r}from"@noble/curves/utils.js";import{mat4 as i,quat as a,vec3 as o,vec4 as s}from"gl-matrix";import{castDraft as c}from"immer";let l=!1;function u(){l=!0}function d(){if(!l)throw Error(`gps-plus-slam-js: license not activated. Construct your store via createRecorderStore() from gps-plus-slam-app-framework, or pass a valid licenseKey to createGpsSlamStore(). See EULA §3.`)}function f(e){return((...t)=>(d(),e(...t)))}function p(e){let t=((...t)=>(d(),e(...t)));return Object.assign(t,e),t.toString=()=>e.type,t}function m(e){return(t,n)=>(d(),e(t,n))}function h(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=`=`.repeat((4-t.length%4)%4),r=atob(t+n);return Uint8Array.from(r,e=>e.charCodeAt(0))}function g(e){let t=new Date,i=e.indexOf(`.`);if(i<=0||i>=e.length-1)throw Error(`Invalid license key format: expected "payload.signature" with base64url-encoded parts.`);let a,o;try{a=h(e.substring(0,i)),o=h(e.substring(i+1))}catch{throw Error(`Invalid license key format: base64url decoding failed.`)}let s=r(`dfe5c62120b7a0ce962b17907a15b27cf1b056e6619bf6ce55e6e094b322a470`);if(!n.verify(o,a,s))throw Error(`Invalid license key: signature verification failed.`);let c=JSON.parse(new TextDecoder().decode(a));if(typeof c!=`object`||!c)throw Error(`Invalid license key: payload must be a JSON object.`);let{type:l,exp:d}=c;if(l!==`community`)throw Error(`Invalid license key: "type" must be "community".`);if(typeof d!=`number`||!Number.isFinite(d))throw Error(`Invalid license key: "exp" must be a finite number (Unix timestamp in seconds).`);if(d<Math.floor(t.getTime()/1e3)){let e=new Date(d*1e3);throw Error(`License key expired on ${e.toISOString()}. Update to the latest version for a renewed community key.`)}return u(),{type:l,expiresAt:new Date(d*1e3)}}const _=180/Math.PI,v=e=>{let t=e[0],n=e[1],r=e[2],i=e[3],a=2*(i*t+n*r),o=1-2*(t*t+n*n),s=Math.atan2(a,o)*_,c=2*(i*n-r*t),l=Math.abs(c)>=1?Math.sign(c)*90:Math.asin(c)*_,u=2*(i*r+t*n),d=1-2*(n*n+r*r);return{pitch:l,yaw:Math.atan2(u,d)*_,roll:s}},y=1/298.257223563,b=y*(2-y),x=40075016.6856/360,S=39940652.7422/360,C=Math.PI/180,w=180/Math.PI,T=`0123456789bcdefghjkmnpqrstuvwxyz`,E=[16,8,4,2,1],D=(e,t,n)=>Math.min(Math.max(e,t),n),ee=e=>D(e,-180,180),O=e=>e*C,te=e=>e*w,k=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},A=e=>({lat:k(e.lat),lon:k(e.lon)}),ne=(e,t=0)=>{let n=O(e.lat),r=O(e.lon),i=Math.sin(n),a=Math.cos(n),s=Math.sin(r),c=Math.cos(r),l=6378137/Math.sqrt(1-b*i*i),u=(l+t)*a*c,d=(l+t)*a*s,f=(l*(1-b)+t)*i;return o.fromValues(u,d,f)},re=f((e,t)=>{if(t<1||t>23)throw RangeError(`levelOfDetail must be between 1 and 23 (inclusive)`);let n=D(e.lat,-85.05112878,85.05112878),r=ee(e.lon),i=Math.sin(O(n)),a=256*2**t,o=(r+180)/360*a,s=(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*a,c=2**t-1,l=D(Math.floor(o/256),0,c),u=D(Math.floor(s/256),0,c),d=``;for(let e=t;e>0;--e){let t=0,n=1<<e-1;(l&n)!==0&&(t+=1),(u&n)!==0&&(t+=2),d+=t.toString()}return d}),ie=f(e=>{if(!/^[0-3]+$/.test(e))throw Error(`QuadKey must consist of digits 0-3`);let t=e.length;if(t===0)throw Error(`QuadKey must not be empty`);let n=0,r=0;for(let i=0;i<t;i+=1){let a=Number.parseInt(e[i],10),o=1<<t-i-1;a&1&&(n+=o),a&2&&(r+=o)}let i=256*2**t,a=(n+.5)*256,o=(r+.5)*256,s=a/i,c=o/i,l=s*360-180;return{lat:te(Math.atan(Math.sinh(Math.PI*(1-2*c)))),lon:l}}),ae=f((e,t)=>{if(t<=0)throw RangeError(`precision must be greater than 0`);let n=-90,r=90,i=-180,a=180,o=``,s=0,c=0,l=!0;for(;o.length<t;){if(l){let t=(i+a)/2;e.lon>=t?(c|=E[s],i=t):a=t}else{let t=(n+r)/2;e.lat>=t?(c|=E[s],n=t):r=t}l=!l,s<4?s+=1:(o+=T[c],s=0,c=0)}return o}),oe=f(e=>{if(e.length===0)throw Error(`geoHash must not be empty`);let t=-90,n=90,r=-180,i=180,a=!0;for(let o of e){let e=T.indexOf(o);if(e===-1)throw Error(`Invalid geohash character: ${o}`);for(let o of E){if(a){let t=(r+i)/2;(e&o)===0?i=t:r=t}else{let r=(t+n)/2;(e&o)===0?n=r:t=r}a=!a}}return{lat:(t+n)/2,lon:(r+i)/2}}),se=f((e,t)=>{let n=O(e.lat),r=O(t.lat),i=r-n,a=O(t.lon-e.lon),o=Math.sin(i/2),s=Math.sin(a/2),c=o*o+Math.cos(n)*Math.cos(r)*s*s,l=Math.min(1,Math.max(0,c));return 6371008.8*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}),ce=f((e,t)=>{let n=le(e,t);return Math.hypot(n[0],n[2])}),le=f((e,t,n=0,r=0)=>{let i=(t.lon-e.lon)*x*Math.cos(O(e.lat)),a=(t.lat-e.lat)*S,s=n-r;return o.fromValues(a,s,i)}),ue=f((e,t)=>{let n=t[0],r=t[2];return{lat:n/S+e.lat,lon:r/(x*Math.cos(O(e.lat)))+e.lon}}),de=f((e,t=0)=>ne(e,t)),fe=e=>{let{lat:t,lon:n}=A(e);return`${t}%2C${n}`},pe=f(e=>`https://www.google.com/maps/search/?api=1&query=${fe(e)}`),me=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${fe(t)}&destination=${fe(e)}`),he=f((e,t=19)=>{let{lat:n,lon:r}=A(e);return`https://www.openstreetmap.org/query?lat=${n}&lon=${r}#map=${t}/${n}/${r}`}),ge=f((e,t,n)=>{let r=i.fromValues(...e),a=o.fromValues(t[0],t[1],t[2]),s=o.create();o.transformMat4(s,a,r);let{lat:c,lon:l}=ue(n,s);return{lat:c,lon:l,altitude:s[1]}}),_e=()=>({points:[]}),ve=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),ye=()=>({arPlanes:{},floorDetections:[],eventAreas:[],currentEventAreaId:null,currentEventAreaPoints:[]}),j=e=>o.fromValues(e[0],e[1],e[2]),M=e=>a.fromValues(e[0],e[1],e[2],e[3]),be=e=>i.fromValues(...e),N=e=>[e[0],e[1],e[2]],P=e=>[e[0],e[1],e[2],e[3]],F=e=>[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]],I=e=>[e[0],e[1],e[2]],xe=e=>[e[0],e[1],e[2],e[3]],Se=e=>[...e],L=Object.freeze([0,0,0,1]),R=Object.freeze([0,0,0]),Ce=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),z=e=>{let t=Te(e);if(t===0)return L;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},we=e=>{for(let t=0;t<16;t++)if(e[t]!==Ce[t])return!1;return!0},Te=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),Ee=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,De=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,Oe=(e,t,n=1e-10)=>{let r=Math.abs(e[0]-t[0])<n&&Math.abs(e[1]-t[1])<n&&Math.abs(e[2]-t[2])<n&&Math.abs(e[3]-t[3])<n,i=Math.abs(e[0]+t[0])<n&&Math.abs(e[1]+t[1])<n&&Math.abs(e[2]+t[2])<n&&Math.abs(e[3]+t[3])<n;return r||i},ke=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},Ae=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},B=e=>[-e[2],e[1],e[0]],je=e=>[e[2],e[1],-e[0]],V=e=>[-e[2],e[1],e[0],e[3]],Me=e=>[e[2],e[1],-e[0],e[3]],H=e=>[e[1],e[2],e[0],e[3]],Ne=e=>[e[2],e[0],e[1],e[3]],Pe=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))throw Error(`eulerToQuaternion: non-finite input (alpha=${e}, beta=${t}, gamma=${n})`);let r=e*Math.PI/180,i=t*Math.PI/180,o=n*Math.PI/180,s=a.create(),c=a.create(),l=a.create();a.setAxisAngle(s,[0,0,1],r),a.setAxisAngle(c,[1,0,0],i),a.setAxisAngle(l,[0,1,0],o);let u=a.create();return a.multiply(u,s,c),a.multiply(u,u,l),[u[0],u[1],u[2],u[3]]},Fe=t({name:`arElements`,initialState:ye(),reducers:{recordPhoneHeight:(e,t)=>{e.floorDetections.push(t.payload)},addOrUpdateArPlane:(e,t)=>{let n=t.payload;if(n.parentPlaneId){delete e.arPlanes[n.planeId];return}e.arPlanes[n.planeId]=c(n)},startEventArea:(e,t)=>{e.currentEventAreaId=t.payload.id,e.currentEventAreaPoints=[]},addCornerToEventArea:(e,t)=>{e.currentEventAreaId&&e.currentEventAreaPoints.push(c(I(t.payload.position)))},correctArDriftForEventArea:(e,t)=>{let n=t.payload.drift;for(let t of e.currentEventAreaPoints)t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]},finishEventArea:(e,t)=>{e.currentEventAreaId&&(e.eventAreas.push({id:e.currentEventAreaId,label:t.payload.label,polygon:[],isInArSpace:!0,arPoints:e.currentEventAreaPoints}),e.currentEventAreaId=null,e.currentEventAreaPoints=[])},anchorEventAreaInWorldSpace:(e,t)=>{let{areaId:n,alignmentMatrix:r,zeroRef:i}=t.payload,a=e.eventAreas.findIndex(e=>e.id===n);if(a===-1)return;let s=e.eventAreas[a];if(!s.isInArSpace||!s.arPoints)throw Error(`The area ${s.id} is already anchored in world space`);let c=be(r),l=s.arPoints.map(e=>{let t=j(e);return ue(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>ye()}}),{recordPhoneHeight:Ie,addOrUpdateArPlane:Le,startEventArea:Re,addCornerToEventArea:ze,correctArDriftForEventArea:Be,finishEventArea:Ve,anchorEventAreaInWorldSpace:He,resetArElements:Ue}=Fe.actions,We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=p(Be),Ye=p(Ve),Xe=p(He),Ze=p(Ue),Qe=m(Fe.reducer);function $e(e,t,n,r){let{inCentroid:i,refCentroid:a,refVec:s,tmp:c}=r;o.set(i,0,0,0),o.set(a,0,0,0);let l=0;for(let n=0;n<e.length;n++){let r=t[n][3];o.scaleAndAdd(i,i,e[n],r),rt(s,t[n]),o.scaleAndAdd(a,a,s,r),l+=r}if(l===0)throw Error(`Weights must not sum to zero when solving Kabsch`);let u=1/l;if(o.scale(i,i,u),o.scale(a,a,u),!n)return{inCentroid:i,refCentroid:a,scaleRatio:1};let d=0,f=0;for(let n=0;n<e.length;n++)o.subtract(c,e[n],i),d+=o.length(c),rt(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function et(e,t,n,r,a,s,c){let{negCentroid:l,scaleVec:u}=c;return i.fromRotationTranslation(e,r,n),s&&(o.set(u,a,a,a),i.scale(e,e,u)),o.negate(l,t),i.translate(e,e,l),e}function tt(e,t,n={}){let r=e.length;if(r!==t.length)throw Error(`Length of the point lists was not equal: ${r} vs ${t.length}`);if(r===0)return i.create();let s=n.solveRotation??!0,c=n.solveScale??!1,l=n.ignoreYAxisForRotation??!1,u=n.rotationIterations??9,{inCentroid:d,refCentroid:f,scaleRatio:p}=$e(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new nt(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return et(i.create(),d,f,m,p,c,h)}var nt=class e{ignoreYAxis;static twoPi=Math.PI*2;static basisX=o.fromValues(1,0,0);static basisY=o.fromValues(0,1,0);static basisZ=o.fromValues(0,0,1);constructor(e){this.ignoreYAxis=e}solve(t,n,r,i,o,s){let c=this.transposeMultSubtract(t,n,r,i);if(this.ignoreYAxis){let t=c[0][0],n=c[0][2],r=c[2][0],i=c[2][2],s=Math.atan2(r-n,t+i);a.setAxisAngle(o,e.basisY,s)}else this.extractRotation(c,o,s)}transposeMultSubtract(e,t,n,r){let i=[o.create(),o.create(),o.create()],a=o.clone(n),s=o.clone(r);this.ignoreYAxis&&(a[1]=0,s[1]=0);let c=o.create(),l=o.create(),u=o.create();for(let n=0;n<e.length;n++){o.copy(c,e[n]),rt(u,t[n]),this.ignoreYAxis&&(c[1]=0,u[1]=0);let r=t[n][3];o.subtract(c,c,a),o.scale(c,c,r),o.subtract(l,u,s),i[0][0]+=c[0]*l[0],i[1][0]+=c[1]*l[0],i[2][0]+=c[2]*l[0],i[0][1]+=c[0]*l[1],i[1][1]+=c[1]*l[1],i[2][1]+=c[2]*l[1],i[0][2]+=c[0]*l[2],i[1][2]+=c[1]*l[2],i[2][2]+=c[2]*l[2]}return i}extractRotation(t,n,r){let i=[o.create(),o.create(),o.create()],s=o.create(),c=o.create(),l=o.create();for(let u=0;u<r;u++){this.fillMatrixFromQuaternion(n,i),o.cross(s,i[0],t[0]),o.cross(l,i[1],t[1]),o.add(s,s,l),o.cross(l,i[2],t[2]),o.add(s,s,l);let r=o.dot(i[0],t[0])+o.dot(i[1],t[1])+o.dot(i[2],t[2])+1e-9;r=Math.abs(r),o.scale(s,s,1/r);let u=o.length(s);if(u<1e-9)break;o.scale(c,s,1/u);let d=u%e.twoPi,f=a.create();a.setAxisAngle(f,c,d),a.multiply(n,f,n),a.normalize(n,n)}}fillMatrixFromQuaternion(t,n){o.transformQuat(n[0],e.basisX,t),o.transformQuat(n[1],e.basisY,t),o.transformQuat(n[2],e.basisZ,t)}};const rt=(e,t)=>(e[0]=t[0],e[1]=t[1],e[2]=t[2],e);function it(e,t,n,r,i,a,o=Math.random){let s=Array.from(e);if(n>s.length)throw RangeError(`minSampleSize must be smaller than the number of elements: minSampleSize=${n}, elements=${s.length}`);return st(s,at(s,t,n,r,i,a,o),i,a)}function at(e,t,n,r,i,a,o){let s=null,c=Array(n),l=new Uint8Array(e.length);for(let u=0;u<r;u+=1){lt(e,n,o,c,l);let{inliers:r,outliers:u}=ot(e,l,i(c),a);if(s===null||n+r.length>=t){let e=[...c,...r],t=i(e),n=ct(t,`createModel must assign totalModelError for comparison during RANSAC`);(s===null||n<s.error)&&(t.inliers=e,t.outliers=u,s={model:t,error:n})}}return s?.model??null}function ot(e,t,n,r){let i=[],a=[];for(let o=0;o<e.length;o+=1){if(t?.[o])continue;let s=e[o];(r(n,s)?i:a).push(s)}return{inliers:i,outliers:a}}function st(e,t,n,r){let i=t??n(e);ct(i,`RANSAC failed to produce a model with totalModelError`);let{inliers:a,outliers:o}=ot(e,null,i,r);return a.length>0&&(i=n(a),ct(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function ct(e,t){let{totalModelError:n}=e;if(n==null)throw Error(t);return n}function lt(e,t,n,r,i){i.fill(0);let a=0;for(;a<t;){let t=Math.floor(n()*e.length);i[t]||(i[t]=1,r[a]=e[t],a+=1)}}const ut=.08,dt=180/Math.PI,ft=e=>(e%360+360)%360,pt=(e,t)=>{let[n,r,i,a]=e,[o,s,c]=t,l=2*(r*c-i*s),u=2*(i*o-n*c),d=2*(n*s-r*o);return[o+a*l+(r*d-i*u),s+a*u+(i*l-n*d),c+a*d+(n*u-r*l)]};function mt(e){let[t,n,r,i]=e,a=-2*(t*r+i*n),o=-2*(n*r-i*t);return Math.hypot(a,o)<ut?null:ft(Math.atan2(a,o)*dt)}const ht=[0,0,-1];function gt(e,t){return ke(e,Ae(t))}function _t(e,t){let[n,r]=pt(gt(e,t),ht);return Math.hypot(n,r)<ut?null:ft(Math.atan2(n,r)*dt)}function U(e,t){let n=((e-t+180)%360+360)%360-180;return n===-180&&(n=180),n}const vt=Math.PI/180,yt=180/Math.PI,bt=2025,xt=2025,St=2030,Ct=6378137;Ct*(1-1/298.257223563);const wt=[[1,0,-29351.8,0,12,0],[1,1,-1410.8,4545.4,9.7,-21.5],[2,0,-2556.6,0,-11.6,0],[2,1,2951.1,-3133.6,-5.2,-27.7],[2,2,1649.3,-815.1,-8,-12.1],[3,0,1361,0,-1.3,0],[3,1,-2404.1,-56.6,-4.2,4],[3,2,1243.8,237.5,.4,-.3],[3,3,453.6,-549.5,-15.6,-4.1],[4,0,895,0,-1.6,0],[4,1,799.5,278.6,-2.4,-1.1],[4,2,55.7,-133.9,-6,4.1],[4,3,-281.1,212,5.6,1.6],[4,4,12.1,-375.6,-7,-4.4],[5,0,-233.2,0,.6,0],[5,1,368.9,45.4,1.4,-.5],[5,2,187.2,220.2,0,2.2],[5,3,-138.7,-122.9,.6,.4],[5,4,-142,43,2.2,1.7],[5,5,20.9,106.1,.9,1.9],[6,0,64.4,0,-.2,0],[6,1,63.8,-18.4,-.4,.3],[6,2,76.9,16.8,.9,-1.6],[6,3,-115.7,48.8,1.2,-.4],[6,4,-40.9,-59.8,-.9,.9],[6,5,14.9,10.9,.3,.7],[6,6,-60.7,72.7,.9,.9],[7,0,79.5,0,-0,0],[7,1,-77,-48.9,-.1,.6],[7,2,-8.8,-14.4,-.1,.5],[7,3,59.3,-1,.5,-.8],[7,4,15.8,23.4,-.1,0],[7,5,2.5,-7.4,-.8,-1],[7,6,-11.1,-25.1,-.8,.6],[7,7,14.2,-2.3,.8,-.2],[8,0,23.2,0,-.1,0],[8,1,10.8,7.1,.2,-.2],[8,2,-17.5,-12.6,0,.5],[8,3,2,11.4,.5,-.4],[8,4,-21.7,-9.7,-.1,.4],[8,5,16.9,12.7,.3,-.5],[8,6,15,.7,.2,-.6],[8,7,-16.8,-5.2,-0,.3],[8,8,.9,3.9,.2,.2],[9,0,4.6,0,-0,0],[9,1,7.8,-24.8,-.1,-.3],[9,2,3,12.2,.1,.3],[9,3,-.2,8.3,.3,-.3],[9,4,-2.5,-3.3,-.3,.3],[9,5,-13.1,-5.2,0,.2],[9,6,2.4,7.2,.3,-.1],[9,7,8.6,-.6,-.1,-.2],[9,8,-8.7,.8,.1,.4],[9,9,-12.9,10,-.1,.1],[10,0,-1.3,0,.1,0],[10,1,-6.4,3.3,0,0],[10,2,.2,0,.1,-0],[10,3,2,2.4,.1,-.2],[10,4,-1,5.3,-0,.1],[10,5,-.6,-9.1,-.3,-.1],[10,6,-.9,.4,0,.1],[10,7,1.5,-4.2,-.1,0],[10,8,.9,-3.8,-.1,-.1],[10,9,-2.7,.9,-0,.2],[10,10,-3.9,-9.1,-0,-0],[11,0,2.9,0,0,0],[11,1,-1.5,0,-0,-0],[11,2,-2.5,2.9,0,.1],[11,3,2.4,-.6,0,-0],[11,4,-.6,.2,0,.1],[11,5,-.1,.5,-.1,-0],[11,6,-.6,-.3,0,-0],[11,7,-.1,-1.2,-0,.1],[11,8,1.1,-1.7,-.1,-0],[11,9,-1,-2.9,-.1,0],[11,10,-.2,-1.8,-.1,0],[11,11,2.6,-2.3,-.1,0],[12,0,-2,0,0,0],[12,1,-.2,-1.3,0,-0],[12,2,.3,.7,-0,0],[12,3,1.2,1,-0,-.1],[12,4,-1.3,-1.4,-0,.1],[12,5,.6,-0,-0,-0],[12,6,.6,.6,.1,-0],[12,7,.5,-.1,-0,-0],[12,8,-.1,.8,0,0],[12,9,-.4,.1,0,-0],[12,10,-.2,-1,-.1,-0],[12,11,-1.3,.1,-0,0],[12,12,-.7,.2,-.1,-.1]];function Tt(){let e=()=>Array.from({length:13},()=>Array(13).fill(0)),t={g:e(),h:e(),gdot:e(),hdot:e()};for(let[e,n,r,i,a,o]of wt)t.g[e][n]=r,t.h[e][n]=i,t.gdot[e][n]=a,t.hdot[e][n]=o;return t}const W=Tt();function Et(){let e=Array(169).fill(0),t=Array(169).fill(0),n=Array(13).fill(0),r=Array(13).fill(0),i=Array(169).fill(0),a=Array(169).fill(0),o=(e,t)=>e*13+t;for(let e=1;e<=12;e++)for(let t=0;t<=e;t++){let n=W.g[e][t],r=W.h[e][t],s=W.gdot[e][t],c=W.hdot[e][t];i[o(t,e)]=n,a[o(t,e)]=s,t!==0&&(i[o(e,t-1)]=r,a[o(e,t-1)]=c)}e[o(0,0)]=1;for(let s=1;s<=12;s++){e[o(0,s)]=e[o(0,s-1)]*(2*s-1)/s;let c=2;for(let n=0,r=(s-n+1)/1;r>0;r--,n+=1){if(t[o(n,s)]=((s-1)*(s-1)-n*n)/((2*s-1)*(2*s-3)),n>0){let t=(s-n+1)*c/(s+n);e[o(n,s)]=e[o(n-1,s)]*Math.sqrt(t),c=1,i[o(s,n-1)]=e[o(n,s)]*i[o(s,n-1)],a[o(s,n-1)]=e[o(n,s)]*a[o(s,n-1)]}i[o(n,s)]=e[o(n,s)]*i[o(n,s)],a[o(n,s)]=e[o(n,s)]*a[o(n,s)]}n[s]=s+1,r[s]=s}return t[o(1,1)]=0,r[0]=0,{snorm:e,k:t,fn:n,fm:r,c:i,cd:a,idx:o}}const Dt=Et();function Ot(e){return e%4==0&&e%100!=0||e%400==0?366:365}function kt(e){let t=e.getUTCFullYear(),n=Date.UTC(t,0,1);return t+Math.floor((e.getTime()-n)/864e5)/Ot(t)}let At=!1;function jt(e){return e===void 0?2027.5:typeof e==`number`?e>1e4?kt(new Date(e)):e:kt(e)}function Mt(e,t,n){let r=Ct/1e3,i=6356752.314245179/1e3,a=r*r,o=i*i,s=a-o,c=a*a;c-o*o;let l=t*t,u=n*n,d=Math.sqrt(a-s*l),f=e*d,p=(f+a)/(f+o)*((f+a)/(f+o)),m=t/Math.sqrt(p*u+l),h=Math.sqrt(1-m*m),g=Math.sqrt(e*e+2*f+(c-22083078973482.75*l)/(d*d)),_=Math.sqrt(a*u+o*l);return{r:g,ct:m,st:h,ca:(e+_)/g,sa:s/_*t*n/g}}function Nt(e,t,n,r,i,a,o,s){if(i===a){e[r(a,i)]=o*e[r(a-1,i-1)],t[r(a,i)]=o*t[r(a-1,i-1)]+s*e[r(a-1,i-1)];return}if(i===1&&a===0){e[r(a,i)]=s*e[r(a,i-1)],t[r(a,i)]=s*t[r(a,i-1)]-o*e[r(a,i-1)];return}a>i-2&&(e[r(a,i-2)]=0,t[r(a,i-2)]=0),e[r(a,i)]=s*e[r(a,i-1)]-n[r(a,i)]*e[r(a,i-2)],t[r(a,i)]=s*t[r(a,i-1)]-o*e[r(a,i-1)]-n[r(a,i)]*t[r(a,i-2)]}function Pt(e,t,n,r){let i=r-bt;(r<2025||r>=2030)&&!At&&(At=!0,console.warn(`magneticDeclinationDeg: date ${r.toFixed(3)} is outside the WMM2025 validity window [${xt}, ${St}); using linear secular extrapolation (accuracy degrades).`));let{snorm:a,k:o,fn:s,fm:c,c:l,cd:u,idx:d}=Dt,f=t*vt,p=e*vt,m=Math.sin(f),h=Math.sin(p),g=Math.cos(f),_=Math.cos(p),v=Array(13).fill(0),y=Array(13).fill(0);v[0]=0,y[0]=1,v[1]=m,y[1]=g;let{r:b,ct:x,st:S,ca:C,sa:w}=Mt(n,h,_);for(let e=2;e<=12;e++)v[e]=m*y[e-1]+g*v[e-1],y[e]=g*y[e-1]-m*v[e-1];let T=6371.2/b,E=T*T,D=0,ee=0,O=0,te=a.slice(),k=Array(169).fill(0);for(let e=1;e<=12;e++){E*=T;for(let t=0,n=(e+t+1)/1;n>0;n--,t+=1){Nt(te,k,o,d,e,t,S,x);let n=l[d(t,e)]+i*u[d(t,e)],r=E*te[d(t,e)],a,f;if(t===0)a=n*y[t],f=n*v[t];else{let r=l[d(e,t-1)]+i*u[d(e,t-1)];a=n*y[t]+r*v[t],f=n*v[t]-r*y[t]}D-=E*a*k[d(t,e)],ee+=c[t]*f*r,O+=s[e]*a*r}}let A;return A=S===0?0:ee/S,{x:-D*C-O*w,y:A,z:D*w-O*C}}function Ft(e){let t=e%360;return t<0?t+360:t}function It(e,t,n){if(!Number.isFinite(e)||!Number.isFinite(t))return NaN;let r=n?.altitudeKm??0;if(!Number.isFinite(r))return NaN;let{x:i,y:a}=Pt(e,t,r,jt(n?.date));return Math.atan2(a,i)*yt}function Lt(e,t,n,r){return Ft(e+It(t,n,r))}const G=Math.PI/180,Rt=180/Math.PI,K=e=>(e%360+360)%360,q=e=>e<0?0:e>1?1:e,zt=e=>{let t=0,n=0;for(let r of e)t+=Math.sin(r*G),n+=Math.cos(r*G);return t===0&&n===0?0:K(Math.atan2(t,n)*Rt)},Bt=e=>{if(e.length===0)return 0;let t=zt(e),n=0;for(let r of e){let e=Math.abs(U(r,t));e>n&&(n=e)}return n},Vt=(e,t,n)=>n<=0?+(e<=t):q((t+n-e)/n),Ht=(e,t,n)=>n<=0?+(e>=t):q((e-(t-n))/n),Ut=(e,t,n)=>{if(e.length<n.minWindow)return 0;let r=Vt(Bt(e),n.collapseThresholdDeg,n.rampWidthDeg),i=Ht(t,n.baselineMinM,n.baselineRampM);return Math.min(r,i)},Wt=e=>q(1-e),Gt=(e,t,n)=>{let r=q(n),i=Math.cos(e*G),a=Math.sin(e*G),o=Math.cos(t*G),s=Math.sin(t*G),c=o+(i-o)*r,l=s+(a-s)*r;return K(Math.hypot(c,l)<1e-9?t:Math.atan2(l,c)*Rt)},Kt=(e,t,n)=>{if(e===null)return K(t);let r=q(n);return K(e+U(t,e)*r)},J=e=>K(Math.atan2(e[2],e[0])*Rt),qt=(e,t,n)=>{let r=i.fromValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]),a=U(n,J(e)),s=o.fromValues(t[0],t[1],t[2]),c=o.create();o.transformMat4(c,s,r);let l=i.create();i.fromYRotation(l,-a*G);let u=i.create();i.fromTranslation(u,c),i.multiply(u,u,l);let d=o.fromValues(-c[0],-c[1],-c[2]);i.translate(u,u,d);let f=i.create();return i.multiply(f,u,r),F(f)},Jt=()=>({state:`dormant`,agreeStreak:0,disagreeStreak:0,recommendRecalibration:!1}),Yt=(e,t,n)=>{if(!t.gpsYawObservable)return{state:`dormant`,agreeStreak:0,disagreeStreak:0,recommendRecalibration:!1};let r=Math.abs(t.agreementDeltaDeg);if(r<=n.agreeToleranceDeg){let t=e.agreeStreak+1;return{state:t>=n.minAgreeStreak?`trusted`:`untrusted`,agreeStreak:t,disagreeStreak:0,recommendRecalibration:!1}}let i=e.disagreeStreak+1;return{state:e.state===`trusted`&&r>n.dropToleranceDeg?`untrusted`:e.state===`trusted`?`trusted`:`untrusted`,agreeStreak:0,disagreeStreak:i,recommendRecalibration:i>=n.recalibrateAfterStreak}},Xt=e=>e<0?0:e>1?1:e,Zt=e=>+(e===`trusted`),Qt=(e,t,n)=>{let r=Xt(e),i=Xt(t);return Xt(1-r+r*i*n.steadyStateMaxWeight)},$t=180/Math.PI,en=e=>(e%360+360)%360,tn=[0,0,-1],nn=[0,1,0],rn=(e,t)=>{let n=gt(e,t),[r,i]=pt(n,tn),a=Math.hypot(r,i),o=a<.08?null:en(Math.atan2(r,i)*$t),[s,c,l]=pt(n,nn);return{bearingDeg:o,horizontality:a,upDisagreementDeg:Math.atan2(Math.hypot(s,c),l)*$t}},an=(e,t)=>{let n=[],r=0;for(let i of e){let e=rn(i.qSensor,i.qWebxr);Number.isFinite(e.upDisagreementDeg)&&(r+=e.upDisagreementDeg),e.bearingDeg!==null&&e.horizontality>=t.minHorizontality&&n.push(e.bearingDeg)}return{yawSpreadDeg:n.length?Bt(n):NaN,meanUpDisagreementDeg:e.length?r/e.length:NaN,usableCount:n.length,totalCount:e.length}},on=(e,t)=>!(e.totalCount===0||e.usableCount===0||e.usableCount/e.totalCount<t.minUsableFraction||!Number.isFinite(e.yawSpreadDeg)||e.yawSpreadDeg>t.maxYawSpreadDeg||!Number.isFinite(e.meanUpDisagreementDeg)||e.meanUpDisagreementDeg>t.maxUpDisagreementDeg),sn={useOnlyRecentData:!1,recentSeconds:180,includeTimeWeight:!0,weightByTimeFactor:2500,ignoreYAxisForRotation:!0,useRansac:!1,ransacInlierRatio:.95,ransacSampleRatio:.3,ransacMaxIterations:230,ransacErrorTolerance:1,geohashPrecision:8,geohashWindowSize:10,gpsAccuracyExponent:.1,altitudeAlignmentMode:`separate1D`,altitudeAggregator:`mean`,altitudeSampleSet:`all`,gpsVerticalAccuracyExponent:5,useOutlierRejection:!1,outlierThresholdMeters:10,outlierRetainRatio:.6,useDistanceGating:!1,minSampleDistanceMeters:1,maxSampleIntervalMs:3e3,useCompassColdStartOverride:!1,coldStartObservabilityCollapseDeg:12,coldStartObservabilityRampDeg:8,coldStartObservabilityWindow:5,coldStartBaselineMinM:15,coldStartBaselineRampM:10,coldStartSnapAlpha:.5,useCompassRotationPrior:!1,compassSteadyStateMaxWeight:.3,requireCompassWebXRConsistency:!1},cn=e=>e.map(e=>I(e)),ln=e=>e.map(e=>z(e)),un=e=>e.map($n),dn=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),Y=e=>Array.isArray(e)?e:N(e),X=e=>Array.isArray(e)?e:P(e),fn=(e,t,n,r)=>({odometryPosOffset:I(Y(e)),odometryRotOffset:z(X(t)),latestLoopClosureFixPointPos:n?I(Y(n)):null,latestLoopClosureFixPointRot:r?z(X(r)):null}),pn=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...Ce],alignmentRotation:[...L],alignmentTranslation:[...R],alignmentRotationInDegree:[...R],...fn(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null,lastAdmittedOdomPos:null,lastAdmittedTs:null}),mn=()=>pn(R,L,null,null),hn=(e,t,n,r)=>{let i=e.map(e=>Y(e)),a=t.map(e=>z(X(e))),o=n.map($n),s=r.gpsAccuracyExponent;for(let e of o)e.weight=bn(e.latLongAccuracy,s);let c=o.map(Zn),l=r.includeTimeWeight?Kn(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?Wn(o,r.recentSeconds):0,d=i.slice(u).map(j),f=o.slice(u);return{allPositionTuples:i,allRotationTuples:a,allGpsPoints:o,allVec4Tuples:l,solverPositionsTyped:d,solverGpsPoints:f,solverWeightedVec4Tuples:l.slice(u),solverVerticalWeights:Gn(f,r)}},gn=(e,t,n,r,i)=>{if(e==null||t==null)return!0;let a=n[0]-e[0],o=n[2]-e[2],s=i.minSampleDistanceMeters*i.minSampleDistanceMeters;return a*a+o*o>=s||r-t>=i.maxSampleIntervalMs},_n=(e,t,n,r)=>{if(!r.useDistanceGating)return{odometryPositions:e,odometryRotations:t,gpsPoints:n};let i=[],a=[],o=[],s=null,c=null;for(let l=0;l<n.length;l+=1){let u=Y(e[l]),d=n[l].timestamp;gn(s,c,u,d,r)&&(i.push(e[l]),a.push(t[l]),o.push(n[l]),s=u,c=d)}return{odometryPositions:i,odometryRotations:a,gpsPoints:o}},vn=(e,t)=>{let n=e.length-1;return n<0?{lastAdmittedOdomPos:null,lastAdmittedTs:null}:{lastAdmittedOdomPos:I(e[n]),lastAdmittedTs:t[n]?.timestamp??null}},yn=e=>{let{odometryPositions:t,odometryRotations:n,gpsPoints:r,odometryPosOffset:i=R,odometryRotOffset:s=L,latestLoopClosureFixPointPos:c=null,latestLoopClosureFixPointRot:l=null,alignmentConfig:u,random:d}=e;if(t.length!==n.length||t.length!==r.length)throw Error(`GpsEvents requires odometry positions, rotations, and gps points to have identical lengths`);let f={...sn,...u??{}},p=d??Math.random;if(t.length===0)return pn(i,s,c,l);let m=_n(t,n,r,f),{allPositionTuples:h,allRotationTuples:g,allGpsPoints:_,allVec4Tuples:v,solverPositionsTyped:y,solverGpsPoints:b,solverWeightedVec4Tuples:x,solverVerticalWeights:S}=hn(m.odometryPositions,m.odometryRotations,m.gpsPoints,f),C=zn(wn(y,x,S,f,p).matrix,y,x,S,_,g,f,p),w=C.matrix,T=a.create(),E=o.create(),D=o.create();Sn(w,T,E,D);let{mean:ee,median:O}=Yn(_),te=Jn(m.gpsPoints,f.geohashPrecision,f.geohashWindowSize),{lastAdmittedOdomPos:k,lastAdmittedTs:A}=vn(h,m.gpsPoints);return{odometryPositions:cn(h),odometryRotations:ln(g),gpsPositions:un(_),gpsPositionsVec4:dn(v),alignmentMatrix:F(w),alignmentRotation:P(T),alignmentTranslation:N(E),alignmentRotationInDegree:N(D),...fn(i,s,c,l),gpsAccuracyMedian:O,gpsAccuracyMean:ee,currentGpsPosGeoHash:te,lastAdmittedOdomPos:k,lastAdmittedTs:A,...C.fields}},bn=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,xn=(e,t,n,r,i,s)=>{let c={...sn,...i??{}},l=Y(t);if(c.useDistanceGating&&!gn(e.lastAdmittedOdomPos,e.lastAdmittedTs,l,r.timestamp,c))return;let u=e.odometryPositions,d=e.odometryRotations,f=e.gpsPositions,p=e.gpsPositionsVec4;u.push(l),d.push(z(X(n)));let m=$n(r);f.push(m),m.weight=bn(m.latLongAccuracy,c.gpsAccuracyExponent);let h=Zn(m);if(c.includeTimeWeight){p.push(h);let e=Kn(p,f,c.weightByTimeFactor);for(let t=0;t<e.length;t++)p[t]=e[t]}else p.push(h);let g=0;c.useOnlyRecentData&&(g=Wn(f,c.recentSeconds));let _=u.slice(g).map(j),v=p.slice(g),y=Rn(e,wn(_,v,Gn(f.slice(g),c),c,s??Math.random).matrix,_,v,f,d,c);e.alignmentMatrix=F(y);let b=a.create(),x=o.create(),S=o.create();Sn(y,b,x,S),e.alignmentRotation=P(b),e.alignmentTranslation=N(x),e.alignmentRotationInDegree=N(S);let{mean:C,median:w}=Yn(f);e.gpsAccuracyMean=C,e.gpsAccuracyMedian=w,e.currentGpsPosGeoHash=Jn(f,c.geohashPrecision,c.geohashWindowSize),e.lastAdmittedOdomPos=I(l),e.lastAdmittedTs=r.timestamp},Sn=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),Xn(t,r)},Z=o.create(),Cn=o.create(),wn=(e,t,n,r,a)=>{if(e.length===0)return{matrix:i.create(),meanError:0};let o=e.length,c=[];for(let r=0;r<o;r+=1){let i=t[r];c.push({odom:e[r],ref:s.fromValues(i[0],i[1],i[2],i[3]),verticalWeight:n[r]??1})}let l,u,d;if(r.useRansac&&c.length>=3){let e=c.length,t=Math.max(3,Math.min(e,Math.ceil(e*r.ransacSampleRatio))),n=it(c,Math.max(t,Math.min(e,Math.ceil(e*r.ransacInlierRatio))),t,r.ransacMaxIterations,e=>Q(e,r.ignoreYAxisForRotation),(e,t)=>Bn(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else if(r.useOutlierRejection&&c.length>=4){let{model:e,inliers:t}=Un(c,r);l=e.alignmentMatrix,u=e.meanAlignmentError,d=t}else{let e=Q(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&Tn(l,c,d,r),{matrix:l,meanError:u}},Tn=(e,t,n,r)=>{let i=r.altitudeSampleSet===`horizontalInliers`&&n!==void 0&&n.length>0?n:t;if(i.length===0)return;let a=Array(i.length),o=Array(i.length);for(let e=0;e<i.length;e+=1){let t=i[e];a[e]=t.ref[1]-t.odom[1];let n=t.verticalWeight;o[e]=n>0&&Number.isFinite(n)?n:0}e[13]=r.altitudeAggregator===`median`?Dn(a,o):En(a,o)},En=(e,t)=>{let n=0,r=0;for(let i=0;i<e.length;i+=1)n+=e[i]*t[i],r+=t[i];if(r>0&&Number.isFinite(r))return n/r;let i=0;for(let t=0;t<e.length;t+=1)i+=e[t];return e.length===0?0:i/e.length},Dn=(e,t)=>{if(e.length===0)return 0;if(e.length===1)return e[0];let n=e.map((e,t)=>t);n.sort((t,n)=>e[t]-e[n]);let r=0;for(let e=0;e<t.length;e+=1)r+=t[e];if(!(r>0)||!Number.isFinite(r)){let t=n.map(t=>e[t]);return t[Math.floor((t.length-1)/2)]}let i=r/2,a=0;for(let r=0;r<n.length;r+=1)if(a+=t[n[r]],a>=i)return e[n[r]];return e[n[n.length-1]]},On=e=>{let t=0;for(let n=1;n<e.length;n+=1){let r=e[n].coordinates,i=e[n-1].coordinates;t+=Math.hypot(r[0]-i[0],r[2]-i[2])}return t},kn=(e,t)=>{let n=o.create(),r=0;for(let i=0;i<e.length;i+=1){let a=t[i][3];o.scaleAndAdd(n,n,e[i],a),r+=a}return r>0&&o.scale(n,n,1/r),n},An=(e,t)=>{let n=[];for(let r=0;r<e.length;r+=1){let i=e[r].absoluteOrientation,a=t[r];if(!i||!a)continue;let o=_t(i.quaternion,a);if(o===null)continue;let s=((o+It(e[r].latitude,e[r].longitude,{date:e[r].timestamp||void 0}))%360+360)%360;Number.isFinite(s)&&n.push(s)}return n.length===0?null:zt(n)},jn=e=>({collapseThresholdDeg:e.coldStartObservabilityCollapseDeg,rampWidthDeg:e.coldStartObservabilityRampDeg,minWindow:e.coldStartObservabilityWindow,baselineMinM:e.coldStartBaselineMinM,baselineRampM:e.coldStartBaselineRampM}),Mn=(e,t,n,r,i)=>{let a=e.length,o=Math.max(1,a-r.coldStartObservabilityWindow+1),s=[];for(let c=o;c<=a;c+=1){let a=wn(e.slice(0,c),t.slice(0,c),n.slice(0,c),r,i);s.push(J(a.matrix))}return s},Nn={agreeToleranceDeg:8,minAgreeStreak:3,dropToleranceDeg:20,recalibrateAfterStreak:4},Pn={minHorizontality:.5,maxYawSpreadDeg:12,maxUpDisagreementDeg:15,minUsableFraction:.5},Fn=(e,t)=>{let n=[];for(let r=0;r<e.length;r+=1){let i=e[r].absoluteOrientation,a=t[r];i&&a&&n.push({qSensor:i.quaternion,qWebxr:a})}return n.length===0?!1:on(an(n,Pn),Pn)},In=(e,t,n,r,i,a,o,s,c)=>{let l=An(r,i);if(l===null||c.requireCompassWebXRConsistency&&!Fn(r,i))return{matrix:e,appliedBearingDeg:o,trust:s};let u=a.length>0?a[a.length-1]:J(e),d=Ut(a,On(r),jn(c)),f,p=s;c.useCompassRotationPrior?(p=Yt(s??Jt(),{gpsYawObservable:d>=.5,agreementDeltaDeg:U(l,u)},Nn),f=Qt(d,Zt(p.state),{steadyStateMaxWeight:c.compassSteadyStateMaxWeight})):f=Wt(d);let m=Kt(o,Gt(l,u,f),c.coldStartSnapAlpha);return{matrix:be(qt(e,kn(t,n),m)),appliedBearingDeg:m,trust:p}},Ln=e=>e.useCompassColdStartOverride||e.useCompassRotationPrior,Rn=(e,t,n,r,i,a,o)=>{if(!Ln(o))return t;let s=e.coldStartYawWindowDeg?[...e.coldStartYawWindowDeg]:[];for(s.push(J(t));s.length>o.coldStartObservabilityWindow;)s.shift();let c=In(t,n,r,i,a,s,e.coldStartAppliedBearingDeg??null,e.compassTrust,o);return e.coldStartYawWindowDeg=s,e.coldStartAppliedBearingDeg=c.appliedBearingDeg,c.trust!==void 0&&(e.compassTrust=c.trust),c.matrix},zn=(e,t,n,r,i,a,o,s)=>{if(!Ln(o))return{matrix:e,fields:{}};let c=Mn(t,n,r,o,s),l=In(e,t,n,i,a,c,null,void 0,o),u={coldStartYawWindowDeg:c,coldStartAppliedBearingDeg:l.appliedBearingDeg};return l.trust!==void 0&&(u.compassTrust=l.trust),{matrix:l.matrix,fields:u}},Q=(e,t)=>{let n=Array.from(e),r=n.length,i=Array(r),a=Array(r);for(let e=0;e<r;e+=1)i[e]=n[e].odom,a[e]=n[e].ref;let s=tt(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(Z,i[e],s),c+=Vn(Z,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},Bn=(e,t)=>(o.transformMat4(Z,t.odom,e.alignmentMatrix),Vn(Z,t.ref)),Vn=(e,t)=>(o.set(Cn,t[0],t[1],t[2]),o.squaredDistance(e,Cn)),Hn=(e,t)=>{o.transformMat4(Z,t.odom,e.alignmentMatrix);let n=Z[0]-t.ref[0],r=Z[2]-t.ref[2];return n*n+r*r},Un=(e,t)=>{let n=e.length,r=Math.max(3,Math.ceil(t.outlierRetainRatio*n)),i=t.outlierThresholdMeters*t.outlierThresholdMeters,a=Array.from(e),o=Q(a,t.ignoreYAxisForRotation);for(;a.length>r;){let e=-1,n=-1;for(let t=0;t<a.length;t+=1){let r=Hn(o,a[t]);r>n&&(n=r,e=t)}if(n<=i||e<0)break;a=a.filter((t,n)=>n!==e),o=Q(a,t.ignoreYAxisForRotation)}return{model:o,inliers:a}},Wn=(e,t)=>{if(e.length===0||t<=0)return 0;let n=e[e.length-1].timestamp-t*1e3;for(let t=0;t<e.length;t+=1)if(e[t].timestamp>=n)return t;return 0},Gn=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return bn(t!=null&&Number.isFinite(t)&&t>0?t:e.latLongAccuracy,n)});if(!t.includeTimeWeight||e.length<2)return r;let i=e[e.length-1].timestamp,a=e[0].timestamp,o=Math.max(1,i-a),s=t.weightByTimeFactor;return r.map((t,n)=>{if(!(t>0&&Number.isFinite(t)))return 0;let r=s*((i-e[n].timestamp)/o)+1;return 1/(1/t+r)})},Kn=(e,t,n)=>{if(e.length<2)return e.map(e=>[e[0],e[1],e[2],e[3]]);let r=t[t.length-1].timestamp,i=t[0].timestamp,a=Math.max(1,r-i);return e.map((e,i)=>{let o=n*((r-t[i].timestamp)/a)+1,s=t[i].weight;if(!(s>0&&Number.isFinite(s)))return[e[0],e[1],e[2],0];let c=1/(1/s+o);return[e[0],e[1],e[2],c]})},qn=new Map,Jn=(e,t,n)=>{if(e.length===0)return null;let r=Math.max(0,e.length-n);qn.clear();for(let n=r;n<e.length;n+=1){let r=e[n],i=ae(Qn(r),t),a=qn.get(i);a?(a.count+=1,a.index=n):qn.set(i,{count:1,index:n})}let i=null,a=-1,o=-1;for(let[e,{count:t,index:n}]of qn)(t>a||t===a&&n>o)&&(i=e,a=t,o=n);return i},Yn=e=>{let t=e.map(e=>e.latLongAccuracy).filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length===0)return{mean:null,median:null};let n=t.reduce((e,t)=>e+t,0)/t.length,r=t.slice().sort((e,t)=>e-t),i=Math.floor(r.length/2);return{mean:n,median:r.length%2==0?(r[i-1]+r[i])/2:r[i]}},Xn=(e,t)=>{let n=e[0],r=e[1],i=e[2],a=e[3],s=2*(a*n+r*i),c=1-2*(n*n+r*r),l=Math.atan2(s,c),u=2*(a*r-i*n),d;d=Math.abs(u)>=1?Math.PI/2*Math.sign(u):Math.asin(u);let f=2*(a*i+n*r),p=1-2*(r*r+i*i),m=Math.atan2(f,p),h=180/Math.PI,g=t??o.create();return g[0]=l*h,g[1]=d*h,g[2]=m*h,g},Zn=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Qn=e=>({lat:e.latitude,lon:e.longitude}),$n=e=>({...e,zeroRef:{lat:e.zeroRef.lat,lon:e.zeroRef.lon},coordinates:[e.coordinates[0],e.coordinates[1],e.coordinates[2]],timestamp:e.timestamp,deviceRotation:e.deviceRotation?z(X(e.deviceRotation)):void 0,absoluteOrientation:e.absoluteOrientation?{...e.absoluteOrientation,quaternion:[e.absoluteOrientation.quaternion[0],e.absoluteOrientation.quaternion[1],e.absoluteOrientation.quaternion[2],e.absoluteOrientation.quaternion[3]]}:void 0}),er=({lat:e,lon:t})=>{if(!Number.isFinite(e))throw Error(`Invalid latitude value: ${e}`);if(!Number.isFinite(t))throw Error(`Invalid longitude value: ${t}`);if(e<-90||e>90)throw Error(`Invalid latitude range: ${e}`);if(t<-180||t>180)throw Error(`Invalid longitude range: ${t}`)},tr=o.fromValues(1,1,1),nr=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],rr=(e,t,n,r)=>{let i=le(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),a=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?H(Pe(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:N(i),weight:1,deviceRotation:a,absoluteOrientation:r}},ir=(e,t,n)=>{if(e)return Pe(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},ar=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},or=e=>{let t=ar(a.normalize(a.create(),M(e.lastSensorRot))),n=a.normalize(a.create(),M(e.lastValidOdomRot)),r=a.multiply(a.create(),t,n),i=a.normalize(a.create(),M(e.newSensorRot)),o=a.multiply(a.create(),i,r),s=a.normalize(a.create(),M(e.newOdomRot)),c=a.multiply(a.create(),o,s);return a.normalize(c,c),P(c)},sr=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),M(t)),j(e),tr),n},cr=(e,t,n)=>{let r=o.create(),s=o.create(),c=a.create(),l=a.create();i.getTranslation(r,e),i.getTranslation(s,t),i.getRotation(c,e),i.getRotation(l,t);let u=o.create();o.lerp(u,r,s,n);let d=a.create();return a.slerp(d,c,l,n),i.fromRotationTranslation(i.create(),d,u)},lr=(e,t)=>{if(e.length===0)return[];let n=e[e.length-1],r=i.invert(i.create(),n);if(!r)throw Error(`End pose matrix is not invertible`);let a=i.multiply(i.create(),t,r),o=i.create(),s=e.length-1;return e.map((e,t)=>{let n=cr(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},ur=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},dr=e=>{let t={};return e.coldStartOverrideEnabled&&(t.useCompassColdStartOverride=!0),e.compassRotationPriorEnabled&&(t.useCompassRotationPrior=!0),e.compassWebXRConsistencyEnabled&&(t.requireCompassWebXRConsistency=!0),Object.keys(t).length>0?t:void 0},fr=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],pr=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3],mr=t({name:`gpsData`,initialState:null,reducers:{setZeroPos:{reducer:(e,t)=>e===null?{zero:t.payload,gpsEvents:mn(),odometryPath:_e()}:e,prepare:e=>(er(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a,rawAbsoluteOrientation:o}=t.payload,s=rr(i,e.zero,a,o);xn(e.gpsEvents,B(n),V(r),s,dr(e))},setColdStartOverrideEnabled:(e,t)=>{if(!e)return e;e.coldStartOverrideEnabled=t.payload},setCompassRotationPriorEnabled:(e,t)=>{if(!e)return e;e.compassRotationPriorEnabled=t.payload},setCompassWebXRConsistencyEnabled:(e,t)=>{if(!e)return e;e.compassWebXRConsistencyEnabled=t.payload},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=nr(e.gpsEvents.odometryPosOffset,B(t.payload.lastValidOdomPos)),r=ir(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=ir(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(yn({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:or({...t.payload,lastValidOdomRot:V(t.payload.lastValidOdomRot),newOdomRot:V(t.payload.newOdomRot),lastSensorRot:H(r),newSensorRot:H(i)}),latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null,alignmentConfig:dr(e)}))},arLoopClosureDetected:(e,t)=>{if(!e)return e;let n=e.gpsEvents;if(n.odometryPositions.length===0)return e;let r=n.latestLoopClosureFixPointPos?ur(n.odometryPositions,n.latestLoopClosureFixPointPos,fr):0,s=n.latestLoopClosureFixPointRot?ur(n.odometryRotations,n.latestLoopClosureFixPointRot,pr):0;if(r<0||s<0)throw Error(`Loop closure fix point could not be located in history`);if(r!==s)throw Error(`Loop closure fix point indices for position and rotation diverged`);let l=n.odometryPositions.slice(0,r).map(e=>I(e)),u=n.odometryRotations.slice(0,r).map(e=>z(e)),d=n.odometryPositions.slice(r).map(e=>I(e)),f=n.odometryRotations.slice(r).map(e=>z(e)),p=d.map((e,t)=>sr(e,f[t])),m=sr(B(t.payload.lastPos),z(V(t.payload.lastRot)));p.push(m);let h=lr(p,sr(B(t.payload.newPos),z(V(t.payload.newRot)))),g=[],_=[],v=o.create();for(let e=0;e<h.length-1;e+=1){let t=h[e],n=o.create();i.getTranslation(n,t);let r=a.create();if(i.getRotation(r,t),a.normalize(r,r),i.getScaling(v,t),Math.hypot(v[0]-1,v[1]-1,v[2]-1)>.05)throw Error(`Unexpected scale drift encountered during loop closure correction`);g.push(N(n)),_.push(P(r))}e.gpsEvents=c(yn({odometryPositions:l.concat(g),odometryRotations:u.concat(_),gpsPoints:n.gpsPositions,odometryPosOffset:n.odometryPosOffset,odometryRotOffset:n.odometryRotOffset,latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null,alignmentConfig:dr(e)}))},add2dImage:(e,t)=>{if(!e)return e;e.odometryPath.points.push(c({imageFile:t.payload.imageFile,screenRotation:t.payload.screenRotation,position:B(t.payload.position),rotation:z(V(t.payload.rotation)),capturedAt:t.payload.capturedAt,width:t.payload.width,height:t.payload.height}))}}}),{setZeroPos:hr,recordGpsEvent:gr,odometryTrackingRestarted:_r,arLoopClosureDetected:vr,add2dImage:yr,setColdStartOverrideEnabled:br,setCompassRotationPriorEnabled:xr,setCompassWebXRConsistencyEnabled:Sr}=mr.actions,Cr=p(hr),wr=p(gr),Tr=p(_r),Er=p(vr),Dr=p(yr),Or=p(br),kr=p(xr),Ar=p(Sr),jr=m(mr.reducer),Mr=t({name:`gpsElements`,initialState:ve(),reducers:{addMarker:(e,t)=>{e.gpsMarkers.push(t.payload)},addLine:(e,t)=>{e.gpsLines.push(t.payload)},addArea:(e,t)=>{e.areas.push(t.payload)},addToHeatMaps:(e,t)=>{let{category:n,tiles:r}=t.payload,i=e.heatMap[n]??{};e.heatMap[n]={...i,...r}},addHeatMapArea:(e,t)=>{let n=t.payload,r=n.category;if(e.heatAreas[r]||(e.heatAreas[r]={}),e.heatAreas[r][n.geoHash])throw Error(`HeatArea collision detected for GeoHash: ${n.geoHash}`);e.heatAreas[r][n.geoHash]=n},resetGpsElements:()=>ve()}}),{addMarker:Nr,addLine:Pr,addArea:Fr,addToHeatMaps:Ir,addHeatMapArea:Lr,resetGpsElements:Rr}=Mr.actions,zr=p(Nr),Br=p(Pr),Vr=p(Fr),Hr=p(Ir),Ur=p(Lr),Wr=p(Rr),Gr=m(Mr.reducer),Kr=()=>({gpsData:null,gpsElements:ve(),arElements:ye()}),qr=e=>{let t=Array.from({length:Math.min(e.length,4)},(t,n)=>e[n].toFixed(2));e.length>4&&t.push(`…`);let n=`[${t.join(`, `)}]`;if(e.length===4){let{pitch:t,yaw:r,roll:i}=v(e);return`${n} (pitch=${t.toFixed(0)}°, yaw=${r.toFixed(0)}°, roll=${i.toFixed(0)}°)`}return n},Jr=e=>(e.length===3||e.length===4||e.length===16)&&e.every(e=>typeof e==`number`),$=(e,t=0)=>{if(t>10||e==null)return e;if(Array.isArray(e))return Jr(e)?qr(e):e.map(e=>$(e,t+1));if(typeof e==`object`){let n={};for(let[r,i]of Object.entries(e))n[r]=$(i,t+1);return n}return e},Yr=(t={})=>{let{preloadedState:n,enableDevToolsSanitizers:r=!0,enableDevChecks:i=!0,licenseKey:a}=t;if(a==null)throw Error(`License key required. Pass options.licenseKey or use createRecorderStore() from gps-plus-slam-app-framework. See EULA §3.`);g(a);let o=Kr(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:jr,gpsElements:Gr,arElements:Qe},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:$,stateSanitizer:$}:!0})},Xr=[],Zr=[],Qr=[],$r={median:null,mean:null},ei=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),ti=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),ni=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??Xr}),ri=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??Zr}),ii=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??Qr}),ai=f(function(e){return e.gpsData?.zero??null}),oi=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?$r:{median:t,mean:n}}),si=`1.0.0`;export{Ce as IDENTITY_MATRIX4,L as IDENTITY_QUATERNION,si as LIB_VERSION,bt as WMM2025_EPOCH,xt as WMM2025_VALID_FROM,St as WMM2025_VALID_TO,R as ZERO_VECTOR3,Dr as add2dImage,Vr as addArea,qe as addCornerToEventArea,Ur as addHeatMapArea,Br as addLine,zr as addMarker,Ge as addOrUpdateArPlane,Hr as addToHeatMaps,Xe as anchorEventAreaInWorldSpace,Qe as arElementsReducer,Er as arLoopClosureDetected,_t as arNorthBearingDeg,gt as arToEnuRotation,U as bearingDeltaDeg,ae as calcGeoHash,ue as calcGpsCoords,re as calcQuadKey,le as calcRelativeCoordsInMeters,Se as cloneMatrix4,xe as cloneQuaternion,I as cloneVector3,Je as correctArDriftForEventArea,Yr as createGpsSlamStore,se as distanceInMeters,ce as distanceInMetersRelative,H as enuQuaternionToNUE,Pe as eulerToQuaternion,Ye as finishEventArea,be as fromMatrix4,M as fromQuaternion,j as fromVector3,ge as fusedGpsFromOdom,oe as geoHashToLatLong,ei as getAlignmentMatrix,ti as getAlignmentRotation,me as getGoogleMapsDirectionsLink,pe as getGoogleMapsLink,oi as getGpsAccuracyStats,ii as getGpsPositions,ni as getOdometryPositions,ri as getOdometryRotations,he as getOpenStreetMapLink,ai as getZeroReference,jr as gpsDataReducer,Gr as gpsElementsReducer,Ae as invertQuaternion,we as isIdentityMatrix4,Ee as isIdentityQuaternion,De as isNearIdentityQuaternion,It as magneticDeclinationDeg,mt as magneticHeadingFromEnuQuat,Lt as magneticToTrueHeadingDeg,ke as multiplyQuaternions,z as normalizeQuaternion,Ne as nueQuaternionToENU,Me as nueQuaternionToWebXR,je as nueToWebXR,Tr as odometryTrackingRestarted,ie as quadKeyToLatLong,Te as quaternionMagnitude,Oe as quaternionsEquivalent,wr as recordGpsEvent,We as recordPhoneHeight,Ze as resetArElements,Wr as resetGpsElements,$ as sanitizeForDevTools,Or as setColdStartOverrideEnabled,kr as setCompassRotationPriorEnabled,Ar as setCompassWebXRConsistencyEnabled,Cr as setZeroPos,Ke as startEventArea,de as toEarthCenteredCoordinates,F as toMatrix4,P as toQuaternion,N as toVector3,g as validateLicenseKey,V as webxrQuaternionToNUE,B as webxrToNUE};
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
* @see docs/2026-04-25-private-key-security-plan.md — secret-backed renewal
|
|
36
36
|
* @see ../../GpsPlusSlamJs_Docs/docs/2026-05-01-community-key-resign-cross-repo-issue.md
|
|
37
37
|
*/
|
|
38
|
-
declare const COMMUNITY_LICENSE_KEY = "
|
|
38
|
+
declare const COMMUNITY_LICENSE_KEY = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODE0MDkzMzgzfQ.L6Eyp5iiP7pbZ2dbwMwInNWxg_1YxP6T9CzGBlm0hxVbUWJ7I0xWHQcJl_T5Ee88MMp41YkoPBHRdUPtw3q8DQ";
|
|
39
39
|
//#endregion
|
|
40
40
|
export { COMMUNITY_LICENSE_KEY };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! gps-plus-slam-js | (c) 2026 cs-util-com | UNLICENSED — see EULA.md */
|
|
2
|
-
const e=`
|
|
2
|
+
const e=`eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODE0MDkzMzgzfQ.L6Eyp5iiP7pbZ2dbwMwInNWxg_1YxP6T9CzGBlm0hxVbUWJ7I0xWHQcJl_T5Ee88MMp41YkoPBHRdUPtw3q8DQ`;export{e as COMMUNITY_LICENSE_KEY};
|