gps-plus-slam-js 1.0.6 → 1.0.7
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/README.md +16 -0
- package/dist/index.d.ts +1 -37
- package/dist/index.js +1 -1
- package/dist/licensing/community-license-key.d.ts +1 -1
- package/dist/licensing/community-license-key.js +1 -1
- package/package.json +17 -17
package/README.md
CHANGED
|
@@ -150,10 +150,26 @@ Source: [github.com/cs-util-com/location-based-webxr](https://github.com/cs-util
|
|
|
150
150
|
To prepare a new release version for npm, use the automated release preparation script from the repository root. It bumps the core package, updates the dependency range in the companion `GpsPlusSlamJs_AppFramework`, and prints a step-by-step checklist for the two PRs that follow.
|
|
151
151
|
|
|
152
152
|
1. Run the preparation script for the desired bump (`patch`, `minor`, or `major`):
|
|
153
|
+
|
|
153
154
|
```bash
|
|
155
|
+
# Core-only release (gps-plus-slam-js):
|
|
154
156
|
pnpm run prep_new_releases --core patch
|
|
157
|
+
|
|
158
|
+
# Framework-only release (gps-plus-slam-app-framework):
|
|
159
|
+
pnpm run prep_new_releases --framework patch
|
|
160
|
+
|
|
161
|
+
# Coordinated release — bump BOTH packages together. The two
|
|
162
|
+
# versions are independent SoTs; if you want them to move in
|
|
163
|
+
# lockstep you must pass both flags explicitly. A core-only
|
|
164
|
+
# bump leaves the framework's package.json#version unchanged,
|
|
165
|
+
# which will fail the publish workflow's tag-vs-version check
|
|
166
|
+
# (e.g. "Release tag app-framework@1.0.6 does not match
|
|
167
|
+
# package.json version app-framework@1.0.4").
|
|
168
|
+
pnpm run prep_new_releases --core patch --framework patch
|
|
155
169
|
```
|
|
170
|
+
|
|
156
171
|
The public-repo `pnpm install` step is **expected** to fail with `ERR_PNPM_NO_MATCHING_VERSION` because the new version is not on npm yet — the script treats this as accepted-red and continues.
|
|
172
|
+
|
|
157
173
|
2. **Private repo (`gps-plus-slam`):** follow the script's checklist to commit the core bump, open a PR, merge it, and draft a GitHub Release with the new `vX.Y.Z` tag. The release workflow re-signs the community license key and publishes `gps-plus-slam-js` to npm.
|
|
158
174
|
3. **Wait** until the new version is resolvable on npm.
|
|
159
175
|
4. **Public repo (`location-based-webxr`):** follow the script's checklist to push the AppFramework dep-range bump, run `pnpm install` to refresh the lockfile, open a PR, and merge it.
|
package/dist/index.d.ts
CHANGED
|
@@ -258,37 +258,6 @@ interface ArImageCapture {
|
|
|
258
258
|
/** Epoch milliseconds (Date.now() / new Date().getTime()) */
|
|
259
259
|
capturedAt?: number;
|
|
260
260
|
}
|
|
261
|
-
/**
|
|
262
|
-
* A user-defined reference point for ground truth validation.
|
|
263
|
-
* Reference points are physical landmarks that can be revisited across sessions
|
|
264
|
-
* to verify alignment accuracy.
|
|
265
|
-
*/
|
|
266
|
-
interface ReferencePoint {
|
|
267
|
-
/** Unique identifier for this reference point (e.g., "benchCorner", "pointA") */
|
|
268
|
-
id: string;
|
|
269
|
-
/** AR pose when the reference point was marked */
|
|
270
|
-
position: Vector3;
|
|
271
|
-
rotation: Quaternion;
|
|
272
|
-
/** GPS data at the moment of marking */
|
|
273
|
-
gpsPoint: GpsPoint;
|
|
274
|
-
/** Epoch milliseconds (Date.now() / new Date().getTime()) */
|
|
275
|
-
timestamp: number;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Payload for the markReferencePoint action.
|
|
279
|
-
*/
|
|
280
|
-
interface MarkReferencePointPayload {
|
|
281
|
-
/** Unique identifier for this reference point */
|
|
282
|
-
id: string;
|
|
283
|
-
/** AR pose position when marking */
|
|
284
|
-
position: Vector3;
|
|
285
|
-
/** AR pose rotation when marking */
|
|
286
|
-
rotation: Quaternion;
|
|
287
|
-
/** Raw GPS point data at the moment of marking */
|
|
288
|
-
rawGpsPoint: RawGpsPoint;
|
|
289
|
-
/** Optional timestamp (defaults to Date.now() if not provided) */
|
|
290
|
-
timestamp?: number;
|
|
291
|
-
}
|
|
292
261
|
interface OdometryPath {
|
|
293
262
|
points: ArImageCapture[];
|
|
294
263
|
}
|
|
@@ -334,8 +303,6 @@ interface GpsModel {
|
|
|
334
303
|
zero: LatLong;
|
|
335
304
|
gpsEvents: GpsEventsType;
|
|
336
305
|
odometryPath: OdometryPath;
|
|
337
|
-
/** User-defined reference points for ground truth validation */
|
|
338
|
-
referencePoints: ReferencePoint[];
|
|
339
306
|
}
|
|
340
307
|
interface GpsSlamState {
|
|
341
308
|
gpsData: GpsModel | null;
|
|
@@ -453,7 +420,6 @@ declare const recordGpsEvent: _$_reduxjs_toolkit0.ActionCreatorWithPayload<Recor
|
|
|
453
420
|
declare const odometryTrackingRestarted: _$_reduxjs_toolkit0.ActionCreatorWithPayload<OdometryTrackingRestartedPayload, "gpsData/odometryTrackingRestarted">;
|
|
454
421
|
declare const arLoopClosureDetected: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArLoopClosureDetectedPayload, "gpsData/arLoopClosureDetected">;
|
|
455
422
|
declare const add2dImage: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArImageCapture, "gpsData/add2dImage">;
|
|
456
|
-
declare const markReferencePoint: _$_reduxjs_toolkit0.ActionCreatorWithPayload<MarkReferencePointPayload, "gpsData/markReferencePoint">;
|
|
457
423
|
declare const gpsDataReducer: (state: GpsModel | null | undefined, action: _$redux.UnknownAction) => GpsModel | null;
|
|
458
424
|
//#endregion
|
|
459
425
|
//#region ../src/state/gpsElementsSlice.d.ts
|
|
@@ -531,8 +497,6 @@ declare const getOdometryPositions: (state: GpsSlamState) => readonly Vector3[];
|
|
|
531
497
|
declare const getOdometryRotations: (state: GpsSlamState) => readonly Quaternion[];
|
|
532
498
|
/** Returns the recorded GPS positions with metadata. */
|
|
533
499
|
declare const getGpsPositions: (state: GpsSlamState) => readonly GpsPoint[];
|
|
534
|
-
/** Returns the user-defined reference points. */
|
|
535
|
-
declare const getReferencePoints: (state: GpsSlamState) => readonly ReferencePoint[];
|
|
536
500
|
/** Returns the GPS zero reference (origin for coordinate conversion), or null. */
|
|
537
501
|
declare const getZeroReference: (state: GpsSlamState) => LatLong | null;
|
|
538
502
|
/** Returns median and mean GPS accuracy statistics, or null values if unavailable. */
|
|
@@ -561,4 +525,4 @@ declare function validateLicenseKey(key: string): LicenseValidationResult;
|
|
|
561
525
|
//#region ../src/index.d.ts
|
|
562
526
|
declare const LIB_VERSION = "1.0.0";
|
|
563
527
|
//#endregion
|
|
564
|
-
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
|
|
528
|
+
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 RawDeviceOrientation, type RawGpsPoint, type RecordGpsEventPayload, type RootState, type Vector3, type Vector4, ZERO_VECTOR3, add2dImage, addArea, addCornerToEventArea, addHeatMapArea, addLine, addMarker, addOrUpdateArPlane, addToHeatMaps, anchorEventAreaInWorldSpace, arElementsReducer, arLoopClosureDetected, 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, multiplyQuaternions, normalizeQuaternion, nueQuaternionToENU, nueQuaternionToWebXR, nueToWebXR, odometryTrackingRestarted, quadKeyToLatLong, quaternionMagnitude, quaternionsEquivalent, recordGpsEvent, recordPhoneHeight, resetArElements, resetGpsElements, sanitizeForDevTools, 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),ee=e=>D(e,-180,180),O=e=>e*C,te=e=>e*w,ne=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},re=e=>({lat:ne(e.lat),lon:ne(e.lon)}),ie=(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)},ae=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}),oe=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}}),se=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}),ce=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}}),le=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)))}),ue=f((e,t)=>{let n=de(e,t);return Math.hypot(n[0],n[2])}),de=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)}),fe=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}}),pe=f((e,t=0)=>ie(e,t)),me=e=>{let{lat:t,lon:n}=re(e);return`${t}%2C${n}`},he=f(e=>`https://www.google.com/maps/search/?api=1&query=${me(e)}`),ge=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${me(t)}&destination=${me(e)}`),_e=f((e,t=19)=>{let{lat:n,lon:r}=re(e);return`https://www.openstreetmap.org/query?lat=${n}&lon=${r}#map=${t}/${n}/${r}`}),ve=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}=fe(n,s);return{lat:c,lon:l,altitude:s[1]}}),ye=()=>({points:[]}),k=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),A=()=>({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]),z=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),B=e=>{let t=we(e);if(t===0)return L;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},Ce=e=>{for(let t=0;t<16;t++)if(e[t]!==z[t])return!1;return!0},we=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),Te=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,Ee=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,De=(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},Oe=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},ke=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},V=e=>[-e[2],e[1],e[0]],Ae=e=>[e[2],e[1],-e[0]],H=e=>[-e[2],e[1],e[0],e[3]],je=e=>[e[2],e[1],-e[0],e[3]],U=e=>[e[1],e[2],e[0],e[3]],Me=e=>[e[2],e[0],e[1],e[3]],W=(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]]},Ne=t({name:`arElements`,initialState:A(),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 fe(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>A()}}),{recordPhoneHeight:Pe,addOrUpdateArPlane:Fe,startEventArea:Ie,addCornerToEventArea:Le,correctArDriftForEventArea:Re,finishEventArea:ze,anchorEventAreaInWorldSpace:Be,resetArElements:Ve}=Ne.actions,He=p(Pe),Ue=p(Fe),We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=p(Be),Ye=p(Ve),Xe=m(Ne.reducer);function Ze(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),G(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),G(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function Qe(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 $e(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}=Ze(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new et(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return Qe(i.create(),d,f,m,p,c,h)}var et=class e{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]),G(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 G=(e,t)=>(e[0]=t[0],e[1]=t[1],e[2]=t[2],e);function tt(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 it(s,nt(s,t,n,r,i,a,o),i,a)}function nt(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}=rt(e,l,i(c),a);if(s===null||n+r.length>=t){let e=[...c,...r],t=i(e),n=K(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 rt(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 it(e,t,n,r){let i=t??n(e);K(i,`RANSAC failed to produce a model with totalModelError`);let{inliers:a,outliers:o}=rt(e,null,i,r);return a.length>0&&(i=n(a),K(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function K(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:800,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},st=e=>e.map(e=>I(e)),ct=e=>e.map(e=>B(e)),lt=e=>e.map(Q),ut=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),q=e=>Array.isArray(e)?e:N(e),J=e=>Array.isArray(e)?e:P(e),dt=(e,t,n,r)=>({odometryPosOffset:I(q(e)),odometryRotOffset:B(J(t)),latestLoopClosureFixPointPos:n?I(q(n)):null,latestLoopClosureFixPointRot:r?B(J(r)):null}),ft=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...z],alignmentRotation:[...L],alignmentTranslation:[...R],alignmentRotationInDegree:[...R],...dt(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null}),pt=()=>ft(R,L,null,null),mt=(e,t,n,r)=>{let i=e.map(e=>q(e)),a=t.map(e=>B(J(e))),o=n.map(Q),s=r.gpsAccuracyExponent;for(let e of o)e.weight=Y(e.latLongAccuracy,s);let c=o.map(Mt),l=r.includeTimeWeight?Ot(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?Et(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:Dt(f,r)}},ht=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={...ot,...u??{}};if(t.length===0)return ft(i,s,c,l);let{allPositionTuples:p,allRotationTuples:m,allGpsPoints:h,allVec4Tuples:g,solverPositionsTyped:_,solverGpsPoints:v,solverWeightedVec4Tuples:y,solverVerticalWeights:b}=mt(t,n,r,f),x=yt(_,y,b,f,d??Math.random),S=a.create(),C=o.create(),w=o.create();_t(x.matrix,S,C,w);let{mean:T,median:E}=At(h),D=kt(r,f.geohashPrecision,f.geohashWindowSize);return{odometryPositions:st(p),odometryRotations:ct(m),gpsPositions:lt(h),gpsPositionsVec4:ut(g),alignmentMatrix:F(x.matrix),alignmentRotation:P(S),alignmentTranslation:N(C),alignmentRotationInDegree:N(w),...dt(i,s,c,l),gpsAccuracyMedian:E,gpsAccuracyMean:T,currentGpsPosGeoHash:D}},Y=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,gt=(e,t,n,r,i,s)=>{let c=e.odometryPositions,l=e.odometryRotations,u=e.gpsPositions,d=e.gpsPositionsVec4;c.push(q(t)),l.push(B(J(n)));let f=Q(r);u.push(f);let p={...ot,...i??{}};f.weight=Y(f.latLongAccuracy,p.gpsAccuracyExponent);let m=Mt(f);if(p.includeTimeWeight){d.push(m);let e=Ot(d,u,p.weightByTimeFactor);for(let t=0;t<e.length;t++)d[t]=e[t]}else d.push(m);let h=0;p.useOnlyRecentData&&(h=Et(u,p.recentSeconds));let g=yt(c.slice(h).map(j),d.slice(h),Dt(u.slice(h),p),p,s??Math.random);e.alignmentMatrix=F(g.matrix);let _=a.create(),v=o.create(),y=o.create();_t(g.matrix,_,v,y),e.alignmentRotation=P(_),e.alignmentTranslation=N(v),e.alignmentRotationInDegree=N(y);let{mean:b,median:x}=At(u);e.gpsAccuracyMean=b,e.gpsAccuracyMedian=x,e.currentGpsPosGeoHash=kt(u,p.geohashPrecision,p.geohashWindowSize)},_t=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),jt(t,r)},X=o.create(),vt=o.create(),yt=(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=tt(c,Math.max(t,Math.min(e,Math.ceil(e*r.ransacInlierRatio))),t,r.ransacMaxIterations,e=>Ct(e,r.ignoreYAxisForRotation),(e,t)=>wt(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else{let e=Ct(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&bt(l,c,d,r),{matrix:l,meanError:u}},bt=(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`?St(a,o):xt(a,o)},xt=(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},St=(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]]},Ct=(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=$e(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(X,i[e],s),c+=Tt(X,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},wt=(e,t)=>(o.transformMat4(X,t.odom,e.alignmentMatrix),Tt(X,t.ref)),Tt=(e,t)=>(o.set(vt,t[0],t[1],t[2]),o.squaredDistance(e,vt)),Et=(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},Dt=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return Y(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)})},Ot=(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,kt=(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=se(Nt(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},At=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]}},jt=(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},Mt=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Nt=e=>({lat:e.latitude,lon:e.longitude}),Q=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?B(J(e.deviceRotation)):void 0}),Pt=({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}`)},Ft=o.fromValues(1,1,1),It=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],Lt=(e,t,n)=>{let r=de(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),i=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?U(W(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:N(r),weight:1,deviceRotation:i}},Rt=(e,t,n)=>{if(e)return W(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},zt=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},Bt=e=>{let t=zt(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)},Vt=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),M(t)),j(e),Ft),n},Ht=(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)},Ut=(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=Ht(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},Wt=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},Gt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],Kt=(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:ye(),referencePoints:[]}:e,prepare:e=>(Pt(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a}=t.payload,o=Lt(i,e.zero,a);gt(e.gpsEvents,V(n),H(r),o)},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=It(e.gpsEvents.odometryPosOffset,V(t.payload.lastValidOdomPos)),r=Rt(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=Rt(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(ht({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:Bt({...t.payload,lastValidOdomRot:H(t.payload.lastValidOdomRot),newOdomRot:H(t.payload.newOdomRot),lastSensorRot:U(r),newSensorRot:U(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?Wt(n.odometryPositions,n.latestLoopClosureFixPointPos,Gt):0,s=n.latestLoopClosureFixPointRot?Wt(n.odometryRotations,n.latestLoopClosureFixPointRot,Kt):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=>B(e)),d=n.odometryPositions.slice(r).map(e=>I(e)),f=n.odometryRotations.slice(r).map(e=>B(e)),p=d.map((e,t)=>Vt(e,f[t])),m=Vt(V(t.payload.lastPos),B(H(t.payload.lastRot)));p.push(m);let h=Ut(p,Vt(V(t.payload.newPos),B(H(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(ht({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:V(t.payload.position),rotation:B(H(t.payload.rotation)),capturedAt:t.payload.capturedAt}))},markReferencePoint:(e,t)=>{if(!e)return e;let{id:n,position:r,rotation:i,rawGpsPoint:a,timestamp:o}=t.payload,s=Lt(a,e.zero);e.referencePoints.push(c({id:n,position:V(r),rotation:B(H(i)),gpsPoint:Q(s),timestamp:o??Date.now()}))}}}),{setZeroPos:Jt,recordGpsEvent:Yt,odometryTrackingRestarted:Xt,arLoopClosureDetected:Zt,add2dImage:Qt,markReferencePoint:$t}=qt.actions,en=p(Jt),tn=p(Yt),nn=p(Xt),rn=p(Zt),an=p(Qt),on=p($t),sn=m(qt.reducer),cn=t({name:`gpsElements`,initialState:k(),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:()=>k()}}),{addMarker:ln,addLine:un,addArea:dn,addToHeatMaps:fn,addHeatMapArea:pn,resetGpsElements:mn}=cn.actions,hn=p(ln),gn=p(un),_n=p(dn),vn=p(fn),yn=p(pn),bn=p(mn),xn=m(cn.reducer),Sn=()=>({gpsData:null,gpsElements:k(),arElements:A()}),Cn=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},wn=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 wn(e)?Cn(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},Tn=(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=Sn(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:sn,gpsElements:xn,arElements:Xe},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:$,stateSanitizer:$}:!0})},En=[],Dn=[],On=[],kn=[],An={median:null,mean:null},jn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),Mn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),Nn=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??En}),Pn=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??Dn}),Fn=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??On}),In=f(function(e){return e.gpsData?.referencePoints??kn}),Ln=f(function(e){return e.gpsData?.zero??null}),Rn=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?An:{median:t,mean:n}}),zn=`1.0.0`;export{z as IDENTITY_MATRIX4,L as IDENTITY_QUATERNION,zn as LIB_VERSION,R as ZERO_VECTOR3,an as add2dImage,_n as addArea,Ge as addCornerToEventArea,yn as addHeatMapArea,gn as addLine,hn as addMarker,Ue as addOrUpdateArPlane,vn as addToHeatMaps,Je as anchorEventAreaInWorldSpace,Xe as arElementsReducer,rn as arLoopClosureDetected,se as calcGeoHash,fe as calcGpsCoords,ae as calcQuadKey,de as calcRelativeCoordsInMeters,Se as cloneMatrix4,xe as cloneQuaternion,I as cloneVector3,Ke as correctArDriftForEventArea,Tn as createGpsSlamStore,le as distanceInMeters,ue as distanceInMetersRelative,U as enuQuaternionToNUE,W as eulerToQuaternion,qe as finishEventArea,be as fromMatrix4,M as fromQuaternion,j as fromVector3,ve as fusedGpsFromOdom,ce as geoHashToLatLong,jn as getAlignmentMatrix,Mn as getAlignmentRotation,ge as getGoogleMapsDirectionsLink,he as getGoogleMapsLink,Rn as getGpsAccuracyStats,Fn as getGpsPositions,Nn as getOdometryPositions,Pn as getOdometryRotations,_e as getOpenStreetMapLink,In as getReferencePoints,Ln as getZeroReference,sn as gpsDataReducer,xn as gpsElementsReducer,ke as invertQuaternion,Ce as isIdentityMatrix4,Te as isIdentityQuaternion,Ee as isNearIdentityQuaternion,on as markReferencePoint,Oe as multiplyQuaternions,B as normalizeQuaternion,Me as nueQuaternionToENU,je as nueQuaternionToWebXR,Ae as nueToWebXR,nn as odometryTrackingRestarted,oe as quadKeyToLatLong,we as quaternionMagnitude,De as quaternionsEquivalent,tn as recordGpsEvent,He as recordPhoneHeight,Ye as resetArElements,bn as resetGpsElements,$ as sanitizeForDevTools,en as setZeroPos,We as startEventArea,pe as toEarthCenteredCoordinates,F as toMatrix4,P as toQuaternion,N as toVector3,g as validateLicenseKey,H as webxrQuaternionToNUE,V 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,ee=Math.PI/180,C=180/Math.PI,w=`0123456789bcdefghjkmnpqrstuvwxyz`,T=[16,8,4,2,1],E=(e,t,n)=>Math.min(Math.max(e,t),n),te=e=>E(e,-180,180),D=e=>e*ee,ne=e=>e*C,re=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},ie=e=>({lat:re(e.lat),lon:re(e.lon)}),ae=(e,t=0)=>{let n=D(e.lat),r=D(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)},oe=f((e,t)=>{if(t<1||t>23)throw RangeError(`levelOfDetail must be between 1 and 23 (inclusive)`);let n=E(e.lat,-85.05112878,85.05112878),r=te(e.lon),i=Math.sin(D(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=E(Math.floor(o/256),0,c),u=E(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}),se=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:ne(Math.atan(Math.sinh(Math.PI*(1-2*c)))),lon:l}}),ce=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|=T[s],i=t):a=t}else{let t=(n+r)/2;e.lat>=t?(c|=T[s],n=t):r=t}l=!l,s<4?s+=1:(o+=w[c],s=0,c=0)}return o}),le=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=w.indexOf(o);if(e===-1)throw Error(`Invalid geohash character: ${o}`);for(let o of T){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}}),ue=f((e,t)=>{let n=D(e.lat),r=D(t.lat),i=r-n,a=D(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)))}),de=f((e,t)=>{let n=O(e,t);return Math.hypot(n[0],n[2])}),O=f((e,t,n=0,r=0)=>{let i=(t.lon-e.lon)*x*Math.cos(D(e.lat)),a=(t.lat-e.lat)*S,s=n-r;return o.fromValues(a,s,i)}),k=f((e,t)=>{let n=t[0],r=t[2];return{lat:n/S+e.lat,lon:r/(x*Math.cos(D(e.lat)))+e.lon}}),fe=f((e,t=0)=>ae(e,t)),A=e=>{let{lat:t,lon:n}=ie(e);return`${t}%2C${n}`},pe=f(e=>`https://www.google.com/maps/search/?api=1&query=${A(e)}`),me=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${A(t)}&destination=${A(e)}`),he=f((e,t=19)=>{let{lat:n,lon:r}=ie(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}=k(n,s);return{lat:c,lon:l,altitude:s[1]}}),_e=()=>({points:[]}),ve=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),j=()=>({arPlanes:{},floorDetections:[],eventAreas:[],currentEventAreaId:null,currentEventAreaPoints:[]}),M=e=>o.fromValues(e[0],e[1],e[2]),N=e=>a.fromValues(e[0],e[1],e[2],e[3]),ye=e=>i.fromValues(...e),P=e=>[e[0],e[1],e[2]],F=e=>[e[0],e[1],e[2],e[3]],I=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]],L=e=>[e[0],e[1],e[2]],be=e=>[e[0],e[1],e[2],e[3]],xe=e=>[...e],R=Object.freeze([0,0,0,1]),z=Object.freeze([0,0,0]),B=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),V=e=>{let t=Ce(e);if(t===0)return R;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},Se=e=>{for(let t=0;t<16;t++)if(e[t]!==B[t])return!1;return!0},Ce=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),we=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,Te=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,Ee=(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},De=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},Oe=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},H=e=>[-e[2],e[1],e[0]],ke=e=>[e[2],e[1],-e[0]],U=e=>[-e[2],e[1],e[0],e[3]],Ae=e=>[e[2],e[1],-e[0],e[3]],W=e=>[e[1],e[2],e[0],e[3]],je=e=>[e[2],e[0],e[1],e[3]],G=(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]]},Me=t({name:`arElements`,initialState:j(),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(L(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=ye(r),l=s.arPoints.map(e=>{let t=M(e);return k(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>j()}}),{recordPhoneHeight:Ne,addOrUpdateArPlane:Pe,startEventArea:Fe,addCornerToEventArea:Ie,correctArDriftForEventArea:Le,finishEventArea:Re,anchorEventAreaInWorldSpace:ze,resetArElements:Be}=Me.actions,Ve=p(Ne),He=p(Pe),Ue=p(Fe),We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=p(Be),Ye=m(Me.reducer);function Xe(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),K(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),K(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function Ze(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 Qe(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}=Xe(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new $e(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return Ze(i.create(),d,f,m,p,c,h)}var $e=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]),K(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 K=(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){it(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=q(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);q(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),q(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function q(e,t){let{totalModelError:n}=e;if(n==null)throw Error(t);return n}function it(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 at={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},ot=e=>e.map(e=>L(e)),st=e=>e.map(e=>V(e)),ct=e=>e.map(Nt),lt=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),J=e=>Array.isArray(e)?e:P(e),Y=e=>Array.isArray(e)?e:F(e),ut=(e,t,n,r)=>({odometryPosOffset:L(J(e)),odometryRotOffset:V(Y(t)),latestLoopClosureFixPointPos:n?L(J(n)):null,latestLoopClosureFixPointRot:r?V(Y(r)):null}),dt=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...B],alignmentRotation:[...R],alignmentTranslation:[...z],alignmentRotationInDegree:[...z],...ut(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null}),ft=()=>dt(z,R,null,null),pt=(e,t,n,r)=>{let i=e.map(e=>J(e)),a=t.map(e=>V(Y(e))),o=n.map(Nt),s=r.gpsAccuracyExponent;for(let e of o)e.weight=X(e.latLongAccuracy,s);let c=o.map(jt),l=r.includeTimeWeight?Dt(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?Tt(o,r.recentSeconds):0,d=i.slice(u).map(M),f=o.slice(u);return{allPositionTuples:i,allRotationTuples:a,allGpsPoints:o,allVec4Tuples:l,solverPositionsTyped:d,solverGpsPoints:f,solverWeightedVec4Tuples:l.slice(u),solverVerticalWeights:Et(f,r)}},mt=e=>{let{odometryPositions:t,odometryRotations:n,gpsPoints:r,odometryPosOffset:i=z,odometryRotOffset:s=R,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={...at,...u??{}};if(t.length===0)return dt(i,s,c,l);let{allPositionTuples:p,allRotationTuples:m,allGpsPoints:h,allVec4Tuples:g,solverPositionsTyped:_,solverGpsPoints:v,solverWeightedVec4Tuples:y,solverVerticalWeights:b}=pt(t,n,r,f),x=vt(_,y,b,f,d??Math.random),S=a.create(),ee=o.create(),C=o.create();gt(x.matrix,S,ee,C);let{mean:w,median:T}=kt(h),E=Ot(r,f.geohashPrecision,f.geohashWindowSize);return{odometryPositions:ot(p),odometryRotations:st(m),gpsPositions:ct(h),gpsPositionsVec4:lt(g),alignmentMatrix:I(x.matrix),alignmentRotation:F(S),alignmentTranslation:P(ee),alignmentRotationInDegree:P(C),...ut(i,s,c,l),gpsAccuracyMedian:T,gpsAccuracyMean:w,currentGpsPosGeoHash:E}},X=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,ht=(e,t,n,r,i,s)=>{let c=e.odometryPositions,l=e.odometryRotations,u=e.gpsPositions,d=e.gpsPositionsVec4;c.push(J(t)),l.push(V(Y(n)));let f=Nt(r);u.push(f);let p={...at,...i??{}};f.weight=X(f.latLongAccuracy,p.gpsAccuracyExponent);let m=jt(f);if(p.includeTimeWeight){d.push(m);let e=Dt(d,u,p.weightByTimeFactor);for(let t=0;t<e.length;t++)d[t]=e[t]}else d.push(m);let h=0;p.useOnlyRecentData&&(h=Tt(u,p.recentSeconds));let g=vt(c.slice(h).map(M),d.slice(h),Et(u.slice(h),p),p,s??Math.random);e.alignmentMatrix=I(g.matrix);let _=a.create(),v=o.create(),y=o.create();gt(g.matrix,_,v,y),e.alignmentRotation=F(_),e.alignmentTranslation=P(v),e.alignmentRotationInDegree=P(y);let{mean:b,median:x}=kt(u);e.gpsAccuracyMean=b,e.gpsAccuracyMedian=x,e.currentGpsPosGeoHash=Ot(u,p.geohashPrecision,p.geohashWindowSize)},gt=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),At(t,r)},Z=o.create(),_t=o.create(),vt=(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=>St(e,r.ignoreYAxisForRotation),(e,t)=>Ct(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else{let e=St(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&yt(l,c,d,r),{matrix:l,meanError:u}},yt=(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`?xt(a,o):bt(a,o)},bt=(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},xt=(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]]},St=(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=Qe(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(Z,i[e],s),c+=wt(Z,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},Ct=(e,t)=>(o.transformMat4(Z,t.odom,e.alignmentMatrix),wt(Z,t.ref)),wt=(e,t)=>(o.set(_t,t[0],t[1],t[2]),o.squaredDistance(e,_t)),Tt=(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},Et=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return X(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)})},Dt=(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]})},Q=new Map,Ot=(e,t,n)=>{if(e.length===0)return null;let r=Math.max(0,e.length-n);Q.clear();for(let n=r;n<e.length;n+=1){let r=e[n],i=ce(Mt(r),t),a=Q.get(i);a?(a.count+=1,a.index=n):Q.set(i,{count:1,index:n})}let i=null,a=-1,o=-1;for(let[e,{count:t,index:n}]of Q)(t>a||t===a&&n>o)&&(i=e,a=t,o=n);return i},kt=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]}},At=(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},jt=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Mt=e=>({lat:e.latitude,lon:e.longitude}),Nt=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?V(Y(e.deviceRotation)):void 0}),Pt=({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}`)},Ft=o.fromValues(1,1,1),It=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],Lt=(e,t,n)=>{let r=O(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),i=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?W(G(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:P(r),weight:1,deviceRotation:i}},Rt=(e,t,n)=>{if(e)return G(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},zt=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},Bt=e=>{let t=zt(a.normalize(a.create(),N(e.lastSensorRot))),n=a.normalize(a.create(),N(e.lastValidOdomRot)),r=a.multiply(a.create(),t,n),i=a.normalize(a.create(),N(e.newSensorRot)),o=a.multiply(a.create(),i,r),s=a.normalize(a.create(),N(e.newOdomRot)),c=a.multiply(a.create(),o,s);return a.normalize(c,c),F(c)},Vt=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),N(t)),M(e),Ft),n},Ht=(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)},Ut=(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=Ht(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},Wt=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},Gt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],Kt=(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:ft(),odometryPath:_e()}:e,prepare:e=>(Pt(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a}=t.payload,o=Lt(i,e.zero,a);ht(e.gpsEvents,H(n),U(r),o)},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=It(e.gpsEvents.odometryPosOffset,H(t.payload.lastValidOdomPos)),r=Rt(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=Rt(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(mt({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:Bt({...t.payload,lastValidOdomRot:U(t.payload.lastValidOdomRot),newOdomRot:U(t.payload.newOdomRot),lastSensorRot:W(r),newSensorRot:W(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?Wt(n.odometryPositions,n.latestLoopClosureFixPointPos,Gt):0,s=n.latestLoopClosureFixPointRot?Wt(n.odometryRotations,n.latestLoopClosureFixPointRot,Kt):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=>L(e)),u=n.odometryRotations.slice(0,r).map(e=>V(e)),d=n.odometryPositions.slice(r).map(e=>L(e)),f=n.odometryRotations.slice(r).map(e=>V(e)),p=d.map((e,t)=>Vt(e,f[t])),m=Vt(H(t.payload.lastPos),V(U(t.payload.lastRot)));p.push(m);let h=Ut(p,Vt(H(t.payload.newPos),V(U(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(P(n)),_.push(F(r))}e.gpsEvents=c(mt({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:H(t.payload.position),rotation:V(U(t.payload.rotation)),capturedAt:t.payload.capturedAt}))}}}),{setZeroPos:Jt,recordGpsEvent:Yt,odometryTrackingRestarted:Xt,arLoopClosureDetected:Zt,add2dImage:Qt}=qt.actions,$t=p(Jt),en=p(Yt),tn=p(Xt),nn=p(Zt),rn=p(Qt),an=m(qt.reducer),on=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:sn,addLine:cn,addArea:ln,addToHeatMaps:un,addHeatMapArea:dn,resetGpsElements:fn}=on.actions,pn=p(sn),mn=p(cn),hn=p(ln),gn=p(un),_n=p(dn),vn=p(fn),yn=m(on.reducer),bn=()=>({gpsData:null,gpsElements:ve(),arElements:j()}),xn=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},Sn=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 Sn(e)?xn(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},Cn=(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=bn(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:an,gpsElements:yn,arElements:Ye},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:$,stateSanitizer:$}:!0})},wn=[],Tn=[],En=[],Dn={median:null,mean:null},On=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),kn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),An=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??wn}),jn=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??Tn}),Mn=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??En}),Nn=f(function(e){return e.gpsData?.zero??null}),Pn=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?Dn:{median:t,mean:n}}),Fn=`1.0.0`;export{B as IDENTITY_MATRIX4,R as IDENTITY_QUATERNION,Fn as LIB_VERSION,z as ZERO_VECTOR3,rn as add2dImage,hn as addArea,We as addCornerToEventArea,_n as addHeatMapArea,mn as addLine,pn as addMarker,He as addOrUpdateArPlane,gn as addToHeatMaps,qe as anchorEventAreaInWorldSpace,Ye as arElementsReducer,nn as arLoopClosureDetected,ce as calcGeoHash,k as calcGpsCoords,oe as calcQuadKey,O as calcRelativeCoordsInMeters,xe as cloneMatrix4,be as cloneQuaternion,L as cloneVector3,Ge as correctArDriftForEventArea,Cn as createGpsSlamStore,ue as distanceInMeters,de as distanceInMetersRelative,W as enuQuaternionToNUE,G as eulerToQuaternion,Ke as finishEventArea,ye as fromMatrix4,N as fromQuaternion,M as fromVector3,ge as fusedGpsFromOdom,le as geoHashToLatLong,On as getAlignmentMatrix,kn as getAlignmentRotation,me as getGoogleMapsDirectionsLink,pe as getGoogleMapsLink,Pn as getGpsAccuracyStats,Mn as getGpsPositions,An as getOdometryPositions,jn as getOdometryRotations,he as getOpenStreetMapLink,Nn as getZeroReference,an as gpsDataReducer,yn as gpsElementsReducer,Oe as invertQuaternion,Se as isIdentityMatrix4,we as isIdentityQuaternion,Te as isNearIdentityQuaternion,De as multiplyQuaternions,V as normalizeQuaternion,je as nueQuaternionToENU,Ae as nueQuaternionToWebXR,ke as nueToWebXR,tn as odometryTrackingRestarted,se as quadKeyToLatLong,Ce as quaternionMagnitude,Ee as quaternionsEquivalent,en as recordGpsEvent,Ve as recordPhoneHeight,Je as resetArElements,vn as resetGpsElements,$ as sanitizeForDevTools,$t as setZeroPos,Ue as startEventArea,fe as toEarthCenteredCoordinates,I as toMatrix4,F as toQuaternion,P as toVector3,g as validateLicenseKey,U as webxrQuaternionToNUE,H 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 = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODExNzg4MTA2fQ.0lSHw7QYXP8U_PgQ7ckP3JIP31h4EGvgzNx0_6u-FeYdFMwM-QUENHsWSbyZ718n8nfyxOvNNGN2v-ljSOxhDQ";
|
|
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=`eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODExNzg4MTA2fQ.0lSHw7QYXP8U_PgQ7ckP3JIP31h4EGvgzNx0_6u-FeYdFMwM-QUENHsWSbyZ718n8nfyxOvNNGN2v-ljSOxhDQ`;export{e as COMMUNITY_LICENSE_KEY};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gps-plus-slam-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "TypeScript library for real-time GPS + AR odometry alignment.",
|
|
5
5
|
"author": "cs-util-com",
|
|
6
6
|
"keywords": [
|
|
@@ -42,35 +42,35 @@
|
|
|
42
42
|
"@noble/curves": "^2.2.0",
|
|
43
43
|
"@reduxjs/toolkit": "^2.11.2",
|
|
44
44
|
"gl-matrix": "3.4.4",
|
|
45
|
-
"immer": "^11.1.
|
|
45
|
+
"immer": "^11.1.8",
|
|
46
46
|
"redux": "^5.0.1",
|
|
47
47
|
"redux-thunk": "^3.1.0"
|
|
48
48
|
},
|
|
49
49
|
"license": "UNLICENSED",
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@eslint/js": "^10.0.1",
|
|
52
|
-
"@playwright/test": "^1.
|
|
52
|
+
"@playwright/test": "^1.60.0",
|
|
53
53
|
"@stryker-mutator/core": "^9.6.1",
|
|
54
54
|
"@stryker-mutator/typescript-checker": "^9.6.1",
|
|
55
55
|
"@stryker-mutator/vitest-runner": "^9.6.1",
|
|
56
|
-
"@types/node": "^25.
|
|
57
|
-
"@vitest/coverage-v8": "^4.1.
|
|
58
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
59
|
-
"dependency-cruiser": "^17.
|
|
60
|
-
"dpdm": "^4.0
|
|
61
|
-
"eslint": "^10.
|
|
56
|
+
"@types/node": "^25.7.0",
|
|
57
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
58
|
+
"@vitest/eslint-plugin": "^1.6.17",
|
|
59
|
+
"dependency-cruiser": "^17.4.0",
|
|
60
|
+
"dpdm": "^4.2.0",
|
|
61
|
+
"eslint": "^10.3.0",
|
|
62
62
|
"eslint-config-prettier": "^10.1.8",
|
|
63
|
-
"fast-check": "^4.
|
|
64
|
-
"globals": "^17.
|
|
65
|
-
"jscpd": "^4.
|
|
66
|
-
"knip": "^6.
|
|
63
|
+
"fast-check": "^4.8.0",
|
|
64
|
+
"globals": "^17.6.0",
|
|
65
|
+
"jscpd": "^4.1.1",
|
|
66
|
+
"knip": "^6.13.1",
|
|
67
67
|
"prettier": "^3.8.3",
|
|
68
68
|
"serve": "^14.2.6",
|
|
69
|
-
"tailwindcss": "^4.
|
|
70
|
-
"tsdown": "^0.
|
|
69
|
+
"tailwindcss": "^4.3.0",
|
|
70
|
+
"tsdown": "^0.22.0",
|
|
71
71
|
"typescript": "^6.0.3",
|
|
72
|
-
"typescript-eslint": "^8.59.
|
|
73
|
-
"vitest": "^4.1.
|
|
72
|
+
"typescript-eslint": "^8.59.3",
|
|
73
|
+
"vitest": "^4.1.6"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"generate-keys": "node scripts/generate-keys.mjs",
|